1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S < %s -instcombine | 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; Check transforms involving atomic operations 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* %p) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test1( 10*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 11*9880d681SAndroid Build Coastguard Worker; CHECK: shl i32 %x, 1 12*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p seq_cst, align 4 13*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p, align 4 14*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 15*9880d681SAndroid Build Coastguard Worker ret i32 %z 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* %p) { 19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test2( 20*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load volatile i32, i32* %p, align 4 21*9880d681SAndroid Build Coastguard Worker; CHECK: %y = load volatile i32, i32* %p, align 4 22*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %p, align 4 23*9880d681SAndroid Build Coastguard Worker %y = load volatile i32, i32* %p, align 4 24*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 25*9880d681SAndroid Build Coastguard Worker ret i32 %z 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; The exact semantics of mixing volatile and non-volatile on the same 29*9880d681SAndroid Build Coastguard Worker; memory location are a bit unclear, but conservatively, we know we don't 30*9880d681SAndroid Build Coastguard Worker; want to remove the volatile. 31*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32* %p) { 32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test3( 33*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load volatile i32, i32* %p, align 4 34*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %p, align 4 35*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p, align 4 36*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 37*9880d681SAndroid Build Coastguard Worker ret i32 %z 38*9880d681SAndroid Build Coastguard Worker} 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; Forwarding from a stronger ordered atomic is fine 41*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32* %p) { 42*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test4( 43*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 44*9880d681SAndroid Build Coastguard Worker; CHECK: shl i32 %x, 1 45*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p seq_cst, align 4 46*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* %p unordered, align 4 47*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 48*9880d681SAndroid Build Coastguard Worker ret i32 %z 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker; Forwarding from a non-atomic is not. (The earlier load 52*9880d681SAndroid Build Coastguard Worker; could in priciple be promoted to atomic and then forwarded, 53*9880d681SAndroid Build Coastguard Worker; but we can't just drop the atomic from the load.) 54*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32* %p) { 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test5( 56*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p unordered, align 4 57*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p unordered, align 4 58*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p, align 4 59*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 60*9880d681SAndroid Build Coastguard Worker ret i32 %z 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; Forwarding atomic to atomic is fine 64*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i32* %p) { 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test6( 66*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p unordered, align 4 67*9880d681SAndroid Build Coastguard Worker; CHECK: shl i32 %x, 1 68*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p unordered, align 4 69*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* %p unordered, align 4 70*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 71*9880d681SAndroid Build Coastguard Worker ret i32 %z 72*9880d681SAndroid Build Coastguard Worker} 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker; FIXME: we currently don't do anything for monotonic 75*9880d681SAndroid Build Coastguard Workerdefine i32 @test7(i32* %p) { 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test7( 77*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 78*9880d681SAndroid Build Coastguard Worker; CHECK: %y = load atomic i32, i32* %p monotonic, align 4 79*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p seq_cst, align 4 80*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* %p monotonic, align 4 81*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 82*9880d681SAndroid Build Coastguard Worker ret i32 %z 83*9880d681SAndroid Build Coastguard Worker} 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker; FIXME: We could forward in racy code 86*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i32* %p) { 87*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test8( 88*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 89*9880d681SAndroid Build Coastguard Worker; CHECK: %y = load atomic i32, i32* %p acquire, align 4 90*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %p seq_cst, align 4 91*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* %p acquire, align 4 92*9880d681SAndroid Build Coastguard Worker %z = add i32 %x, %y 93*9880d681SAndroid Build Coastguard Worker ret i32 %z 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; An unordered access to null is still unreachable. There's no 97*9880d681SAndroid Build Coastguard Worker; ordering imposed. 98*9880d681SAndroid Build Coastguard Workerdefine i32 @test9() { 99*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test9( 100*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 undef, i32* null 101*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* null unordered, align 4 102*9880d681SAndroid Build Coastguard Worker ret i32 %x 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; FIXME: Could also fold 106*9880d681SAndroid Build Coastguard Workerdefine i32 @test10() { 107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test10( 108*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* null monotonic 109*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* null monotonic, align 4 110*9880d681SAndroid Build Coastguard Worker ret i32 %x 111*9880d681SAndroid Build Coastguard Worker} 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker; Would this be legal to fold? Probably? 114*9880d681SAndroid Build Coastguard Workerdefine i32 @test11() { 115*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test11( 116*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* null seq_cst 117*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* null seq_cst, align 4 118*9880d681SAndroid Build Coastguard Worker ret i32 %x 119*9880d681SAndroid Build Coastguard Worker} 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker; An unordered access to null is still unreachable. There's no 122*9880d681SAndroid Build Coastguard Worker; ordering imposed. 123*9880d681SAndroid Build Coastguard Workerdefine i32 @test12() { 124*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test12( 125*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32 undef, i32* null 126*9880d681SAndroid Build Coastguard Worker store atomic i32 0, i32* null unordered, align 4 127*9880d681SAndroid Build Coastguard Worker ret i32 0 128*9880d681SAndroid Build Coastguard Worker} 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker; FIXME: Could also fold 131*9880d681SAndroid Build Coastguard Workerdefine i32 @test13() { 132*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test13( 133*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32 0, i32* null monotonic 134*9880d681SAndroid Build Coastguard Worker store atomic i32 0, i32* null monotonic, align 4 135*9880d681SAndroid Build Coastguard Worker ret i32 0 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker; Would this be legal to fold? Probably? 139*9880d681SAndroid Build Coastguard Workerdefine i32 @test14() { 140*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test14( 141*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32 0, i32* null seq_cst 142*9880d681SAndroid Build Coastguard Worker store atomic i32 0, i32* null seq_cst, align 4 143*9880d681SAndroid Build Coastguard Worker ret i32 0 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker@a = external global i32 147*9880d681SAndroid Build Coastguard Worker@b = external global i32 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Workerdefine i32 @test15(i1 %cnd) { 150*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test15( 151*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @a unordered, align 4 152*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @b unordered, align 4 153*9880d681SAndroid Build Coastguard Worker %addr = select i1 %cnd, i32* @a, i32* @b 154*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %addr unordered, align 4 155*9880d681SAndroid Build Coastguard Worker ret i32 %x 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; FIXME: This would be legal to transform 159*9880d681SAndroid Build Coastguard Workerdefine i32 @test16(i1 %cnd) { 160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test16( 161*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %addr monotonic, align 4 162*9880d681SAndroid Build Coastguard Worker %addr = select i1 %cnd, i32* @a, i32* @b 163*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %addr monotonic, align 4 164*9880d681SAndroid Build Coastguard Worker ret i32 %x 165*9880d681SAndroid Build Coastguard Worker} 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker; FIXME: This would be legal to transform 168*9880d681SAndroid Build Coastguard Workerdefine i32 @test17(i1 %cnd) { 169*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test17( 170*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %addr seq_cst, align 4 171*9880d681SAndroid Build Coastguard Worker %addr = select i1 %cnd, i32* @a, i32* @b 172*9880d681SAndroid Build Coastguard Worker %x = load atomic i32, i32* %addr seq_cst, align 4 173*9880d681SAndroid Build Coastguard Worker ret i32 %x 174*9880d681SAndroid Build Coastguard Worker} 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerdefine i32 @test22(i1 %cnd) { 177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test22( 178*9880d681SAndroid Build Coastguard Worker; CHECK: [[PHI:%.*]] = phi i32 179*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32 [[PHI]], i32* @a unordered, align 4 180*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %block1, label %block2 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerblock1: 183*9880d681SAndroid Build Coastguard Worker store atomic i32 1, i32* @a unordered, align 4 184*9880d681SAndroid Build Coastguard Worker br label %merge 185*9880d681SAndroid Build Coastguard Workerblock2: 186*9880d681SAndroid Build Coastguard Worker store atomic i32 2, i32* @a unordered, align 4 187*9880d681SAndroid Build Coastguard Worker br label %merge 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Workermerge: 190*9880d681SAndroid Build Coastguard Worker ret i32 0 191*9880d681SAndroid Build Coastguard Worker} 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker; TODO: probably also legal here 194*9880d681SAndroid Build Coastguard Workerdefine i32 @test23(i1 %cnd) { 195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test23( 196*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cnd, label %block1, label %block2 197*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %block1, label %block2 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Workerblock1: 200*9880d681SAndroid Build Coastguard Worker store atomic i32 1, i32* @a monotonic, align 4 201*9880d681SAndroid Build Coastguard Worker br label %merge 202*9880d681SAndroid Build Coastguard Workerblock2: 203*9880d681SAndroid Build Coastguard Worker store atomic i32 2, i32* @a monotonic, align 4 204*9880d681SAndroid Build Coastguard Worker br label %merge 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Workermerge: 207*9880d681SAndroid Build Coastguard Worker ret i32 0 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Workerdeclare void @clobber() 211*9880d681SAndroid Build Coastguard Worker 212*9880d681SAndroid Build Coastguard Workerdefine i32 @test18(float* %p) { 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test18( 214*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* [[A:%.*]] unordered, align 4 215*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32 [[B:%.*]], i32* [[C:%.*]] unordered, align 4 216*9880d681SAndroid Build Coastguard Worker %x = load atomic float, float* %p unordered, align 4 217*9880d681SAndroid Build Coastguard Worker call void @clobber() ;; keep the load around 218*9880d681SAndroid Build Coastguard Worker store atomic float %x, float* %p unordered, align 4 219*9880d681SAndroid Build Coastguard Worker ret i32 0 220*9880d681SAndroid Build Coastguard Worker} 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker; TODO: probably also legal in this case 223*9880d681SAndroid Build Coastguard Workerdefine i32 @test19(float* %p) { 224*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test19( 225*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic float, float* %p seq_cst, align 4 226*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic float %x, float* %p seq_cst, align 4 227*9880d681SAndroid Build Coastguard Worker %x = load atomic float, float* %p seq_cst, align 4 228*9880d681SAndroid Build Coastguard Worker call void @clobber() ;; keep the load around 229*9880d681SAndroid Build Coastguard Worker store atomic float %x, float* %p seq_cst, align 4 230*9880d681SAndroid Build Coastguard Worker ret i32 0 231*9880d681SAndroid Build Coastguard Worker} 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Workerdefine i32 @test20(i32** %p, i8* %v) { 234*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test20( 235*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i8* %v, i8** [[D:%.*]] unordered, align 4 236*9880d681SAndroid Build Coastguard Worker %cast = bitcast i8* %v to i32* 237*9880d681SAndroid Build Coastguard Worker store atomic i32* %cast, i32** %p unordered, align 4 238*9880d681SAndroid Build Coastguard Worker ret i32 0 239*9880d681SAndroid Build Coastguard Worker} 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Workerdefine i32 @test21(i32** %p, i8* %v) { 242*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test21( 243*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i32* %cast, i32** %p monotonic, align 4 244*9880d681SAndroid Build Coastguard Worker %cast = bitcast i8* %v to i32* 245*9880d681SAndroid Build Coastguard Worker store atomic i32* %cast, i32** %p monotonic, align 4 246*9880d681SAndroid Build Coastguard Worker ret i32 0 247*9880d681SAndroid Build Coastguard Worker} 248*9880d681SAndroid Build Coastguard Worker 249*9880d681SAndroid Build Coastguard Workerdefine void @pr27490a(i8** %p1, i8** %p2) { 250*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @pr27490 251*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = bitcast i8** %p1 to i64* 252*9880d681SAndroid Build Coastguard Worker; CHECK: %l1 = load i64, i64* %1, align 8 253*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = bitcast i8** %p2 to i64* 254*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile i64 %l1, i64* %2, align 8 255*9880d681SAndroid Build Coastguard Worker %l = load i8*, i8** %p1 256*9880d681SAndroid Build Coastguard Worker store volatile i8* %l, i8** %p2 257*9880d681SAndroid Build Coastguard Worker ret void 258*9880d681SAndroid Build Coastguard Worker} 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Workerdefine void @pr27490b(i8** %p1, i8** %p2) { 261*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @pr27490 262*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = bitcast i8** %p1 to i64* 263*9880d681SAndroid Build Coastguard Worker; CHECK: %l1 = load i64, i64* %1, align 8 264*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = bitcast i8** %p2 to i64* 265*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic i64 %l1, i64* %2 seq_cst, align 8 266*9880d681SAndroid Build Coastguard Worker %l = load i8*, i8** %p1 267*9880d681SAndroid Build Coastguard Worker store atomic i8* %l, i8** %p2 seq_cst, align 8 268*9880d681SAndroid Build Coastguard Worker ret void 269*9880d681SAndroid Build Coastguard Worker} 270