1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -early-cse < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; While it is normally okay to do memory optimizations over calls to 4*9880d681SAndroid Build Coastguard Worker; @readonly_function and @readnone_function, we cannot do that if 5*9880d681SAndroid Build Coastguard Worker; they're carrying unknown operand bundles since the presence of 6*9880d681SAndroid Build Coastguard Worker; unknown operand bundles implies arbitrary memory effects. 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdeclare void @readonly_function() readonly nounwind 9*9880d681SAndroid Build Coastguard Workerdeclare void @readnone_function() readnone nounwind 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdefine i32 @test0(i32* %x) { 12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test0( 13*9880d681SAndroid Build Coastguard Worker entry: 14*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 15*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 100, i32* %x 16*9880d681SAndroid Build Coastguard Worker call void @readonly_function() [ "tag"() ] 17*9880d681SAndroid Build Coastguard Worker; CHECK: call void @readonly_function() 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %x 20*9880d681SAndroid Build Coastguard Worker; CHECK: %v = load i32, i32* %x 21*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %v 22*9880d681SAndroid Build Coastguard Worker ret i32 %v 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* %x) { 26*9880d681SAndroid Build Coastguard Worker; CHECK: @test1( 27*9880d681SAndroid Build Coastguard Worker entry: 28*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 29*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 100, i32* %x 30*9880d681SAndroid Build Coastguard Worker call void @readonly_function() readonly [ "tag"() ] 31*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void @readonly_function 32*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %x 33*9880d681SAndroid Build Coastguard Worker ret i32 %v 34*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 100 35*9880d681SAndroid Build Coastguard Worker} 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32* %x) { 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3( 39*9880d681SAndroid Build Coastguard Worker entry: 40*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 41*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 100, i32* %x 42*9880d681SAndroid Build Coastguard Worker call void @readonly_function() 43*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void @readonly_function 44*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %x 45*9880d681SAndroid Build Coastguard Worker ret i32 %v 46*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 100 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerdefine void @test4(i32* %x) { 50*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 51*9880d681SAndroid Build Coastguard Worker entry: 52*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 53*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 100, i32* %x 54*9880d681SAndroid Build Coastguard Worker call void @readnone_function() [ "tag"() ] 55*9880d681SAndroid Build Coastguard Worker; CHECK: call void @readnone_function 56*9880d681SAndroid Build Coastguard Worker store i32 200, i32* %x 57*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 200, i32* %x 58*9880d681SAndroid Build Coastguard Worker ret void 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerdefine void @test5(i32* %x) { 62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 63*9880d681SAndroid Build Coastguard Worker entry: 64*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store i32 100, i32* %x 66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void @readnone_function 67*9880d681SAndroid Build Coastguard Worker call void @readnone_function() readnone [ "tag"() ] 68*9880d681SAndroid Build Coastguard Worker store i32 200, i32* %x 69*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 200, i32* %x 70*9880d681SAndroid Build Coastguard Worker ret void 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Workerdefine void @test6(i32* %x) { 74*9880d681SAndroid Build Coastguard Worker; The "deopt" operand bundle does not make the call to 75*9880d681SAndroid Build Coastguard Worker; @readonly_function read-write; and so the nounwind readonly call can 76*9880d681SAndroid Build Coastguard Worker; be deleted. 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 79*9880d681SAndroid Build Coastguard Worker entry: 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i32 200, i32* %x 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker store i32 100, i32* %x 86*9880d681SAndroid Build Coastguard Worker call void @readonly_function() [ "deopt"() ] 87*9880d681SAndroid Build Coastguard Worker store i32 200, i32* %x 88*9880d681SAndroid Build Coastguard Worker ret void 89*9880d681SAndroid Build Coastguard Worker} 90