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