1*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -gvn -S < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-apple-macosx10.7.0" 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker@x = common global i32 0, align 4 7*9880d681SAndroid Build Coastguard Worker@y = common global i32 0, align 4 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; GVN across unordered store (allowed) 10*9880d681SAndroid Build Coastguard Workerdefine i32 @test1() nounwind uwtable ssp { 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1 12*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x 13*9880d681SAndroid Build Coastguard Workerentry: 14*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* @y 15*9880d681SAndroid Build Coastguard Worker store atomic i32 %x, i32* @x unordered, align 4 16*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* @y 17*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 18*9880d681SAndroid Build Coastguard Worker ret i32 %z 19*9880d681SAndroid Build Coastguard Worker} 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker; GVN across unordered load (allowed) 22*9880d681SAndroid Build Coastguard Workerdefine i32 @test3() nounwind uwtable ssp { 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3 24*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x 25*9880d681SAndroid Build Coastguard Workerentry: 26*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* @y 27*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* @x unordered, align 4 28*9880d681SAndroid Build Coastguard Worker %z = load i32, i32* @y 29*9880d681SAndroid Build Coastguard Worker %a = add i32 %x, %z 30*9880d681SAndroid Build Coastguard Worker %b = add i32 %y, %a 31*9880d681SAndroid Build Coastguard Worker ret i32 %b 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; GVN load to unordered load (allowed) 35*9880d681SAndroid Build Coastguard Workerdefine i32 @test5() nounwind uwtable ssp { 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5 37*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* @x unordered, align 4 40*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* @x 41*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 42*9880d681SAndroid Build Coastguard Worker ret i32 %z 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; GVN unordered load to load (unordered load must not be removed) 46*9880d681SAndroid Build Coastguard Workerdefine i32 @test6() nounwind uwtable ssp { 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test6 48*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @x unordered 49*9880d681SAndroid Build Coastguard Workerentry: 50*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* @x 51*9880d681SAndroid Build Coastguard Worker %x2 = load atomic i32, i32* @x unordered, align 4 52*9880d681SAndroid Build Coastguard Worker %x3 = add i32 %x, %x2 53*9880d681SAndroid Build Coastguard Worker ret i32 %x3 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; GVN across release-acquire pair (forbidden) 57*9880d681SAndroid Build Coastguard Workerdefine i32 @test7() nounwind uwtable ssp { 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test7 59*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %y 60*9880d681SAndroid Build Coastguard Workerentry: 61*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* @y 62*9880d681SAndroid Build Coastguard Worker store atomic i32 %x, i32* @x release, align 4 63*9880d681SAndroid Build Coastguard Worker %w = load atomic i32, i32* @x acquire, align 4 64*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* @y 65*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 66*9880d681SAndroid Build Coastguard Worker ret i32 %z 67*9880d681SAndroid Build Coastguard Worker} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; GVN across monotonic store (allowed) 70*9880d681SAndroid Build Coastguard Workerdefine i32 @test9() nounwind uwtable ssp { 71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test9 72*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x 73*9880d681SAndroid Build Coastguard Workerentry: 74*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* @y 75*9880d681SAndroid Build Coastguard Worker store atomic i32 %x, i32* @x monotonic, align 4 76*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* @y 77*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 78*9880d681SAndroid Build Coastguard Worker ret i32 %z 79*9880d681SAndroid Build Coastguard Worker} 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; GVN of an unordered across monotonic load (not allowed) 82*9880d681SAndroid Build Coastguard Workerdefine i32 @test10() nounwind uwtable ssp { 83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test10 84*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %y 85*9880d681SAndroid Build Coastguard Workerentry: 86*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* @y unordered, align 4 87*9880d681SAndroid Build Coastguard Worker %clobber = load atomic i32, i32* @x monotonic, align 4 88*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* @y monotonic, align 4 89*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 90*9880d681SAndroid Build Coastguard Worker ret i32 %z 91*9880d681SAndroid Build Coastguard Worker} 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerdefine i32 @PR22708(i1 %flag) { 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22708 95*9880d681SAndroid Build Coastguard Workerentry: 96*9880d681SAndroid Build Coastguard Worker br i1 %flag, label %if.then, label %if.end 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerif.then: 99*9880d681SAndroid Build Coastguard Worker store i32 43, i32* @y, align 4 100*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 43, i32* @y, align 4 101*9880d681SAndroid Build Coastguard Worker br label %if.end 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerif.end: 104*9880d681SAndroid Build Coastguard Worker load atomic i32, i32* @x acquire, align 4 105*9880d681SAndroid Build Coastguard Worker %load = load i32, i32* @y, align 4 106*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @x acquire, align 4 107*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* @y, align 4 108*9880d681SAndroid Build Coastguard Worker ret i32 %load 109*9880d681SAndroid Build Coastguard Worker} 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12( 112*9880d681SAndroid Build Coastguard Worker; Can't remove a load over a ordering barrier 113*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i1 %B, i32* %P1, i32* %P2) { 114*9880d681SAndroid Build Coastguard Worker %load0 = load i32, i32* %P1 115*9880d681SAndroid Build Coastguard Worker %1 = load atomic i32, i32* %P2 seq_cst, align 4 116*9880d681SAndroid Build Coastguard Worker %load1 = load i32, i32* %P1 117*9880d681SAndroid Build Coastguard Worker %sel = select i1 %B, i32 %load0, i32 %load1 118*9880d681SAndroid Build Coastguard Worker ret i32 %sel 119*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 120*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13( 124*9880d681SAndroid Build Coastguard Worker; atomic to non-atomic forwarding is legal 125*9880d681SAndroid Build Coastguard Workerdefine i32 @test13(i32* %P1) { 126*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 127*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %P1 128*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 129*9880d681SAndroid Build Coastguard Worker ret i32 %res 130*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 131*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 132*9880d681SAndroid Build Coastguard Worker} 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13b( 135*9880d681SAndroid Build Coastguard Workerdefine i32 @test13b(i32* %P1) { 136*9880d681SAndroid Build Coastguard Worker store atomic i32 0, i32* %P1 unordered, align 4 137*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %P1 138*9880d681SAndroid Build Coastguard Worker ret i32 %b 139*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 140*9880d681SAndroid Build Coastguard Worker} 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14( 143*9880d681SAndroid Build Coastguard Worker; atomic to unordered atomic forwarding is legal 144*9880d681SAndroid Build Coastguard Workerdefine i32 @test14(i32* %P1) { 145*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 146*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 147*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 148*9880d681SAndroid Build Coastguard Worker ret i32 %res 149*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 seq_cst 150*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: ret i32 0 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test15( 154*9880d681SAndroid Build Coastguard Worker; implementation restriction: can't forward to stonger 155*9880d681SAndroid Build Coastguard Worker; than unordered 156*9880d681SAndroid Build Coastguard Workerdefine i32 @test15(i32* %P1, i32* %P2) { 157*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 158*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 seq_cst, align 4 159*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 160*9880d681SAndroid Build Coastguard Worker ret i32 %res 161*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 162*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 163*9880d681SAndroid Build Coastguard Worker} 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16( 166*9880d681SAndroid Build Coastguard Worker; forwarding non-atomic to atomic is wrong! (However, 167*9880d681SAndroid Build Coastguard Worker; it would be legal to use the later value in place of the 168*9880d681SAndroid Build Coastguard Worker; former in this particular example. We just don't 169*9880d681SAndroid Build Coastguard Worker; do that right now.) 170*9880d681SAndroid Build Coastguard Workerdefine i32 @test16(i32* %P1, i32* %P2) { 171*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %P1, align 4 172*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 173*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 174*9880d681SAndroid Build Coastguard Worker ret i32 %res 175*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 176*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 177*9880d681SAndroid Build Coastguard Worker} 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16b( 180*9880d681SAndroid Build Coastguard Workerdefine i32 @test16b(i32* %P1) { 181*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1 182*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 183*9880d681SAndroid Build Coastguard Worker ret i32 %b 184*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence 188*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst_store(i32* %P1, i32* %P2) { 189*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst_store( 190*9880d681SAndroid Build Coastguard Worker; CHECK: store 191*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic 192*9880d681SAndroid Build Coastguard Worker; CHECK: store 193*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 194*9880d681SAndroid Build Coastguard Worker store atomic i32 0, i32* %P2 seq_cst, align 4 195*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 196*9880d681SAndroid Build Coastguard Worker ret void 197*9880d681SAndroid Build Coastguard Worker} 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence 200*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst(i32* %P1, i32* %P2) { 201*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst( 202*9880d681SAndroid Build Coastguard Worker; CHECK: store 203*9880d681SAndroid Build Coastguard Worker; CHECK: fence seq_cst 204*9880d681SAndroid Build Coastguard Worker; CHECK: store 205*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 206*9880d681SAndroid Build Coastguard Worker fence seq_cst 207*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 208*9880d681SAndroid Build Coastguard Worker ret void 209*9880d681SAndroid Build Coastguard Worker} 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full singlethread fence 212*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst_st(i32* %P1, i32* %P2) { 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst_st( 214*9880d681SAndroid Build Coastguard Worker; CHECK: store 215*9880d681SAndroid Build Coastguard Worker; CHECK: fence singlethread seq_cst 216*9880d681SAndroid Build Coastguard Worker; CHECK: store 217*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 218*9880d681SAndroid Build Coastguard Worker fence singlethread seq_cst 219*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 220*9880d681SAndroid Build Coastguard Worker ret void 221*9880d681SAndroid Build Coastguard Worker} 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence 224*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_sideeffect(i32* %P1, i32* %P2) { 225*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_sideeffect( 226*9880d681SAndroid Build Coastguard Worker; CHECK: store 227*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm sideeffect 228*9880d681SAndroid Build Coastguard Worker; CHECK: store 229*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 230*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "", ""() 231*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 232*9880d681SAndroid Build Coastguard Worker ret void 233*9880d681SAndroid Build Coastguard Worker} 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence 236*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_memory(i32* %P1, i32* %P2) { 237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_memory( 238*9880d681SAndroid Build Coastguard Worker; CHECK: store 239*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm 240*9880d681SAndroid Build Coastguard Worker; CHECK: store 241*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 242*9880d681SAndroid Build Coastguard Worker call void asm "", "~{memory}"() 243*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %P1, align 4 244*9880d681SAndroid Build Coastguard Worker ret void 245*9880d681SAndroid Build Coastguard Worker} 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Worker; Can't remove a volatile load 248*9880d681SAndroid Build Coastguard Workerdefine i32 @volatile_load(i32* %P1, i32* %P2) { 249*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %P1, align 4 250*9880d681SAndroid Build Coastguard Worker %b = load volatile i32, i32* %P1, align 4 251*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 252*9880d681SAndroid Build Coastguard Worker ret i32 %res 253*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @volatile_load( 254*9880d681SAndroid Build Coastguard Worker ; CHECK: load i32, i32* %P1 255*9880d681SAndroid Build Coastguard Worker ; CHECK: load volatile i32, i32* %P1 256*9880d681SAndroid Build Coastguard Worker} 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Worker; Can't remove redundant volatile loads 259*9880d681SAndroid Build Coastguard Workerdefine i32 @redundant_volatile_load(i32* %P1, i32* %P2) { 260*9880d681SAndroid Build Coastguard Worker %a = load volatile i32, i32* %P1, align 4 261*9880d681SAndroid Build Coastguard Worker %b = load volatile i32, i32* %P1, align 4 262*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 263*9880d681SAndroid Build Coastguard Worker ret i32 %res 264*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @redundant_volatile_load( 265*9880d681SAndroid Build Coastguard Worker ; CHECK: load volatile i32, i32* %P1 266*9880d681SAndroid Build Coastguard Worker ; CHECK: load volatile i32, i32* %P1 267*9880d681SAndroid Build Coastguard Worker ; CHECK: sub 268*9880d681SAndroid Build Coastguard Worker} 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Worker; Can't DSE a volatile store 271*9880d681SAndroid Build Coastguard Workerdefine void @volatile_store(i32* %P1, i32* %P2) { 272*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @volatile_store( 273*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile 274*9880d681SAndroid Build Coastguard Worker; CHECK: store 275*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* %P1, align 4 276*9880d681SAndroid Build Coastguard Worker store i32 3, i32* %P1, align 4 277*9880d681SAndroid Build Coastguard Worker ret void 278*9880d681SAndroid Build Coastguard Worker} 279*9880d681SAndroid Build Coastguard Worker 280*9880d681SAndroid Build Coastguard Worker; Can't DSE a redundant volatile store 281*9880d681SAndroid Build Coastguard Workerdefine void @redundant_volatile_store(i32* %P1, i32* %P2) { 282*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @redundant_volatile_store( 283*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile 284*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile 285*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* %P1, align 4 286*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* %P1, align 4 287*9880d681SAndroid Build Coastguard Worker ret void 288*9880d681SAndroid Build Coastguard Worker} 289*9880d681SAndroid Build Coastguard Worker 290*9880d681SAndroid Build Coastguard Worker; Can value forward from volatiles 291*9880d681SAndroid Build Coastguard Workerdefine i32 @test20(i32* %P1, i32* %P2) { 292*9880d681SAndroid Build Coastguard Worker %a = load volatile i32, i32* %P1, align 4 293*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %P1, align 4 294*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 295*9880d681SAndroid Build Coastguard Worker ret i32 %res 296*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @test20( 297*9880d681SAndroid Build Coastguard Worker ; CHECK: load volatile i32, i32* %P1 298*9880d681SAndroid Build Coastguard Worker ; CHECK: ret i32 0 299*9880d681SAndroid Build Coastguard Worker} 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Worker; We're currently conservative about widening 302*9880d681SAndroid Build Coastguard Workerdefine i64 @widen1(i32* %P1) { 303*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @widen1( 304*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 305*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i64, i64* %p2 306*9880d681SAndroid Build Coastguard Worker %p2 = bitcast i32* %P1 to i64* 307*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 unordered, align 4 308*9880d681SAndroid Build Coastguard Worker %b = load atomic i64, i64* %p2 unordered, align 4 309*9880d681SAndroid Build Coastguard Worker %a64 = sext i32 %a to i64 310*9880d681SAndroid Build Coastguard Worker %res = sub i64 %a64, %b 311*9880d681SAndroid Build Coastguard Worker ret i64 %res 312*9880d681SAndroid Build Coastguard Worker} 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker; narrowing does work 315*9880d681SAndroid Build Coastguard Workerdefine i64 @narrow(i32* %P1) { 316*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @narrow( 317*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i64, i64* %p2 318*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: load atomic i32, i32* %P1 319*9880d681SAndroid Build Coastguard Worker %p2 = bitcast i32* %P1 to i64* 320*9880d681SAndroid Build Coastguard Worker %a64 = load atomic i64, i64* %p2 unordered, align 4 321*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 322*9880d681SAndroid Build Coastguard Worker %b64 = sext i32 %b to i64 323*9880d681SAndroid Build Coastguard Worker %res = sub i64 %a64, %b64 324*9880d681SAndroid Build Coastguard Worker ret i64 %res 325*9880d681SAndroid Build Coastguard Worker} 326*9880d681SAndroid Build Coastguard Worker 327*9880d681SAndroid Build Coastguard Worker; Missed optimization, we don't yet optimize ordered loads 328*9880d681SAndroid Build Coastguard Workerdefine i64 @narrow2(i32* %P1) { 329*9880d681SAndroid Build Coastguard Worker ; CHECK-LABEL: @narrow2( 330*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i64, i64* %p2 331*9880d681SAndroid Build Coastguard Worker ; CHECK: load atomic i32, i32* %P1 332*9880d681SAndroid Build Coastguard Worker %p2 = bitcast i32* %P1 to i64* 333*9880d681SAndroid Build Coastguard Worker %a64 = load atomic i64, i64* %p2 acquire, align 4 334*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 acquire, align 4 335*9880d681SAndroid Build Coastguard Worker %b64 = sext i32 %b to i64 336*9880d681SAndroid Build Coastguard Worker %res = sub i64 %a64, %b64 337*9880d681SAndroid Build Coastguard Worker ret i64 %res 338*9880d681SAndroid Build Coastguard Worker} 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Worker; Note: The cross block FRE testing is deliberately light. All of the tricky 341*9880d681SAndroid Build Coastguard Worker; bits of legality are shared code with the block-local FRE above. These 342*9880d681SAndroid Build Coastguard Worker; are here only to show that we haven't obviously broken anything. 343*9880d681SAndroid Build Coastguard Worker 344*9880d681SAndroid Build Coastguard Worker; unordered atomic to unordered atomic 345*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre(i32* %P1) { 346*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre( 347*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 348*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 349*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 350*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 unordered, align 4 351*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 352*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 353*9880d681SAndroid Build Coastguard Workerearly: 354*9880d681SAndroid Build Coastguard Worker ret i32 %a 355*9880d681SAndroid Build Coastguard Workernext: 356*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 357*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 358*9880d681SAndroid Build Coastguard Worker ret i32 %res 359*9880d681SAndroid Build Coastguard Worker} 360*9880d681SAndroid Build Coastguard Worker 361*9880d681SAndroid Build Coastguard Worker; unordered atomic to non-atomic 362*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre2(i32* %P1) { 363*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre2( 364*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 365*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 366*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 367*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 unordered, align 4 368*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 369*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 370*9880d681SAndroid Build Coastguard Workerearly: 371*9880d681SAndroid Build Coastguard Worker ret i32 %a 372*9880d681SAndroid Build Coastguard Workernext: 373*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %P1 374*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 375*9880d681SAndroid Build Coastguard Worker ret i32 %res 376*9880d681SAndroid Build Coastguard Worker} 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Worker; Can't forward ordered atomics. 379*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre3(i32* %P1) { 380*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre3( 381*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 acquire 382*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 383*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 acquire 384*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %res 385*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 acquire, align 4 386*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 387*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 388*9880d681SAndroid Build Coastguard Workerearly: 389*9880d681SAndroid Build Coastguard Worker ret i32 %a 390*9880d681SAndroid Build Coastguard Workernext: 391*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 acquire, align 4 392*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %b 393*9880d681SAndroid Build Coastguard Worker ret i32 %res 394*9880d681SAndroid Build Coastguard Worker} 395*9880d681SAndroid Build Coastguard Worker 396*9880d681SAndroid Build Coastguard Workerdeclare void @clobber() 397*9880d681SAndroid Build Coastguard Worker 398*9880d681SAndroid Build Coastguard Worker; unordered atomic to unordered atomic 399*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre(i32* %P1) { 400*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre( 401*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered 402*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered 403*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ] 404*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 405*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 unordered, align 4 406*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 407*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 408*9880d681SAndroid Build Coastguard Workerearly: 409*9880d681SAndroid Build Coastguard Worker call void @clobber() 410*9880d681SAndroid Build Coastguard Worker br label %next 411*9880d681SAndroid Build Coastguard Workernext: 412*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 413*9880d681SAndroid Build Coastguard Worker ret i32 %b 414*9880d681SAndroid Build Coastguard Worker} 415*9880d681SAndroid Build Coastguard Worker 416*9880d681SAndroid Build Coastguard Worker; unordered atomic to non-atomic 417*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre2(i32* %P1) { 418*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre2( 419*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered 420*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %P1 421*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ] 422*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 423*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 unordered, align 4 424*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 425*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 426*9880d681SAndroid Build Coastguard Workerearly: 427*9880d681SAndroid Build Coastguard Worker call void @clobber() 428*9880d681SAndroid Build Coastguard Worker br label %next 429*9880d681SAndroid Build Coastguard Workernext: 430*9880d681SAndroid Build Coastguard Worker %b = load i32, i32* %P1 431*9880d681SAndroid Build Coastguard Worker ret i32 %b 432*9880d681SAndroid Build Coastguard Worker} 433*9880d681SAndroid Build Coastguard Worker 434*9880d681SAndroid Build Coastguard Worker; non-atomic to unordered atomic - can't forward! 435*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre3(i32* %P1) { 436*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre3( 437*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load i32, i32* %P1 438*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load atomic i32, i32* %P1 unordered 439*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 440*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %P1 441*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 442*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 443*9880d681SAndroid Build Coastguard Workerearly: 444*9880d681SAndroid Build Coastguard Worker call void @clobber() 445*9880d681SAndroid Build Coastguard Worker br label %next 446*9880d681SAndroid Build Coastguard Workernext: 447*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 448*9880d681SAndroid Build Coastguard Worker ret i32 %b 449*9880d681SAndroid Build Coastguard Worker} 450*9880d681SAndroid Build Coastguard Worker 451*9880d681SAndroid Build Coastguard Worker; ordered atomic to ordered atomic - can't forward 452*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre4(i32* %P1) { 453*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre4( 454*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load atomic i32, i32* %P1 seq_cst 455*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load atomic i32, i32* %P1 seq_cst 456*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 457*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 458*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 459*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 460*9880d681SAndroid Build Coastguard Workerearly: 461*9880d681SAndroid Build Coastguard Worker call void @clobber() 462*9880d681SAndroid Build Coastguard Worker br label %next 463*9880d681SAndroid Build Coastguard Workernext: 464*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 seq_cst, align 4 465*9880d681SAndroid Build Coastguard Worker ret i32 %b 466*9880d681SAndroid Build Coastguard Worker} 467*9880d681SAndroid Build Coastguard Worker 468*9880d681SAndroid Build Coastguard Worker; can't remove volatile on any path 469*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre5(i32* %P1) { 470*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre5( 471*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load atomic i32, i32* %P1 seq_cst 472*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load volatile i32, i32* %P1 473*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 474*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 475*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 476*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 477*9880d681SAndroid Build Coastguard Workerearly: 478*9880d681SAndroid Build Coastguard Worker call void @clobber() 479*9880d681SAndroid Build Coastguard Worker br label %next 480*9880d681SAndroid Build Coastguard Workernext: 481*9880d681SAndroid Build Coastguard Worker %b = load volatile i32, i32* %P1 482*9880d681SAndroid Build Coastguard Worker ret i32 %b 483*9880d681SAndroid Build Coastguard Worker} 484*9880d681SAndroid Build Coastguard Worker 485*9880d681SAndroid Build Coastguard Worker 486*9880d681SAndroid Build Coastguard Worker; ordered atomic to unordered atomic 487*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre6(i32* %P1) { 488*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre6( 489*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 seq_cst 490*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered 491*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ] 492*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b 493*9880d681SAndroid Build Coastguard Worker %a = load atomic i32, i32* %P1 seq_cst, align 4 494*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %a, 0 495*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %early, label %next 496*9880d681SAndroid Build Coastguard Workerearly: 497*9880d681SAndroid Build Coastguard Worker call void @clobber() 498*9880d681SAndroid Build Coastguard Worker br label %next 499*9880d681SAndroid Build Coastguard Workernext: 500*9880d681SAndroid Build Coastguard Worker %b = load atomic i32, i32* %P1 unordered, align 4 501*9880d681SAndroid Build Coastguard Worker ret i32 %b 502*9880d681SAndroid Build Coastguard Worker} 503*9880d681SAndroid Build Coastguard Worker 504