1 // RUN: %clang_cc1 -triple i386-pc-win32 -fms-extensions -emit-llvm -fms-volatile -o - < %s | FileCheck %s
2 struct foo {
3   volatile int x;
4 };
5 struct bar {
6   int x;
7 };
8 typedef _Complex float __declspec(align(8)) baz;
9 
10 #pragma pack(push)
11 #pragma pack(1)
12 struct qux {
13    volatile int f;
14 };
15 #pragma pack(pop)
16 
test1(struct foo * p,struct foo * q)17 void test1(struct foo *p, struct foo *q) {
18   *p = *q;
19   // CHECK-LABEL: @test1
20   // CHECK: load atomic volatile {{.*}} acquire
21   // CHECK: store atomic volatile {{.*}}, {{.*}} release
22 }
test2(volatile int * p,volatile int * q)23 void test2(volatile int *p, volatile int *q) {
24   *p = *q;
25   // CHECK-LABEL: @test2
26   // CHECK: load atomic volatile {{.*}} acquire
27   // CHECK: store atomic volatile {{.*}}, {{.*}} release
28 }
test3(struct foo * p,struct foo * q)29 void test3(struct foo *p, struct foo *q) {
30   p->x = q->x;
31   // CHECK-LABEL: @test3
32   // CHECK: load atomic volatile {{.*}} acquire
33   // CHECK: store atomic volatile {{.*}}, {{.*}} release
34 }
test4(volatile struct foo * p,volatile struct foo * q)35 void test4(volatile struct foo *p, volatile struct foo *q) {
36   p->x = q->x;
37   // CHECK-LABEL: @test4
38   // CHECK: load atomic volatile {{.*}} acquire
39   // CHECK: store atomic volatile {{.*}}, {{.*}} release
40 }
test5(volatile struct foo * p,volatile struct foo * q)41 void test5(volatile struct foo *p, volatile struct foo *q) {
42   *p = *q;
43   // CHECK-LABEL: @test5
44   // CHECK: load atomic volatile {{.*}} acquire
45   // CHECK: store atomic volatile {{.*}}, {{.*}} release
46 }
test6(struct bar * p,struct bar * q)47 void test6(struct bar *p, struct bar *q) {
48   *p = *q;
49   // CHECK-LABEL: @test6
50   // CHECK-NOT: load atomic volatile {{.*}}
51   // CHECK-NOT: store atomic volatile {{.*}}, {{.*}}
52 }
test7(volatile struct bar * p,volatile struct bar * q)53 void test7(volatile struct bar *p, volatile struct bar *q) {
54   *p = *q;
55   // CHECK-LABEL: @test7
56   // CHECK: load atomic volatile {{.*}} acquire
57   // CHECK: store atomic volatile {{.*}}, {{.*}} release
58 }
test8(volatile double * p,volatile double * q)59 void test8(volatile double *p, volatile double *q) {
60   *p = *q;
61   // CHECK-LABEL: @test8
62   // CHECK: load volatile {{.*}}
63   // CHECK: store volatile {{.*}}, {{.*}}
64 }
test9(volatile baz * p,baz * q)65 void test9(volatile baz *p, baz *q) {
66   *p = *q;
67   // CHECK-LABEL: @test9
68   // CHECK: store volatile {{.*}}, {{.*}}
69   // CHECK: store volatile {{.*}}, {{.*}}
70 }
test10(volatile long long * p,volatile long long * q)71 void test10(volatile long long *p, volatile long long *q) {
72   *p = *q;
73   // CHECK-LABEL: @test10
74   // CHECK: load volatile {{.*}}
75   // CHECK: store volatile {{.*}}, {{.*}}
76 }
test11(volatile float * p,volatile float * q)77 void test11(volatile float *p, volatile float *q) {
78   *p = *q;
79   // CHECK-LABEL: @test11
80   // CHECK: load atomic volatile {{.*}} acquire
81   // CHECK: store atomic volatile {{.*}}, {{.*}} release
82 }
test12(struct qux * p)83 int test12(struct qux *p) {
84   return p->f;
85   // CHECK-LABEL: @test12
86   // CHECK: load volatile {{.*}}
87 }
88