1 // RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
2 // RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu -target-cpu core2 | FileCheck %s --check-prefix=CORE2
3 // RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i386-linux-gnu -target-cpu i386 | FileCheck %s --check-prefix=I386
4 // RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i386-linux-gnu -target-cpu i486 | FileCheck %s --check-prefix=I486
5 // Check the atomic code generation for cpu targets w/wo cx, cx8 and cx16 support.
6 
7 struct alignas(4) AM4 {
8   short f1, f2;
9 };
10 AM4 m4;
11 AM4 load4() {
12   AM4 am;
13   // CHECK-LABEL: @_Z5load4v
14   // CHECK: load atomic i32, {{.*}} monotonic
15   // CORE2-LABEL: @_Z5load4v
16   // CORE2: load atomic i32, {{.*}} monotonic
17   // I386-LABEL: @_Z5load4v
18   // I386: call i32 @__atomic_load_4
19   // I486-LABEL: @_Z5load4v
20   // I486: load atomic i32, {{.*}} monotonic
21   __atomic_load(&m4, &am, 0);
22   return am;
23 }
24 
25 AM4 s4;
26 void store4() {
27   // CHECK-LABEL: @_Z6store4v
28   // CHECK: store atomic i32 {{.*}} monotonic
29   // CORE2-LABEL: @_Z6store4v
30   // CORE2: store atomic i32 {{.*}} monotonic
31   // I386-LABEL: @_Z6store4v
32   // I386: call void @__atomic_store_4
33   // I486-LABEL: @_Z6store4v
34   // I486: store atomic i32 {{.*}} monotonic
35   __atomic_store(&m4, &s4, 0);
36 }
37 
38 bool cmpxchg4() {
39   AM4 am;
40   // CHECK-LABEL: @_Z8cmpxchg4v
41   // CHECK: cmpxchg i32* {{.*}} monotonic
42   // CORE2-LABEL: @_Z8cmpxchg4v
43   // CORE2: cmpxchg i32* {{.*}} monotonic
44   // I386-LABEL: @_Z8cmpxchg4v
45   // I386: call zeroext i1 @__atomic_compare_exchange_4
46   // I486-LABEL: @_Z8cmpxchg4v
47   // I486: cmpxchg i32* {{.*}} monotonic
48   return __atomic_compare_exchange(&m4, &s4, &am, 0, 0, 0);
49 }
50 
51 struct alignas(8) AM8 {
52   int f1, f2;
53 };
54 AM8 m8;
55 AM8 load8() {
56   AM8 am;
57   // CHECK-LABEL: @_Z5load8v
58   // CHECK: load atomic i64, {{.*}} monotonic
59   // CORE2-LABEL: @_Z5load8v
60   // CORE2: load atomic i64, {{.*}} monotonic
61   // I386-LABEL: @_Z5load8v
62   // I386: call i64 @__atomic_load_8
63   // I486-LABEL: @_Z5load8v
64   // I486: call i64 @__atomic_load_8
65   __atomic_load(&m8, &am, 0);
66   return am;
67 }
68 
69 AM8 s8;
70 void store8() {
71   // CHECK-LABEL: @_Z6store8v
72   // CHECK: store atomic i64 {{.*}} monotonic
73   // CORE2-LABEL: @_Z6store8v
74   // CORE2: store atomic i64 {{.*}} monotonic
75   // I386-LABEL: @_Z6store8v
76   // I386: call void @__atomic_store_8
77   // I486-LABEL: @_Z6store8v
78   // I486: call void @__atomic_store_8
79   __atomic_store(&m8, &s8, 0);
80 }
81 
82 bool cmpxchg8() {
83   AM8 am;
84   // CHECK-LABEL: @_Z8cmpxchg8v
85   // CHECK: cmpxchg i64* {{.*}} monotonic
86   // CORE2-LABEL: @_Z8cmpxchg8v
87   // CORE2: cmpxchg i64* {{.*}} monotonic
88   // I386-LABEL: @_Z8cmpxchg8v
89   // I386: call zeroext i1 @__atomic_compare_exchange_8
90   // I486-LABEL: @_Z8cmpxchg8v
91   // I486: call zeroext i1 @__atomic_compare_exchange_8
92   return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
93 }
94 
95 struct alignas(16) AM16 {
96   long f1, f2;
97 };
98 
99 AM16 m16;
100 AM16 load16() {
101   AM16 am;
102   // CHECK-LABEL: @_Z6load16v
103   // CHECK: call void @__atomic_load
104   // CORE2-LABEL: @_Z6load16v
105   // CORE2: load atomic i128, {{.*}} monotonic
106   __atomic_load(&m16, &am, 0);
107   return am;
108 }
109 
110 AM16 s16;
111 void store16() {
112   // CHECK-LABEL: @_Z7store16v
113   // CHECK: call void @__atomic_store
114   // CORE2-LABEL: @_Z7store16v
115   // CORE2: store atomic i128 {{.*}} monotonic
116   __atomic_store(&m16, &s16, 0);
117 }
118 
119 bool cmpxchg16() {
120   AM16 am;
121   // CHECK-LABEL: @_Z9cmpxchg16v
122   // CHECK: call zeroext i1 @__atomic_compare_exchange
123   // CORE2-LABEL: @_Z9cmpxchg16v
124   // CORE2: cmpxchg i128* {{.*}} monotonic
125   return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
126 }
127