1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -early-cse | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -passes=early-cse | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.assume(i1) nounwind 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 7*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8 %V, i32 *%P) { 8*9880d681SAndroid Build Coastguard Worker %A = bitcast i64 42 to double ;; dead 9*9880d681SAndroid Build Coastguard Worker %B = add i32 4, 19 ;; constant folds 10*9880d681SAndroid Build Coastguard Worker store i32 %B, i32* %P 11*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 23, i32* %P 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker %C = zext i8 %V to i32 14*9880d681SAndroid Build Coastguard Worker %D = zext i8 %V to i32 ;; CSE 15*9880d681SAndroid Build Coastguard Worker store volatile i32 %C, i32* %P 16*9880d681SAndroid Build Coastguard Worker store volatile i32 %D, i32* %P 17*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: %C = zext i8 %V to i32 18*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store volatile i32 %C 19*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store volatile i32 %C 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker %E = add i32 %C, %C 22*9880d681SAndroid Build Coastguard Worker %F = add i32 %C, %C 23*9880d681SAndroid Build Coastguard Worker store volatile i32 %E, i32* %P 24*9880d681SAndroid Build Coastguard Worker store volatile i32 %F, i32* %P 25*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: %E = add i32 %C, %C 26*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store volatile i32 %E 27*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store volatile i32 %E 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker %G = add nuw i32 %C, %C 30*9880d681SAndroid Build Coastguard Worker store volatile i32 %G, i32* %P 31*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store volatile i32 %E 32*9880d681SAndroid Build Coastguard Worker ret void 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker;; Simple load value numbering. 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 38*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32 *%P) { 39*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 40*9880d681SAndroid Build Coastguard Worker %V2 = load i32, i32* %P 41*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 42*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 43*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 44*9880d681SAndroid Build Coastguard Worker} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2a( 47*9880d681SAndroid Build Coastguard Workerdefine i32 @test2a(i32 *%P, i1 %b) { 48*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 49*9880d681SAndroid Build Coastguard Worker tail call void @llvm.assume(i1 %b) 50*9880d681SAndroid Build Coastguard Worker %V2 = load i32, i32* %P 51*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 52*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 53*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker;; Cross block load value numbering. 57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3( 58*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32 *%P, i1 %Cond) { 59*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 60*9880d681SAndroid Build Coastguard Worker br i1 %Cond, label %T, label %F 61*9880d681SAndroid Build Coastguard WorkerT: 62*9880d681SAndroid Build Coastguard Worker store i32 4, i32* %P 63*9880d681SAndroid Build Coastguard Worker ret i32 42 64*9880d681SAndroid Build Coastguard WorkerF: 65*9880d681SAndroid Build Coastguard Worker %V2 = load i32, i32* %P 66*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 67*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 68*9880d681SAndroid Build Coastguard Worker ; CHECK: F: 69*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3a( 73*9880d681SAndroid Build Coastguard Workerdefine i32 @test3a(i32 *%P, i1 %Cond, i1 %b) { 74*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 75*9880d681SAndroid Build Coastguard Worker br i1 %Cond, label %T, label %F 76*9880d681SAndroid Build Coastguard WorkerT: 77*9880d681SAndroid Build Coastguard Worker store i32 4, i32* %P 78*9880d681SAndroid Build Coastguard Worker ret i32 42 79*9880d681SAndroid Build Coastguard WorkerF: 80*9880d681SAndroid Build Coastguard Worker tail call void @llvm.assume(i1 %b) 81*9880d681SAndroid Build Coastguard Worker %V2 = load i32, i32* %P 82*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 83*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 84*9880d681SAndroid Build Coastguard Worker ; CHECK: F: 85*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 86*9880d681SAndroid Build Coastguard Worker} 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker;; Cross block load value numbering stops when stores happen. 89*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 90*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32 *%P, i1 %Cond) { 91*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 92*9880d681SAndroid Build Coastguard Worker br i1 %Cond, label %T, label %F 93*9880d681SAndroid Build Coastguard WorkerT: 94*9880d681SAndroid Build Coastguard Worker ret i32 42 95*9880d681SAndroid Build Coastguard WorkerF: 96*9880d681SAndroid Build Coastguard Worker ; Clobbers V1 97*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %P 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker %V2 = load i32, i32* %P 100*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 101*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 102*9880d681SAndroid Build Coastguard Worker ; CHECK: F: 103*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 %Diff 104*9880d681SAndroid Build Coastguard Worker} 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerdeclare i32 @func(i32 *%P) readonly 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker;; Simple call CSE'ing. 109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 110*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32 *%P) { 111*9880d681SAndroid Build Coastguard Worker %V1 = call i32 @func(i32* %P) 112*9880d681SAndroid Build Coastguard Worker %V2 = call i32 @func(i32* %P) 113*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 114*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 115*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker;; Trivial Store->load forwarding 119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 120*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i32 *%P) { 121*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %P 122*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 123*9880d681SAndroid Build Coastguard Worker ret i32 %V1 124*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 42 125*9880d681SAndroid Build Coastguard Worker} 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6a( 128*9880d681SAndroid Build Coastguard Workerdefine i32 @test6a(i32 *%P, i1 %b) { 129*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %P 130*9880d681SAndroid Build Coastguard Worker tail call void @llvm.assume(i1 %b) 131*9880d681SAndroid Build Coastguard Worker %V1 = load i32, i32* %P 132*9880d681SAndroid Build Coastguard Worker ret i32 %V1 133*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 42 134*9880d681SAndroid Build Coastguard Worker} 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker;; Trivial dead store elimination. 137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7( 138*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32 *%P) { 139*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %P 140*9880d681SAndroid Build Coastguard Worker store i32 45, i32* %P 141*9880d681SAndroid Build Coastguard Worker ret void 142*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 45 143*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker;; Readnone functions aren't invalidated by stores. 147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8( 148*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i32 *%P) { 149*9880d681SAndroid Build Coastguard Worker %V1 = call i32 @func(i32* %P) readnone 150*9880d681SAndroid Build Coastguard Worker store i32 4, i32* %P 151*9880d681SAndroid Build Coastguard Worker %V2 = call i32 @func(i32* %P) readnone 152*9880d681SAndroid Build Coastguard Worker %Diff = sub i32 %V1, %V2 153*9880d681SAndroid Build Coastguard Worker ret i32 %Diff 154*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 155*9880d681SAndroid Build Coastguard Worker} 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker;; Trivial DSE can't be performed across a readonly call. The call 158*9880d681SAndroid Build Coastguard Worker;; can observe the earlier write. 159*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9( 160*9880d681SAndroid Build Coastguard Workerdefine i32 @test9(i32 *%P) { 161*9880d681SAndroid Build Coastguard Worker store i32 4, i32* %P 162*9880d681SAndroid Build Coastguard Worker %V1 = call i32 @func(i32* %P) readonly 163*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %P 164*9880d681SAndroid Build Coastguard Worker ret i32 %V1 165*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 4, i32* %P 166*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: %V1 = call i32 @func(i32* %P) 167*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 5, i32* %P 168*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: ret i32 %V1 169*9880d681SAndroid Build Coastguard Worker} 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker;; Trivial DSE can be performed across a readnone call. 172*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10 173*9880d681SAndroid Build Coastguard Workerdefine i32 @test10(i32 *%P) { 174*9880d681SAndroid Build Coastguard Worker store i32 4, i32* %P 175*9880d681SAndroid Build Coastguard Worker %V1 = call i32 @func(i32* %P) readnone 176*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %P 177*9880d681SAndroid Build Coastguard Worker ret i32 %V1 178*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: %V1 = call i32 @func(i32* %P) 179*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 5, i32* %P 180*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: ret i32 %V1 181*9880d681SAndroid Build Coastguard Worker} 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker;; Trivial dead store elimination - should work for an entire series of dead stores too. 184*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11( 185*9880d681SAndroid Build Coastguard Workerdefine void @test11(i32 *%P) { 186*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %P 187*9880d681SAndroid Build Coastguard Worker store i32 43, i32* %P 188*9880d681SAndroid Build Coastguard Worker store i32 44, i32* %P 189*9880d681SAndroid Build Coastguard Worker store i32 45, i32* %P 190*9880d681SAndroid Build Coastguard Worker ret void 191*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 45 192*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: ret void 193*9880d681SAndroid Build Coastguard Worker} 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12( 196*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i1 %B, i32* %P1, i32* %P2) { 197*9880d681SAndroid Build Coastguard Worker %load0 = load i32, i32* %P1 198*9880d681SAndroid Build Coastguard Worker %1 = load atomic i32, i32* %P2 seq_cst, align 4 199*9880d681SAndroid Build Coastguard Worker %load1 = load i32, i32* %P1 200*9880d681SAndroid Build Coastguard Worker %sel = select i1 %B, i32 %load0, i32 %load1 201*9880d681SAndroid Build Coastguard Worker ret i32 %sel 202*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 203*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 204*9880d681SAndroid Build Coastguard Worker} 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Workerdefine void @dse1(i32 *%P) { 207*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse1 208*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 209*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %P 210*9880d681SAndroid Build Coastguard Worker store i32 %v, i32* %P 211*9880d681SAndroid Build Coastguard Worker ret void 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Workerdefine void @dse2(i32 *%P) { 215*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse2 216*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 217*9880d681SAndroid Build Coastguard Worker %v = load atomic i32, i32* %P seq_cst, align 4 218*9880d681SAndroid Build Coastguard Worker store i32 %v, i32* %P 219*9880d681SAndroid Build Coastguard Worker ret void 220*9880d681SAndroid Build Coastguard Worker} 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Workerdefine void @dse3(i32 *%P) { 223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse3 224*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 225*9880d681SAndroid Build Coastguard Worker %v = load atomic i32, i32* %P seq_cst, align 4 226*9880d681SAndroid Build Coastguard Worker store atomic i32 %v, i32* %P unordered, align 4 227*9880d681SAndroid Build Coastguard Worker ret void 228*9880d681SAndroid Build Coastguard Worker} 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerdefine i32 @dse4(i32 *%P, i32 *%Q) { 231*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse4 232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 233*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 234*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %Q 235*9880d681SAndroid Build Coastguard Worker %v = load atomic i32, i32* %P unordered, align 4 236*9880d681SAndroid Build Coastguard Worker store atomic i32 %v, i32* %P unordered, align 4 237*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %Q 238*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 239*9880d681SAndroid Build Coastguard Worker ret i32 %res 240*9880d681SAndroid Build Coastguard Worker} 241*9880d681SAndroid Build Coastguard Worker 242*9880d681SAndroid Build Coastguard Worker; Note that in this example, %P and %Q could in fact be the same 243*9880d681SAndroid Build Coastguard Worker; pointer. %v could be different than the value observed for %a 244*9880d681SAndroid Build Coastguard Worker; and that's okay because we're using relaxed memory ordering. 245*9880d681SAndroid Build Coastguard Worker; The only guarantee we have to provide is that each of the loads 246*9880d681SAndroid Build Coastguard Worker; has to observe some value written to that location. We do 247*9880d681SAndroid Build Coastguard Worker; not have to respect the order in which those writes were done. 248*9880d681SAndroid Build Coastguard Workerdefine i32 @dse5(i32 *%P, i32 *%Q) { 249*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse5 250*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 251*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 252*9880d681SAndroid Build Coastguard Worker %v = load atomic i32, i32* %P unordered, align 4 253*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %Q unordered, align 4 254*9880d681SAndroid Build Coastguard Worker store atomic i32 %v, i32* %P unordered, align 4 255*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %Q unordered, align 4 256*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 257*9880d681SAndroid Build Coastguard Worker ret i32 %res 258*9880d681SAndroid Build Coastguard Worker} 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Workerdefine void @dse_neg1(i32 *%P) { 262*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse_neg1 263*9880d681SAndroid Build Coastguard Worker; CHECK: store 264*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %P 265*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %P 266*9880d681SAndroid Build Coastguard Worker ret void 267*9880d681SAndroid Build Coastguard Worker} 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Worker; Could remove the store, but only if ordering was somehow 270*9880d681SAndroid Build Coastguard Worker; encoded. 271*9880d681SAndroid Build Coastguard Workerdefine void @dse_neg2(i32 *%P) { 272*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse_neg2 273*9880d681SAndroid Build Coastguard Worker; CHECK: store 274*9880d681SAndroid Build Coastguard Worker %v = load i32, i32* %P 275*9880d681SAndroid Build Coastguard Worker store atomic i32 %v, i32* %P seq_cst, align 4 276*9880d681SAndroid Build Coastguard Worker ret void 277*9880d681SAndroid Build Coastguard Worker} 278*9880d681SAndroid Build Coastguard Worker 279