1 // RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s 2 3 int S; 4 volatile int vS; 5 6 int* pS; 7 volatile int* pvS; 8 9 int A[10]; 10 volatile int vA[10]; 11 12 struct { int x; } F; 13 struct { volatile int x; } vF; 14 15 struct { int x; } F2; 16 volatile struct { int x; } vF2; 17 volatile struct { int x; } *vpF2; 18 19 struct { struct { int y; } x; } F3; 20 volatile struct { struct { int y; } x; } vF3; 21 22 struct { int x:3; } BF; 23 struct { volatile int x:3; } vBF; 24 25 typedef int v4si __attribute__ ((vector_size (16))); 26 v4si V; 27 volatile v4si vV; 28 29 typedef __attribute__(( ext_vector_type(4) )) int extv4; 30 extv4 VE; 31 volatile extv4 vVE; 32 33 volatile struct {int x;} aggFct(void); 34 35 typedef volatile int volatile_int; 36 volatile_int vtS; 37 38 int 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