1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -early-cse < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare void @clobber_and_use(i32) 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdefine void @f_0(i32* %ptr) { 6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_0( 7*9880d681SAndroid Build Coastguard Worker; CHECK: %val0 = load i32, i32* %ptr, !invariant.load !0 8*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 9*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 10*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 11*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker %val0 = load i32, i32* %ptr, !invariant.load !{} 14*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val0) 15*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr, !invariant.load !{} 16*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val1) 17*9880d681SAndroid Build Coastguard Worker %val2 = load i32, i32* %ptr, !invariant.load !{} 18*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val2) 19*9880d681SAndroid Build Coastguard Worker ret void 20*9880d681SAndroid Build Coastguard Worker} 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerdefine void @f_1(i32* %ptr) { 23*9880d681SAndroid Build Coastguard Worker; We can forward invariant loads to non-invariant loads, since once an 24*9880d681SAndroid Build Coastguard Worker; invariant load has executed, the location loaded from is known to be 25*9880d681SAndroid Build Coastguard Worker; unchanging. 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_1( 28*9880d681SAndroid Build Coastguard Worker; CHECK: %val0 = load i32, i32* %ptr, !invariant.load !0 29*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 30*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker %val0 = load i32, i32* %ptr, !invariant.load !{} 33*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val0) 34*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr 35*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val1) 36*9880d681SAndroid Build Coastguard Worker ret void 37*9880d681SAndroid Build Coastguard Worker} 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerdefine void @f_2(i32* %ptr) { 40*9880d681SAndroid Build Coastguard Worker; Negative test -- we can't forward a non-invariant load into an 41*9880d681SAndroid Build Coastguard Worker; invariant load. 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_2( 44*9880d681SAndroid Build Coastguard Worker; CHECK: %val0 = load i32, i32* %ptr 45*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val0) 46*9880d681SAndroid Build Coastguard Worker; CHECK: %val1 = load i32, i32* %ptr, !invariant.load !0 47*9880d681SAndroid Build Coastguard Worker; CHECK: call void @clobber_and_use(i32 %val1) 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker %val0 = load i32, i32* %ptr 50*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val0) 51*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr, !invariant.load !{} 52*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val1) 53*9880d681SAndroid Build Coastguard Worker ret void 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerdefine void @f_3(i1 %cond, i32* %ptr) { 57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_3( 58*9880d681SAndroid Build Coastguard Worker %val0 = load i32, i32* %ptr, !invariant.load !{} 59*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val0) 60*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %left, label %right 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; CHECK: %val0 = load i32, i32* %ptr, !invariant.load !0 63*9880d681SAndroid Build Coastguard Worker; CHECK: left: 64*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @clobber_and_use(i32 %val0) 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerleft: 67*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr 68*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val1) 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerright: 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerdefine void @f_4(i1 %cond, i32* %ptr) { 76*9880d681SAndroid Build Coastguard Worker; Negative test -- can't forward %val0 to %va1 because that'll break 77*9880d681SAndroid Build Coastguard Worker; def-dominates-use. 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_4( 80*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %left, label %merge 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerleft: 83*9880d681SAndroid Build Coastguard Worker; CHECK: left: 84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %val0 = load i32, i32* %ptr, !invariant.load ! 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @clobber_and_use(i32 %val0) 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker %val0 = load i32, i32* %ptr, !invariant.load !{} 88*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val0) 89*9880d681SAndroid Build Coastguard Worker br label %merge 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Workermerge: 92*9880d681SAndroid Build Coastguard Worker; CHECK: merge: 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %val1 = load i32, i32* %ptr 94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @clobber_and_use(i32 %val1) 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker %val1 = load i32, i32* %ptr 97*9880d681SAndroid Build Coastguard Worker call void @clobber_and_use(i32 %val1) 98*9880d681SAndroid Build Coastguard Worker ret void 99*9880d681SAndroid Build Coastguard Worker} 100