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