1 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s 2 // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s 3 // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s 4 5 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 6 // RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s 7 // RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s 8 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} 9 // expected-no-diagnostics 10 // REQUIRES: x86-registered-target 11 #ifndef HEADER 12 #define HEADER 13 14 _Bool bv, bx; 15 char cv, cx; 16 unsigned char ucv, ucx; 17 short sv, sx; 18 unsigned short usv, usx; 19 int iv, ix; 20 unsigned int uiv, uix; 21 long lv, lx; 22 unsigned long ulv, ulx; 23 long long llv, llx; 24 unsigned long long ullv, ullx; 25 float fv, fx; 26 double dv, dx; 27 long double ldv, ldx; 28 _Complex int civ, cix; 29 _Complex float cfv, cfx; 30 _Complex double cdv, cdx; 31 32 typedef int int4 __attribute__((__vector_size__(16))); 33 int4 int4x; 34 35 struct BitFields { 36 int : 32; 37 int a : 31; 38 } bfx; 39 40 struct BitFields_packed { 41 int : 32; 42 int a : 31; 43 } __attribute__ ((__packed__)) bfx_packed; 44 45 struct BitFields2 { 46 int : 31; 47 int a : 1; 48 } bfx2; 49 50 struct BitFields2_packed { 51 int : 31; 52 int a : 1; 53 } __attribute__ ((__packed__)) bfx2_packed; 54 55 struct BitFields3 { 56 int : 11; 57 int a : 14; 58 } bfx3; 59 60 struct BitFields3_packed { 61 int : 11; 62 int a : 14; 63 } __attribute__ ((__packed__)) bfx3_packed; 64 65 struct BitFields4 { 66 short : 16; 67 int a: 1; 68 long b : 7; 69 } bfx4; 70 71 struct BitFields4_packed { 72 short : 16; 73 int a: 1; 74 long b : 7; 75 } __attribute__ ((__packed__)) bfx4_packed; 76 77 typedef float float2 __attribute__((ext_vector_type(2))); 78 float2 float2x; 79 80 // Register "0" is currently an invalid register for global register variables. 81 // Use "esp" instead of "0". 82 // register int rix __asm__("0"); 83 register int rix __asm__("esp"); 84 85 // CHECK-LABEL: @main( 86 int main(void) { 87 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 88 // CHECK: store i8 89 #pragma omp atomic read 90 bv = bx; 91 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 92 // CHECK: store i8 93 #pragma omp atomic read 94 cv = cx; 95 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 96 // CHECK: store i8 97 #pragma omp atomic read 98 ucv = ucx; 99 // CHECK: load atomic i16, ptr {{.*}} monotonic, align 2 100 // CHECK: store i16 101 #pragma omp atomic read 102 sv = sx; 103 // CHECK: load atomic i16, ptr {{.*}} monotonic, align 2 104 // CHECK: store i16 105 #pragma omp atomic read 106 usv = usx; 107 // CHECK: load atomic i32, ptr {{.*}} monotonic, align 4 108 // CHECK: store i32 109 #pragma omp atomic read 110 iv = ix; 111 // CHECK: load atomic i32, ptr {{.*}} monotonic, align 4 112 // CHECK: store i32 113 #pragma omp atomic read 114 uiv = uix; 115 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 116 // CHECK: store i64 117 #pragma omp atomic read 118 lv = lx; 119 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 120 // CHECK: store i64 121 #pragma omp atomic read 122 ulv = ulx; 123 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 124 // CHECK: store i64 125 #pragma omp atomic read 126 llv = llx; 127 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 128 // CHECK: store i64 129 #pragma omp atomic read 130 ullv = ullx; 131 // CHECK: load atomic float, ptr {{.*}} monotonic, align 4 132 // CHECK: store float 133 #pragma omp atomic read 134 fv = fx; 135 // CHECK: load atomic double, ptr {{.*}} monotonic, align 8 136 // CHECK: store double 137 #pragma omp atomic read 138 dv = dx; 139 // CHECK: [[LD:%.+]] = load atomic i128, ptr {{.*}} monotonic, align 16 140 // CHECK: store i128 [[LD]], ptr [[LDTEMP:%.+]] 141 // CHECK: [[LD:%.+]] = load x86_fp80, ptr [[LDTEMP]] 142 // CHECK: store x86_fp80 [[LD]] 143 #pragma omp atomic read 144 ldv = ldx; 145 // CHECK: call{{.*}} void @__atomic_load(i64 noundef 8, 146 // CHECK: store i32 147 // CHECK: store i32 148 #pragma omp atomic read 149 civ = cix; 150 // CHECK: call{{.*}} void @__atomic_load(i64 noundef 8, 151 // CHECK: store float 152 // CHECK: store float 153 #pragma omp atomic read 154 cfv = cfx; 155 // CHECK: call{{.*}} void @__atomic_load(i64 noundef 16, 156 // CHECK: call{{.*}} @__kmpc_flush( 157 // CHECK: store double 158 // CHECK: store double 159 #pragma omp atomic seq_cst read 160 cdv = cdx; 161 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 162 // CHECK: store i8 163 #pragma omp atomic read 164 bv = ulx; 165 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 166 // CHECK: store i8 167 #pragma omp atomic read 168 cv = bx; 169 // CHECK: load atomic i8, ptr {{.*}} seq_cst, align 1 170 // CHECK: call{{.*}} @__kmpc_flush( 171 // CHECK: store i8 172 #pragma omp atomic read seq_cst 173 ucv = cx; 174 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 175 // CHECK: store i16 176 #pragma omp atomic read 177 sv = ulx; 178 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 179 // CHECK: store i16 180 #pragma omp atomic read 181 usv = lx; 182 // CHECK: load atomic i32, ptr {{.*}} seq_cst, align 4 183 // CHECK: call{{.*}} @__kmpc_flush( 184 // CHECK: store i32 185 #pragma omp atomic seq_cst, read 186 iv = uix; 187 // CHECK: load atomic i32, ptr {{.*}} monotonic, align 4 188 // CHECK: store i32 189 #pragma omp atomic read 190 uiv = ix; 191 // CHECK: call{{.*}} void @__atomic_load(i64 noundef 8, 192 // CHECK: store i64 193 #pragma omp atomic read 194 lv = cix; 195 // CHECK: load atomic float, ptr {{.*}} monotonic, align 4 196 // CHECK: store i64 197 #pragma omp atomic read 198 ulv = fx; 199 // CHECK: load atomic double, ptr {{.*}} monotonic, align 8 200 // CHECK: store i64 201 #pragma omp atomic read 202 llv = dx; 203 // CHECK: load atomic i128, ptr {{.*}} monotonic, align 16 204 // CHECK: store i64 205 #pragma omp atomic read 206 ullv = ldx; 207 // CHECK: call{{.*}} void @__atomic_load(i64 noundef 8, 208 // CHECK: store float 209 #pragma omp atomic read 210 fv = cix; 211 // CHECK: load atomic i16, ptr {{.*}} monotonic, align 2 212 // CHECK: store double 213 #pragma omp atomic read 214 dv = sx; 215 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 216 // CHECK: store x86_fp80 217 #pragma omp atomic read 218 ldv = bx; 219 // CHECK: load atomic i8, ptr {{.*}} monotonic, align 1 220 // CHECK: store i32 221 // CHECK: store i32 222 #pragma omp atomic read 223 civ = bx; 224 // CHECK: load atomic i16, ptr {{.*}} monotonic, align 2 225 // CHECK: store float 226 // CHECK: store float 227 #pragma omp atomic read 228 cfv = usx; 229 // CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 230 // CHECK: store double 231 // CHECK: store double 232 #pragma omp atomic read 233 cdv = llx; 234 // CHECK: [[I128VAL:%.+]] = load atomic i128, ptr @{{.+}} monotonic, align 16 235 // CHECK: store i128 [[I128VAL]], ptr [[LDTEMP:%.+]] 236 // CHECK: [[LD:%.+]] = load <4 x i32>, ptr [[LDTEMP]] 237 // CHECK: extractelement <4 x i32> [[LD]] 238 // CHECK: store i8 239 #pragma omp atomic read 240 bv = int4x[0]; 241 // CHECK: [[LD:%.+]] = load atomic i32, ptr getelementptr (i8, ptr @{{.+}}, i64 4) monotonic, align 4 242 // CHECK: store i32 [[LD]], ptr [[LDTEMP:%.+]] 243 // CHECK: [[LD:%.+]] = load i32, ptr [[LDTEMP]] 244 // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 1 245 // CHECK: ashr i32 [[SHL]], 1 246 // CHECK: store x86_fp80 247 #pragma omp atomic read 248 ldv = bfx.a; 249 // CHECK: call void @__atomic_load(i64 noundef 4, ptr noundef getelementptr (i8, ptr @bfx_packed, i64 4), ptr noundef [[LDTEMP:%.+]], i32 noundef 0) 250 // CHECK: [[LD:%.+]] = load i32, ptr [[LDTEMP]] 251 // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 1 252 // CHECK: ashr i32 [[SHL]], 1 253 // CHECK: store x86_fp80 254 #pragma omp atomic read 255 ldv = bfx_packed.a; 256 // CHECK: [[LD:%.+]] = load atomic i32, ptr @bfx2 monotonic, align 4 257 // CHECK: store i32 [[LD]], ptr [[LDTEMP:%.+]] 258 // CHECK: [[LD:%.+]] = load i32, ptr [[LDTEMP]] 259 // CHECK: ashr i32 [[LD]], 31 260 // CHECK: store x86_fp80 261 #pragma omp atomic read 262 ldv = bfx2.a; 263 // CHECK: [[LD:%.+]] = load atomic i8, ptr getelementptr (i8, ptr @bfx2_packed, i64 3) monotonic, align 1 264 // CHECK: store i8 [[LD]], ptr [[LDTEMP:%.+]] 265 // CHECK: [[LD:%.+]] = load i8, ptr [[LDTEMP]] 266 // CHECK: ashr i8 [[LD]], 7 267 // CHECK: store x86_fp80 268 #pragma omp atomic read 269 ldv = bfx2_packed.a; 270 // CHECK: [[LD:%.+]] = load atomic i32, ptr @bfx3 monotonic, align 4 271 // CHECK: store i32 [[LD]], ptr [[LDTEMP:%.+]] 272 // CHECK: [[LD:%.+]] = load i32, ptr [[LDTEMP]] 273 // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 7 274 // CHECK: ashr i32 [[SHL]], 18 275 // CHECK: store x86_fp80 276 #pragma omp atomic read 277 ldv = bfx3.a; 278 // CHECK: call void @__atomic_load(i64 noundef 3, ptr noundef getelementptr (i8, ptr @bfx3_packed, i64 1), ptr noundef [[LDTEMP:%.+]], i32 noundef 0) 279 // CHECK: [[LD:%.+]] = load i24, ptr [[LDTEMP]] 280 // CHECK: [[SHL:%.+]] = shl i24 [[LD]], 7 281 // CHECK: [[ASHR:%.+]] = ashr i24 [[SHL]], 10 282 // CHECK: sext i24 [[ASHR]] to i32 283 // CHECK: store x86_fp80 284 #pragma omp atomic read 285 ldv = bfx3_packed.a; 286 // CHECK: [[LD:%.+]] = load atomic i64, ptr @bfx4 monotonic, align 8 287 // CHECK: store i64 [[LD]], ptr [[LDTEMP:%.+]] 288 // CHECK: [[LD:%.+]] = load i64, ptr [[LDTEMP]] 289 // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 47 290 // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 63 291 // CHECK: trunc i64 [[ASHR]] to i32 292 // CHECK: store x86_fp80 293 #pragma omp atomic read 294 ldv = bfx4.a; 295 // CHECK: [[LD:%.+]] = load atomic i8, ptr getelementptr inbounds nuw (%struct.BitFields4_packed, ptr @bfx4_packed, i32 0, i32 1) monotonic, align 1 296 // CHECK: store i8 [[LD]], ptr [[LDTEMP:%.+]] 297 // CHECK: [[LD:%.+]] = load i8, ptr [[LDTEMP]] 298 // CHECK: [[SHL:%.+]] = shl i8 [[LD]], 7 299 // CHECK: [[ASHR:%.+]] = ashr i8 [[SHL]], 7 300 // CHECK: sext i8 [[ASHR]] to i32 301 // CHECK: store x86_fp80 302 #pragma omp atomic relaxed read 303 ldv = bfx4_packed.a; 304 // CHECK: [[LD:%.+]] = load atomic i64, ptr @bfx4 monotonic, align 8 305 // CHECK: store i64 [[LD]], ptr [[LDTEMP:%.+]] 306 // CHECK: [[LD:%.+]] = load i64, ptr [[LDTEMP]] 307 // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 40 308 // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 57 309 // CHECK: store x86_fp80 310 #pragma omp atomic read relaxed 311 ldv = bfx4.b; 312 // CHECK: [[LD:%.+]] = load atomic i8, ptr getelementptr inbounds nuw (%struct.BitFields4_packed, ptr @bfx4_packed, i32 0, i32 1) acquire, align 1 313 // CHECK: store i8 [[LD]], ptr [[LDTEMP:%.+]] 314 // CHECK: [[LD:%.+]] = load i8, ptr [[LDTEMP]] 315 // CHECK: [[ASHR:%.+]] = ashr i8 [[LD]], 1 316 // CHECK: sext i8 [[ASHR]] to i64 317 // CHECK: call{{.*}} @__kmpc_flush( 318 // CHECK: store x86_fp80 319 #pragma omp atomic read acquire 320 ldv = bfx4_packed.b; 321 // CHECK: [[LD:%.+]] = load atomic i64, ptr @{{.+}} monotonic, align 8 322 // CHECK: store i64 [[LD]], ptr [[LDTEMP:%.+]] 323 // CHECK: [[LD:%.+]] = load <2 x float>, ptr [[LDTEMP]] 324 // CHECK: extractelement <2 x float> [[LD]] 325 // CHECK: store i64 326 #pragma omp atomic read 327 ulv = float2x.x; 328 // CHECK: call{{.*}} i{{[0-9]+}} @llvm.read_register 329 // CHECK: call{{.*}} @__kmpc_flush( 330 // CHECK: store double 331 #pragma omp atomic read seq_cst 332 dv = rix; 333 return 0; 334 } 335 336 #endif 337