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