1 // RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -emit-llvm < %s | FileCheck %s -check-prefix CHECK -check-prefixes CHECK-IT,CHECK-IT-ARM 2 // RUN: %clang_cc1 -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 -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 40 int main() { 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