1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -Wno-unused-value -emit-llvm %s -o - | FileCheck %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc // CHECK: @i = global [[INT:i[0-9]+]] 0 4*f4a2713aSLionel Sambuc volatile int i, j, k; 5*f4a2713aSLionel Sambuc volatile int ar[5]; 6*f4a2713aSLionel Sambuc volatile char c; 7*f4a2713aSLionel Sambuc // CHECK: @ci = global [[CINT:.*]] zeroinitializer 8*f4a2713aSLionel Sambuc volatile _Complex int ci; 9*f4a2713aSLionel Sambuc volatile struct S { 10*f4a2713aSLionel Sambuc #ifdef __cplusplus 11*f4a2713aSLionel Sambuc void operator =(volatile struct S&o) volatile; 12*f4a2713aSLionel Sambuc #endif 13*f4a2713aSLionel Sambuc int i; 14*f4a2713aSLionel Sambuc } a, b; 15*f4a2713aSLionel Sambuc 16*f4a2713aSLionel Sambuc //void operator =(volatile struct S&o1, volatile struct S&o2) volatile; 17*f4a2713aSLionel Sambuc int printf(const char *, ...); 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc 20*f4a2713aSLionel Sambuc // CHECK: define void @{{.*}}test 21*f4a2713aSLionel Sambuc void test() { 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc asm("nop"); // CHECK: call void asm 24*f4a2713aSLionel Sambuc 25*f4a2713aSLionel Sambuc // should not load 26*f4a2713aSLionel Sambuc i; 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc (float)(ci); 29*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 30*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 31*f4a2713aSLionel Sambuc // CHECK-NEXT: sitofp [[INT]] 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel Sambuc // These are not uses in C++: 34*f4a2713aSLionel Sambuc // [expr.static.cast]p6: 35*f4a2713aSLionel Sambuc // The lvalue-to-rvalue . . . conversions are not applied to the expression. 36*f4a2713aSLionel Sambuc (void)ci; 37*f4a2713aSLionel Sambuc (void)a; 38*f4a2713aSLionel Sambuc 39*f4a2713aSLionel Sambuc (void)(ci=ci); 40*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 41*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 42*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 43*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 44*f4a2713aSLionel Sambuc 45*f4a2713aSLionel Sambuc (void)(i=j); 46*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j 47*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i 48*f4a2713aSLionel Sambuc 49*f4a2713aSLionel Sambuc ci+=ci; 50*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 51*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 52*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 53*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 54*f4a2713aSLionel Sambuc // Not sure why they're ordered this way. 55*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] 56*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] 57*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 58*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 59*f4a2713aSLionel Sambuc 60*f4a2713aSLionel Sambuc // Note that C++ requires an extra load volatile over C from the LHS of the '+'. 61*f4a2713aSLionel Sambuc (ci += ci) + ci; 62*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 63*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 64*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 65*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 66*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] 67*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] 68*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 69*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 70*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 71*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 72*f4a2713aSLionel Sambuc // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) 73*f4a2713aSLionel Sambuc // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 74*f4a2713aSLionel Sambuc // These additions can be elided. 75*f4a2713aSLionel Sambuc // CHECK-NEXT: add [[INT]] [[R1]], [[R2]] 76*f4a2713aSLionel Sambuc // CHECK-NEXT: add [[INT]] [[I1]], [[I2]] 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 79*f4a2713aSLionel Sambuc 80*f4a2713aSLionel Sambuc // Extra load volatile in C++. 81*f4a2713aSLionel Sambuc (i += j) + k; 82*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 83*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 84*f4a2713aSLionel Sambuc // CHECK-NEXT: add nsw [[INT]] 85*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 86*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 87*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 88*f4a2713aSLionel Sambuc // CHECK-NEXT: add nsw [[INT]] 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 91*f4a2713aSLionel Sambuc 92*f4a2713aSLionel Sambuc // Extra load volatile in C++. 93*f4a2713aSLionel Sambuc (i += j) + 1; 94*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 95*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 96*f4a2713aSLionel Sambuc // CHECK-NEXT: add nsw [[INT]] 97*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 98*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 99*f4a2713aSLionel Sambuc // CHECK-NEXT: add nsw [[INT]] 100*f4a2713aSLionel Sambuc 101*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 102*f4a2713aSLionel Sambuc 103*f4a2713aSLionel Sambuc ci+ci; 104*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 105*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 106*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 107*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 108*f4a2713aSLionel Sambuc // CHECK-NEXT: add [[INT]] 109*f4a2713aSLionel Sambuc // CHECK-NEXT: add [[INT]] 110*f4a2713aSLionel Sambuc 111*f4a2713aSLionel Sambuc __real i; 112*f4a2713aSLionel Sambuc 113*f4a2713aSLionel Sambuc +ci; 114*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 115*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 118*f4a2713aSLionel Sambuc 119*f4a2713aSLionel Sambuc (void)(i=i); 120*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 121*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 122*f4a2713aSLionel Sambuc 123*f4a2713aSLionel Sambuc (float)(i=i); 124*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 125*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 126*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 127*f4a2713aSLionel Sambuc // CHECK-NEXT: sitofp 128*f4a2713aSLionel Sambuc 129*f4a2713aSLionel Sambuc (void)i; 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc i=i; 132*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 133*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc // Extra load volatile in C++. 136*f4a2713aSLionel Sambuc i=i=i; 137*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 138*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 139*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 140*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 141*f4a2713aSLionel Sambuc 142*f4a2713aSLionel Sambuc (void)__builtin_choose_expr(0, i=i, j=j); 143*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 144*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 145*f4a2713aSLionel Sambuc 146*f4a2713aSLionel Sambuc k ? (i=i) : (j=j); 147*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 148*f4a2713aSLionel Sambuc // CHECK-NEXT: icmp 149*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 150*f4a2713aSLionel Sambuc // CHECK: load volatile 151*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 152*f4a2713aSLionel Sambuc // CHECK-NEXT: br label 153*f4a2713aSLionel Sambuc // CHECK: load volatile 154*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 155*f4a2713aSLionel Sambuc // CHECK-NEXT: br label 156*f4a2713aSLionel Sambuc // CHECK: phi 157*f4a2713aSLionel Sambuc 158*f4a2713aSLionel Sambuc (void)(i,(i=i)); 159*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 160*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 161*f4a2713aSLionel Sambuc 162*f4a2713aSLionel Sambuc i=i,k; 163*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @i 164*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc (i=j,k=j); 167*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @j 168*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i 169*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @j 170*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k 171*f4a2713aSLionel Sambuc 172*f4a2713aSLionel Sambuc (i=j,k); 173*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @j 174*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i 175*f4a2713aSLionel Sambuc 176*f4a2713aSLionel Sambuc (i,j); 177*f4a2713aSLionel Sambuc 178*f4a2713aSLionel Sambuc // Extra load in C++. 179*f4a2713aSLionel Sambuc i=c=k; 180*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 181*f4a2713aSLionel Sambuc // CHECK-NEXT: trunc 182*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 183*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 184*f4a2713aSLionel Sambuc // CHECK-NEXT: sext 185*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 186*f4a2713aSLionel Sambuc 187*f4a2713aSLionel Sambuc i+=k; 188*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 189*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 190*f4a2713aSLionel Sambuc // CHECK-NEXT: add nsw [[INT]] 191*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 192*f4a2713aSLionel Sambuc 193*f4a2713aSLionel Sambuc ci; 194*f4a2713aSLionel Sambuc 195*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 196*f4a2713aSLionel Sambuc 197*f4a2713aSLionel Sambuc (int)ci; 198*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0 199*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1 200*f4a2713aSLionel Sambuc 201*f4a2713aSLionel Sambuc (bool)ci; 202*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0 203*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1 204*f4a2713aSLionel Sambuc // CHECK-NEXT: icmp ne 205*f4a2713aSLionel Sambuc // CHECK-NEXT: icmp ne 206*f4a2713aSLionel Sambuc // CHECK-NEXT: or i1 207*f4a2713aSLionel Sambuc 208*f4a2713aSLionel Sambuc ci=ci; 209*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 210*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 211*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 212*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 213*f4a2713aSLionel Sambuc 214*f4a2713aSLionel Sambuc asm("nop"); // CHECK-NEXT: call void asm 215*f4a2713aSLionel Sambuc 216*f4a2713aSLionel Sambuc // Extra load in C++. 217*f4a2713aSLionel Sambuc ci=ci=ci; 218*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 219*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 220*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 221*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 222*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 223*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 224*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 225*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc __imag ci = __imag ci = __imag ci; 228*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 229*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 230*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 231*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) 232*f4a2713aSLionel Sambuc 233*f4a2713aSLionel Sambuc __real (i = j); 234*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 235*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 236*f4a2713aSLionel Sambuc 237*f4a2713aSLionel Sambuc __imag i; 238*f4a2713aSLionel Sambuc 239*f4a2713aSLionel Sambuc // ============================================================ 240*f4a2713aSLionel Sambuc // FIXME: Test cases we get wrong. 241*f4a2713aSLionel Sambuc 242*f4a2713aSLionel Sambuc // A use. We load all of a into a copy of a, then load i. gcc forgets to do 243*f4a2713aSLionel Sambuc // the assignment. 244*f4a2713aSLionel Sambuc // (a = a).i; 245*f4a2713aSLionel Sambuc 246*f4a2713aSLionel Sambuc // ============================================================ 247*f4a2713aSLionel Sambuc // Test cases where we intentionally differ from gcc, due to suspected bugs in 248*f4a2713aSLionel Sambuc // gcc. 249*f4a2713aSLionel Sambuc 250*f4a2713aSLionel Sambuc // Not a use. gcc forgets to do the assignment. 251*f4a2713aSLionel Sambuc // CHECK-NEXT: call 252*f4a2713aSLionel Sambuc ((a=a),a); 253*f4a2713aSLionel Sambuc 254*f4a2713aSLionel Sambuc // Not a use. gcc gets this wrong, it doesn't emit the copy! 255*f4a2713aSLionel Sambuc // CHECK-NEXT: call 256*f4a2713aSLionel Sambuc (void)(a=a); 257*f4a2713aSLionel Sambuc 258*f4a2713aSLionel Sambuc // Not a use. gcc got this wrong in 4.2 and omitted the side effects 259*f4a2713aSLionel Sambuc // entirely, but it is fixed in 4.4.0. 260*f4a2713aSLionel Sambuc __imag (i = j); 261*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 262*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 263*f4a2713aSLionel Sambuc 264*f4a2713aSLionel Sambuc // C++ does an extra load here. Note that we have to do full loads. 265*f4a2713aSLionel Sambuc (float)(ci=ci); 266*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 267*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 268*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 269*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 270*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 271*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 272*f4a2713aSLionel Sambuc // CHECK-NEXT: sitofp 273*f4a2713aSLionel Sambuc 274*f4a2713aSLionel Sambuc // Not a use, bug? gcc treats this as not a use, that's probably a 275*f4a2713aSLionel Sambuc // bug due to tree folding ignoring volatile. 276*f4a2713aSLionel Sambuc (int)(ci=ci); 277*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 278*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 279*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 280*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 281*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 282*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 283*f4a2713aSLionel Sambuc 284*f4a2713aSLionel Sambuc // A use. 285*f4a2713aSLionel Sambuc (float)(i=i); 286*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 287*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 288*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 289*f4a2713aSLionel Sambuc // CHECK-NEXT: sitofp 290*f4a2713aSLionel Sambuc 291*f4a2713aSLionel Sambuc // A use. gcc treats this as not a use, that's probably a bug due to tree 292*f4a2713aSLionel Sambuc // folding ignoring volatile. 293*f4a2713aSLionel Sambuc (int)(i=i); 294*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 295*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 296*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 297*f4a2713aSLionel Sambuc 298*f4a2713aSLionel Sambuc // A use. 299*f4a2713aSLionel Sambuc -(i=j); 300*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 301*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 302*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 303*f4a2713aSLionel Sambuc // CHECK-NEXT: sub 304*f4a2713aSLionel Sambuc 305*f4a2713aSLionel Sambuc // A use. gcc treats this a not a use, that's probably a bug due to tree 306*f4a2713aSLionel Sambuc // folding ignoring volatile. 307*f4a2713aSLionel Sambuc +(i=k); 308*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 309*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 310*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 311*f4a2713aSLionel Sambuc 312*f4a2713aSLionel Sambuc // A use. gcc treats this a not a use, that's probably a bug due to tree 313*f4a2713aSLionel Sambuc // folding ignoring volatile. 314*f4a2713aSLionel Sambuc __real (ci=ci); 315*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 316*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 317*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 318*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 319*f4a2713aSLionel Sambuc 320*f4a2713aSLionel Sambuc // A use. 321*f4a2713aSLionel Sambuc i + 0; 322*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 323*f4a2713aSLionel Sambuc // CHECK-NEXT: add 324*f4a2713aSLionel Sambuc 325*f4a2713aSLionel Sambuc // A use. 326*f4a2713aSLionel Sambuc (i=j) + i; 327*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 328*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 329*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 330*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 331*f4a2713aSLionel Sambuc // CHECK-NEXT: add 332*f4a2713aSLionel Sambuc 333*f4a2713aSLionel Sambuc // A use. gcc treats this as not a use, that's probably a bug due to tree 334*f4a2713aSLionel Sambuc // folding ignoring volatile. 335*f4a2713aSLionel Sambuc (i=j) + 0; 336*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 337*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile 338*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile 339*f4a2713aSLionel Sambuc // CHECK-NEXT: add 340*f4a2713aSLionel Sambuc 341*f4a2713aSLionel Sambuc (i,j)=k; 342*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @k 343*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j 344*f4a2713aSLionel Sambuc 345*f4a2713aSLionel Sambuc (j=k,i)=i; 346*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @i 347*f4a2713aSLionel Sambuc // CHECK-NEXT: load volatile [[INT]]* @k 348*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j 349*f4a2713aSLionel Sambuc // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i 350*f4a2713aSLionel Sambuc 351*f4a2713aSLionel Sambuc // CHECK-NEXT: ret void 352*f4a2713aSLionel Sambuc } 353