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