1// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s 2 3int S; 4volatile int vS; 5 6int* pS; 7volatile int* pvS; 8 9int A[10]; 10volatile int vA[10]; 11 12struct { int x; } F; 13struct { volatile int x; } vF; 14 15struct { int x; } F2; 16volatile struct { int x; } vF2; 17volatile struct { int x; } *vpF2; 18 19struct { struct { int y; } x; } F3; 20volatile struct { struct { int y; } x; } vF3; 21 22struct { int x:3; } BF; 23struct { volatile int x:3; } vBF; 24 25typedef int v4si __attribute__ ((vector_size (16))); 26v4si V; 27volatile v4si vV; 28 29typedef __attribute__(( ext_vector_type(4) )) int extv4; 30extv4 VE; 31volatile extv4 vVE; 32 33volatile struct {int x;} aggFct(void); 34 35typedef volatile int volatile_int; 36volatile_int vtS; 37 38int main() { 39 int i; 40// CHECK: [[I:%[a-zA-Z0-9_.]+]] = alloca i32 41 // load 42 i=S; 43// CHECK: load i32* @S 44// CHECK: store i32 {{.*}}, i32* [[I]] 45 i=vS; 46// CHECK: load volatile i32* @vS 47// CHECK: store i32 {{.*}}, i32* [[I]] 48 i=*pS; 49// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS 50// CHECK: load i32* [[PS_VAL]] 51// CHECK: store i32 {{.*}}, i32* [[I]] 52 i=*pvS; 53// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS 54// CHECK: load volatile i32* [[PVS_VAL]] 55// CHECK: store i32 {{.*}}, i32* [[I]] 56 i=A[2]; 57// CHECK: load i32* getelementptr {{.*}} @A 58// CHECK: store i32 {{.*}}, i32* [[I]] 59 i=vA[2]; 60// CHECK: load volatile i32* getelementptr {{.*}} @vA 61// CHECK: store i32 {{.*}}, i32* [[I]] 62 i=F.x; 63// CHECK: load i32* getelementptr {{.*}} @F 64// CHECK: store i32 {{.*}}, i32* [[I]] 65 i=vF.x; 66// CHECK: load volatile i32* getelementptr {{.*}} @vF 67// CHECK: store i32 {{.*}}, i32* [[I]] 68 i=F2.x; 69// CHECK: load i32* getelementptr {{.*}} @F2 70// CHECK: store i32 {{.*}}, i32* [[I]] 71 i=vF2.x; 72// CHECK: load volatile i32* getelementptr {{.*}} @vF2 73// CHECK: store i32 {{.*}}, i32* [[I]] 74 i=vpF2->x; 75// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9_.]+}}** @vpF2 76// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]] 77// CHECK: load volatile i32* [[ELT]] 78// CHECK: store i32 {{.*}}, i32* [[I]] 79 i=F3.x.y; 80// CHECK: load i32* getelementptr {{.*}} @F3 81// CHECK: store i32 {{.*}}, i32* [[I]] 82 i=vF3.x.y; 83// CHECK: load volatile i32* getelementptr {{.*}} @vF3 84// CHECK: store i32 {{.*}}, i32* [[I]] 85 i=BF.x; 86// CHECK: load i8* getelementptr {{.*}} @BF 87// CHECK: store i32 {{.*}}, i32* [[I]] 88 i=vBF.x; 89// CHECK: load volatile i8* getelementptr {{.*}} @vBF 90// CHECK: store i32 {{.*}}, i32* [[I]] 91 i=V[3]; 92// CHECK: load <4 x i32>* @V 93// CHECK: store i32 {{.*}}, i32* [[I]] 94 i=vV[3]; 95// CHECK: load volatile <4 x i32>* @vV 96// CHECK: store i32 {{.*}}, i32* [[I]] 97 i=VE.yx[1]; 98// CHECK: load <4 x i32>* @VE 99// CHECK: store i32 {{.*}}, i32* [[I]] 100 i=vVE.zy[1]; 101// CHECK: load volatile <4 x i32>* @vVE 102// CHECK: store i32 {{.*}}, i32* [[I]] 103 i = aggFct().x; // Note: not volatile 104 // N.b. Aggregate return is extremely target specific, all we can 105 // really say here is that there probably shouldn't be a volatile 106 // load. 107// CHECK-NOT: load volatile 108// CHECK: store i32 {{.*}}, i32* [[I]] 109 i=vtS; 110// CHECK: load volatile i32* @vtS 111// CHECK: store i32 {{.*}}, i32* [[I]] 112 113 114 // store 115 S=i; 116// CHECK: load i32* [[I]] 117// CHECK: store i32 {{.*}}, i32* @S 118 vS=i; 119// CHECK: load i32* [[I]] 120// CHECK: store volatile i32 {{.*}}, i32* @vS 121 *pS=i; 122// CHECK: load i32* [[I]] 123// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS 124// CHECK: store i32 {{.*}}, i32* [[PS_VAL]] 125 *pvS=i; 126// CHECK: load i32* [[I]] 127// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS 128// CHECK: store volatile i32 {{.*}}, i32* [[PVS_VAL]] 129 A[2]=i; 130// CHECK: load i32* [[I]] 131// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @A 132 vA[2]=i; 133// CHECK: load i32* [[I]] 134// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vA 135 F.x=i; 136// CHECK: load i32* [[I]] 137// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F 138 vF.x=i; 139// CHECK: load i32* [[I]] 140// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF 141 F2.x=i; 142// CHECK: load i32* [[I]] 143// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F2 144 vF2.x=i; 145// CHECK: load i32* [[I]] 146// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF2 147 vpF2->x=i; 148// CHECK: load i32* [[I]] 149// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9._]+}}** @vpF2 150// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]] 151// CHECK: store volatile i32 {{.*}}, i32* [[ELT]] 152 vF3.x.y=i; 153// CHECK: load i32* [[I]] 154// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF3 155 BF.x=i; 156// CHECK: load i32* [[I]] 157// CHECK: load i8* getelementptr {{.*}} @BF 158// CHECK: store i8 {{.*}}, i8* getelementptr {{.*}} @BF 159 vBF.x=i; 160// CHECK: load i32* [[I]] 161// CHECK: load volatile i8* getelementptr {{.*}} @vBF 162// CHECK: store volatile i8 {{.*}}, i8* getelementptr {{.*}} @vBF 163 V[3]=i; 164// CHECK: load i32* [[I]] 165// CHECK: load <4 x i32>* @V 166// CHECK: store <4 x i32> {{.*}}, <4 x i32>* @V 167 vV[3]=i; 168// CHECK: load i32* [[I]] 169// CHECK: load volatile <4 x i32>* @vV 170// CHECK: store volatile <4 x i32> {{.*}}, <4 x i32>* @vV 171 vtS=i; 172// CHECK: load i32* [[I]] 173// CHECK: store volatile i32 {{.*}}, i32* @vtS 174 175 // other ops: 176 ++S; 177// CHECK: load i32* @S 178// CHECK: store i32 {{.*}}, i32* @S 179 ++vS; 180// CHECK: load volatile i32* @vS 181// CHECK: store volatile i32 {{.*}}, i32* @vS 182 i+=S; 183// CHECK: load i32* @S 184// CHECK: load i32* [[I]] 185// CHECK: store i32 {{.*}}, i32* [[I]] 186 i+=vS; 187// CHECK: load volatile i32* @vS 188// CHECK: load i32* [[I]] 189// CHECK: store i32 {{.*}}, i32* [[I]] 190 ++vtS; 191// CHECK: load volatile i32* @vtS 192// CHECK: store volatile i32 {{.*}}, i32* @vtS 193 (void)vF2; 194 // From vF2 to a temporary 195// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*}} @vF2 {{.*}}, i1 true) 196 vF2 = vF2; 197 // vF2 to itself 198// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) 199 vF2 = vF2 = vF2; 200 // vF2 to itself twice 201// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) 202// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) 203 vF2 = (vF2, vF2); 204 // vF2 to a temporary, then vF2 to itself 205// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*@vF2.*}}, i1 true) 206// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) 207} 208