xref: /llvm-project/clang/test/CodeGen/atomic-test-and-set.c (revision c4ef805b0bda16f734276086b0984583c2e21db6)
1*c4ef805bSOliver Stannard // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2*c4ef805bSOliver Stannard // RUN: %clang_cc1 %s -emit-llvm -o - -triple=aarch64-none-elf | FileCheck %s
3*c4ef805bSOliver Stannard // REQUIRES: aarch64-registered-target
4*c4ef805bSOliver Stannard 
5*c4ef805bSOliver Stannard #include <stdatomic.h>
6*c4ef805bSOliver Stannard 
7*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_relaxed(
8*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
9*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
10*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
11*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
12*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
13*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] monotonic, align 1
14*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
15*c4ef805bSOliver Stannard //
16*c4ef805bSOliver Stannard void clear_relaxed(char *ptr) {
17*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_relaxed);
18*c4ef805bSOliver Stannard }
19*c4ef805bSOliver Stannard 
20*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_seq_cst(
21*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
22*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
23*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
24*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
25*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
26*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] seq_cst, align 1
27*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
28*c4ef805bSOliver Stannard //
29*c4ef805bSOliver Stannard void clear_seq_cst(char *ptr) {
30*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_seq_cst);
31*c4ef805bSOliver Stannard }
32*c4ef805bSOliver Stannard 
33*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_release(
34*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
35*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
36*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
37*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
38*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
39*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] release, align 1
40*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
41*c4ef805bSOliver Stannard //
42*c4ef805bSOliver Stannard void clear_release(char *ptr) {
43*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_release);
44*c4ef805bSOliver Stannard }
45*c4ef805bSOliver Stannard 
46*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_dynamic(
47*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[ORDER:%.*]]) #[[ATTR0]] {
48*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
49*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
50*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ORDER_ADDR:%.*]] = alloca i32, align 4
51*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
52*c4ef805bSOliver Stannard // CHECK-NEXT:    store i32 [[ORDER]], ptr [[ORDER_ADDR]], align 4
53*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
54*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ORDER_ADDR]], align 4
55*c4ef805bSOliver Stannard // CHECK-NEXT:    switch i32 [[TMP1]], label %[[MONOTONIC:.*]] [
56*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 3, label %[[RELEASE:.*]]
57*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 5, label %[[SEQCST:.*]]
58*c4ef805bSOliver Stannard // CHECK-NEXT:    ]
59*c4ef805bSOliver Stannard // CHECK:       [[MONOTONIC]]:
60*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] monotonic, align 1
61*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE:.*]]
62*c4ef805bSOliver Stannard // CHECK:       [[RELEASE]]:
63*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] release, align 1
64*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
65*c4ef805bSOliver Stannard // CHECK:       [[SEQCST]]:
66*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] seq_cst, align 1
67*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
68*c4ef805bSOliver Stannard // CHECK:       [[ATOMIC_CONTINUE]]:
69*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
70*c4ef805bSOliver Stannard //
71*c4ef805bSOliver Stannard void clear_dynamic(char *ptr, int order) {
72*c4ef805bSOliver Stannard   __atomic_clear(ptr, order);
73*c4ef805bSOliver Stannard }
74*c4ef805bSOliver Stannard 
75*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_relaxed(
76*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
77*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
78*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
79*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
80*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
81*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
82*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1
83*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
84*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
85*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
86*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
87*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
88*c4ef805bSOliver Stannard //
89*c4ef805bSOliver Stannard void test_and_set_relaxed(char *ptr) {
90*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_relaxed);
91*c4ef805bSOliver Stannard }
92*c4ef805bSOliver Stannard 
93*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_consume(
94*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
95*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
96*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
97*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
98*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
99*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
100*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1
101*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
102*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
103*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
104*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
105*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
106*c4ef805bSOliver Stannard //
107*c4ef805bSOliver Stannard void test_and_set_consume(char *ptr) {
108*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_consume);
109*c4ef805bSOliver Stannard }
110*c4ef805bSOliver Stannard 
111*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_acquire(
112*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
113*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
114*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
115*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
116*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
117*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
118*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1
119*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
120*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
121*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
122*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
123*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
124*c4ef805bSOliver Stannard //
125*c4ef805bSOliver Stannard void test_and_set_acquire(char *ptr) {
126*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_acquire);
127*c4ef805bSOliver Stannard }
128*c4ef805bSOliver Stannard 
129*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_release(
130*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
131*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
132*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
133*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
134*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
135*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
136*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 release, align 1
137*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
138*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
139*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
140*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
141*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
142*c4ef805bSOliver Stannard //
143*c4ef805bSOliver Stannard void test_and_set_release(char *ptr) {
144*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_release);
145*c4ef805bSOliver Stannard }
146*c4ef805bSOliver Stannard 
147*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_acq_rel(
148*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
149*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
150*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
151*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
152*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
153*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
154*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acq_rel, align 1
155*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
156*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
157*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
158*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
159*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
160*c4ef805bSOliver Stannard //
161*c4ef805bSOliver Stannard void test_and_set_acq_rel(char *ptr) {
162*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_acq_rel);
163*c4ef805bSOliver Stannard }
164*c4ef805bSOliver Stannard 
165*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_seq_cst(
166*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
167*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
168*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
169*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
170*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
171*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
172*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 seq_cst, align 1
173*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
174*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
175*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
176*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
177*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
178*c4ef805bSOliver Stannard //
179*c4ef805bSOliver Stannard void test_and_set_seq_cst(char *ptr) {
180*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_seq_cst);
181*c4ef805bSOliver Stannard }
182*c4ef805bSOliver Stannard 
183*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_dynamic(
184*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[ORDER:%.*]]) #[[ATTR0]] {
185*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
186*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
187*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ORDER_ADDR:%.*]] = alloca i32, align 4
188*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
189*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
190*c4ef805bSOliver Stannard // CHECK-NEXT:    store i32 [[ORDER]], ptr [[ORDER_ADDR]], align 4
191*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
192*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ORDER_ADDR]], align 4
193*c4ef805bSOliver Stannard // CHECK-NEXT:    switch i32 [[TMP1]], label %[[MONOTONIC:.*]] [
194*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 1, label %[[ACQUIRE:.*]]
195*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 2, label %[[ACQUIRE]]
196*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 3, label %[[RELEASE:.*]]
197*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 4, label %[[ACQREL:.*]]
198*c4ef805bSOliver Stannard // CHECK-NEXT:      i32 5, label %[[SEQCST:.*]]
199*c4ef805bSOliver Stannard // CHECK-NEXT:    ]
200*c4ef805bSOliver Stannard // CHECK:       [[MONOTONIC]]:
201*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1
202*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP2]], 0
203*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
204*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE:.*]]
205*c4ef805bSOliver Stannard // CHECK:       [[ACQUIRE]]:
206*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP3:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1
207*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp ne i8 [[TMP3]], 0
208*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL1]], ptr [[ATOMIC_TEMP]], align 1
209*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
210*c4ef805bSOliver Stannard // CHECK:       [[RELEASE]]:
211*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP4:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 release, align 1
212*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i8 [[TMP4]], 0
213*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL2]], ptr [[ATOMIC_TEMP]], align 1
214*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
215*c4ef805bSOliver Stannard // CHECK:       [[ACQREL]]:
216*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP5:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acq_rel, align 1
217*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp ne i8 [[TMP5]], 0
218*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL3]], ptr [[ATOMIC_TEMP]], align 1
219*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
220*c4ef805bSOliver Stannard // CHECK:       [[SEQCST]]:
221*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP6:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 seq_cst, align 1
222*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[TMP6]], 0
223*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL4]], ptr [[ATOMIC_TEMP]], align 1
224*c4ef805bSOliver Stannard // CHECK-NEXT:    br label %[[ATOMIC_CONTINUE]]
225*c4ef805bSOliver Stannard // CHECK:       [[ATOMIC_CONTINUE]]:
226*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
227*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP7]] to i1
228*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
229*c4ef805bSOliver Stannard //
230*c4ef805bSOliver Stannard void test_and_set_dynamic(char *ptr, int order) {
231*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, order);
232*c4ef805bSOliver Stannard }
233*c4ef805bSOliver Stannard 
234*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_array(
235*c4ef805bSOliver Stannard // CHECK-SAME: ) #[[ATTR0]] {
236*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
237*c4ef805bSOliver Stannard // CHECK-NEXT:    [[X:%.*]] = alloca [10 x i32], align 4
238*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
239*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[X]], i64 0, i64 0
240*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = atomicrmw volatile xchg ptr [[ARRAYDECAY]], i8 1 seq_cst, align 4
241*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP0]], 0
242*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
243*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
244*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP1]] to i1
245*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
246*c4ef805bSOliver Stannard //
247*c4ef805bSOliver Stannard void test_and_set_array() {
248*c4ef805bSOliver Stannard   volatile int x[10];
249*c4ef805bSOliver Stannard   __atomic_test_and_set(x, memory_order_seq_cst);
250*c4ef805bSOliver Stannard }
251*c4ef805bSOliver Stannard 
252*c4ef805bSOliver Stannard // These intrinsics accept any pointer type, including void and incomplete
253*c4ef805bSOliver Stannard // structs, and always access the first byte regardless of the actual type
254*c4ef805bSOliver Stannard // size.
255*c4ef805bSOliver Stannard 
256*c4ef805bSOliver Stannard struct incomplete;
257*c4ef805bSOliver Stannard 
258*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_int(
259*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
260*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
261*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
262*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
263*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
264*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] monotonic, align 4
265*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
266*c4ef805bSOliver Stannard //
267*c4ef805bSOliver Stannard void clear_int(int *ptr) {
268*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_relaxed);
269*c4ef805bSOliver Stannard }
270*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_void(
271*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
272*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
273*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
274*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
275*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
276*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] monotonic, align 1
277*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
278*c4ef805bSOliver Stannard //
279*c4ef805bSOliver Stannard void clear_void(void *ptr) {
280*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_relaxed);
281*c4ef805bSOliver Stannard }
282*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_incomplete(
283*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
284*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
285*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
286*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
287*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
288*c4ef805bSOliver Stannard // CHECK-NEXT:    store atomic i8 0, ptr [[TMP0]] monotonic, align 1
289*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
290*c4ef805bSOliver Stannard //
291*c4ef805bSOliver Stannard void clear_incomplete(struct incomplete *ptr) {
292*c4ef805bSOliver Stannard   __atomic_clear(ptr, memory_order_relaxed);
293*c4ef805bSOliver Stannard }
294*c4ef805bSOliver Stannard 
295*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_int(
296*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
297*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
298*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
299*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
300*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
301*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
302*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 4
303*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
304*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
305*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
306*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
307*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
308*c4ef805bSOliver Stannard //
309*c4ef805bSOliver Stannard void test_and_set_int(int *ptr) {
310*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_relaxed);
311*c4ef805bSOliver Stannard }
312*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_void(
313*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
314*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
315*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
316*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
317*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
318*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
319*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1
320*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
321*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
322*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
323*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
324*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
325*c4ef805bSOliver Stannard //
326*c4ef805bSOliver Stannard void test_and_set_void(void *ptr) {
327*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_relaxed);
328*c4ef805bSOliver Stannard }
329*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_incomplete(
330*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
331*c4ef805bSOliver Stannard // CHECK-NEXT:  [[ENTRY:.*:]]
332*c4ef805bSOliver Stannard // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
333*c4ef805bSOliver Stannard // CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i8, align 1
334*c4ef805bSOliver Stannard // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8
335*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8
336*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1
337*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0
338*c4ef805bSOliver Stannard // CHECK-NEXT:    store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1
339*c4ef805bSOliver Stannard // CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1
340*c4ef805bSOliver Stannard // CHECK-NEXT:    [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1
341*c4ef805bSOliver Stannard // CHECK-NEXT:    ret void
342*c4ef805bSOliver Stannard //
343*c4ef805bSOliver Stannard void test_and_set_incomplete(struct incomplete *ptr) {
344*c4ef805bSOliver Stannard   __atomic_test_and_set(ptr, memory_order_relaxed);
345*c4ef805bSOliver Stannard }
346