1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand %s | FileCheck %s
4 define { i16, i1 } @cmpxchg_flat_agent_i16(ptr %ptr, i16 %val, i16 %swap) {
5 ; CHECK-LABEL: define { i16, i1 } @cmpxchg_flat_agent_i16(
6 ; CHECK-SAME: ptr [[PTR:%.*]], i16 [[VAL:%.*]], i16 [[SWAP:%.*]]) {
7 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR]], i64 -4)
8 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
9 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
10 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
11 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
12 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
13 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
14 ; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[SWAP]] to i32
15 ; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
16 ; CHECK-NEXT: [[TMP5:%.*]] = zext i16 [[VAL]] to i32
17 ; CHECK-NEXT: [[TMP6:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
18 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
19 ; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], [[INV_MASK]]
20 ; CHECK-NEXT: br label %[[PARTWORD_CMPXCHG_LOOP:.*]]
21 ; CHECK: [[PARTWORD_CMPXCHG_LOOP]]:
22 ; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[TMP0:%.*]] ], [ [[TMP15:%.*]], %[[PARTWORD_CMPXCHG_FAILURE:.*]] ]
23 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP4]]
24 ; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP9]], [[TMP6]]
25 ; CHECK-NEXT: [[TMP12:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[TMP11]], i32 [[TMP10]] syncscope("agent") monotonic seq_cst, align 4
26 ; CHECK-NEXT: [[TMP13:%.*]] = extractvalue { i32, i1 } [[TMP12]], 0
27 ; CHECK-NEXT: [[TMP14:%.*]] = extractvalue { i32, i1 } [[TMP12]], 1
28 ; CHECK-NEXT: br i1 [[TMP14]], label %[[PARTWORD_CMPXCHG_END:.*]], label %[[PARTWORD_CMPXCHG_FAILURE]]
29 ; CHECK: [[PARTWORD_CMPXCHG_FAILURE]]:
30 ; CHECK-NEXT: [[TMP15]] = and i32 [[TMP13]], [[INV_MASK]]
31 ; CHECK-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP9]], [[TMP15]]
32 ; CHECK-NEXT: br i1 [[TMP16]], label %[[PARTWORD_CMPXCHG_LOOP]], label %[[PARTWORD_CMPXCHG_END]]
33 ; CHECK: [[PARTWORD_CMPXCHG_END]]:
34 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP13]], [[SHIFTAMT]]
35 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
36 ; CHECK-NEXT: [[TMP17:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
37 ; CHECK-NEXT: [[TMP18:%.*]] = insertvalue { i16, i1 } [[TMP17]], i1 [[TMP14]], 1
38 ; CHECK-NEXT: ret { i16, i1 } [[TMP18]]
40 %result = cmpxchg ptr %ptr, i16 %val, i16 %swap syncscope("agent") monotonic seq_cst
41 ret { i16, i1 } %result
44 define { i16, i1 } @cmpxchg_flat_agent_i16_align4(ptr %ptr, i16 %val, i16 %swap) {
45 ; CHECK-LABEL: define { i16, i1 } @cmpxchg_flat_agent_i16_align4(
46 ; CHECK-SAME: ptr [[PTR:%.*]], i16 [[VAL:%.*]], i16 [[SWAP:%.*]]) {
47 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[SWAP]] to i32
48 ; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[VAL]] to i32
49 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[PTR]], align 4
50 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], -65536
51 ; CHECK-NEXT: br label %[[PARTWORD_CMPXCHG_LOOP:.*]]
52 ; CHECK: [[PARTWORD_CMPXCHG_LOOP]]:
53 ; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[TMP11:%.*]], %[[PARTWORD_CMPXCHG_FAILURE:.*]] ]
54 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP1]]
55 ; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP5]], [[TMP2]]
56 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP7]], i32 [[TMP6]] syncscope("agent") monotonic seq_cst, align 4
57 ; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
58 ; CHECK-NEXT: [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
59 ; CHECK-NEXT: br i1 [[TMP10]], label %[[PARTWORD_CMPXCHG_END:.*]], label %[[PARTWORD_CMPXCHG_FAILURE]]
60 ; CHECK: [[PARTWORD_CMPXCHG_FAILURE]]:
61 ; CHECK-NEXT: [[TMP11]] = and i32 [[TMP9]], -65536
62 ; CHECK-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP5]], [[TMP11]]
63 ; CHECK-NEXT: br i1 [[TMP12]], label %[[PARTWORD_CMPXCHG_LOOP]], label %[[PARTWORD_CMPXCHG_END]]
64 ; CHECK: [[PARTWORD_CMPXCHG_END]]:
65 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP9]] to i16
66 ; CHECK-NEXT: [[TMP13:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
67 ; CHECK-NEXT: [[TMP14:%.*]] = insertvalue { i16, i1 } [[TMP13]], i1 [[TMP10]], 1
68 ; CHECK-NEXT: ret { i16, i1 } [[TMP14]]
70 %result = cmpxchg ptr %ptr, i16 %val, i16 %swap syncscope("agent") monotonic seq_cst, align 4
71 ret { i16, i1 } %result
74 define { i32, i1 } @cmpxchg_flat_agent_i32(ptr %ptr, i32 %val, i32 %swap) {
75 ; CHECK-LABEL: define { i32, i1 } @cmpxchg_flat_agent_i32(
76 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[VAL:%.*]], i32 [[SWAP:%.*]]) {
77 ; CHECK-NEXT: [[RESULT:%.*]] = cmpxchg ptr [[PTR]], i32 [[VAL]], i32 [[SWAP]] syncscope("agent") monotonic seq_cst, align 4
78 ; CHECK-NEXT: ret { i32, i1 } [[RESULT]]
80 %result = cmpxchg ptr %ptr, i32 %val, i32 %swap syncscope("agent") monotonic seq_cst
81 ret { i32, i1 } %result
84 define { i64, i1 } @cmpxchg_flat_agent_i64(ptr %ptr, i64 %val, i64 %swap) {
85 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64(
86 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
87 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
88 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
89 ; CHECK: [[ATOMICRMW_PRIVATE]]:
90 ; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
91 ; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr addrspace(5) [[TMP3]], align 8
92 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], [[VAL]]
93 ; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[SWAP]], i64 [[TMP4]]
94 ; CHECK-NEXT: store i64 [[TMP6]], ptr addrspace(5) [[TMP3]], align 8
95 ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP4]], 0
96 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i64, i1 } [[TMP7]], i1 [[TMP5]], 1
97 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
98 ; CHECK: [[ATOMICRMW_GLOBAL]]:
99 ; CHECK-NEXT: [[TMP9:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0:![0-9]+]]
100 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
101 ; CHECK: [[ATOMICRMW_PHI]]:
102 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP8]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP9]], %[[ATOMICRMW_GLOBAL]] ]
103 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
104 ; CHECK: [[ATOMICRMW_END]]:
105 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
107 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst
108 ret { i64, i1 } %result
111 define { i64, i1 } @cmpxchg_flat_agent_i64_volatile(ptr %ptr, i64 %val, i64 %swap) {
112 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64_volatile(
113 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
114 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
115 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
116 ; CHECK: [[ATOMICRMW_PRIVATE]]:
117 ; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
118 ; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr addrspace(5) [[TMP3]], align 8
119 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], [[VAL]]
120 ; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[SWAP]], i64 [[TMP4]]
121 ; CHECK-NEXT: store i64 [[TMP6]], ptr addrspace(5) [[TMP3]], align 8
122 ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP4]], 0
123 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i64, i1 } [[TMP7]], i1 [[TMP5]], 1
124 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
125 ; CHECK: [[ATOMICRMW_GLOBAL]]:
126 ; CHECK-NEXT: [[TMP9:%.*]] = cmpxchg volatile ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0]]
127 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
128 ; CHECK: [[ATOMICRMW_PHI]]:
129 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP8]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP9]], %[[ATOMICRMW_GLOBAL]] ]
130 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
131 ; CHECK: [[ATOMICRMW_END]]:
132 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
134 %result = cmpxchg volatile ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst
135 ret { i64, i1 } %result
138 define { i16, i1 } @cmpxchg_flat_agent_i16__noprivate(ptr %ptr, i16 %val, i16 %swap) {
139 ; CHECK-LABEL: define { i16, i1 } @cmpxchg_flat_agent_i16__noprivate(
140 ; CHECK-SAME: ptr [[PTR:%.*]], i16 [[VAL:%.*]], i16 [[SWAP:%.*]]) {
141 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR]], i64 -4)
142 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
143 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
144 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
145 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
146 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
147 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
148 ; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[SWAP]] to i32
149 ; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
150 ; CHECK-NEXT: [[TMP5:%.*]] = zext i16 [[VAL]] to i32
151 ; CHECK-NEXT: [[TMP6:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
152 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
153 ; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], [[INV_MASK]]
154 ; CHECK-NEXT: br label %[[PARTWORD_CMPXCHG_LOOP:.*]]
155 ; CHECK: [[PARTWORD_CMPXCHG_LOOP]]:
156 ; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[TMP0:%.*]] ], [ [[TMP15:%.*]], %[[PARTWORD_CMPXCHG_FAILURE:.*]] ]
157 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP4]]
158 ; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP9]], [[TMP6]]
159 ; CHECK-NEXT: [[TMP12:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[TMP11]], i32 [[TMP10]] syncscope("agent") monotonic seq_cst, align 4
160 ; CHECK-NEXT: [[TMP13:%.*]] = extractvalue { i32, i1 } [[TMP12]], 0
161 ; CHECK-NEXT: [[TMP14:%.*]] = extractvalue { i32, i1 } [[TMP12]], 1
162 ; CHECK-NEXT: br i1 [[TMP14]], label %[[PARTWORD_CMPXCHG_END:.*]], label %[[PARTWORD_CMPXCHG_FAILURE]]
163 ; CHECK: [[PARTWORD_CMPXCHG_FAILURE]]:
164 ; CHECK-NEXT: [[TMP15]] = and i32 [[TMP13]], [[INV_MASK]]
165 ; CHECK-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP9]], [[TMP15]]
166 ; CHECK-NEXT: br i1 [[TMP16]], label %[[PARTWORD_CMPXCHG_LOOP]], label %[[PARTWORD_CMPXCHG_END]]
167 ; CHECK: [[PARTWORD_CMPXCHG_END]]:
168 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP13]], [[SHIFTAMT]]
169 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
170 ; CHECK-NEXT: [[TMP17:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
171 ; CHECK-NEXT: [[TMP18:%.*]] = insertvalue { i16, i1 } [[TMP17]], i1 [[TMP14]], 1
172 ; CHECK-NEXT: ret { i16, i1 } [[TMP18]]
174 %result = cmpxchg ptr %ptr, i16 %val, i16 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !0
175 ret { i16, i1 } %result
178 define { i32, i1 } @cmpxchg_flat_agent_i32__noprivate(ptr %ptr, i32 %val, i32 %swap) {
179 ; CHECK-LABEL: define { i32, i1 } @cmpxchg_flat_agent_i32__noprivate(
180 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[VAL:%.*]], i32 [[SWAP:%.*]]) {
181 ; CHECK-NEXT: [[RESULT:%.*]] = cmpxchg ptr [[PTR]], i32 [[VAL]], i32 [[SWAP]] syncscope("agent") monotonic seq_cst, align 4, !noalias.addrspace [[META0]]
182 ; CHECK-NEXT: ret { i32, i1 } [[RESULT]]
184 %result = cmpxchg ptr %ptr, i32 %val, i32 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !0
185 ret { i32, i1 } %result
188 define { i64, i1 } @cmpxchg_flat_agent_i64__noprivate(ptr %ptr, i64 %val, i64 %swap) {
189 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64__noprivate(
190 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
191 ; CHECK-NEXT: [[RESULT:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0]]
192 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
194 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !0
195 ret { i64, i1 } %result
198 define { i64, i1 } @cmpxchg_flat_agent_i64__nolocal(ptr %ptr, i64 %val, i64 %swap) {
199 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64__nolocal(
200 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
201 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
202 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
203 ; CHECK: [[ATOMICRMW_PRIVATE]]:
204 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
205 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(5) [[TMP1]], align 8
206 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], [[VAL]]
207 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[SWAP]], i64 [[TMP2]]
208 ; CHECK-NEXT: store i64 [[TMP4]], ptr addrspace(5) [[TMP1]], align 8
209 ; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP2]], 0
210 ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i64, i1 } [[TMP5]], i1 [[TMP3]], 1
211 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
212 ; CHECK: [[ATOMICRMW_GLOBAL]]:
213 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0]]
214 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
215 ; CHECK: [[ATOMICRMW_PHI]]:
216 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP6]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP7]], %[[ATOMICRMW_GLOBAL]] ]
217 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
218 ; CHECK: [[ATOMICRMW_END]]:
219 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
221 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !1
222 ret { i64, i1 } %result
225 define { i64, i1 } @cmpxchg_flat_agent_i64_mmra(ptr %ptr, i64 %val, i64 %swap) {
226 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64_mmra(
227 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
228 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
229 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
230 ; CHECK: [[ATOMICRMW_PRIVATE]]:
231 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
232 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(5) [[TMP1]], align 8
233 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], [[VAL]]
234 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[SWAP]], i64 [[TMP2]]
235 ; CHECK-NEXT: store i64 [[TMP4]], ptr addrspace(5) [[TMP1]], align 8
236 ; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP2]], 0
237 ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i64, i1 } [[TMP5]], i1 [[TMP3]], 1
238 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
239 ; CHECK: [[ATOMICRMW_GLOBAL]]:
240 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !mmra [[META1:![0-9]+]], !noalias.addrspace [[META0]]
241 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
242 ; CHECK: [[ATOMICRMW_PHI]]:
243 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP6]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP7]], %[[ATOMICRMW_GLOBAL]] ]
244 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
245 ; CHECK: [[ATOMICRMW_END]]:
246 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
248 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !mmra !4
249 ret { i64, i1 } %result
252 define { i64, i1 } @cmpxchg_flat_agent_i64_mmra_noprivate(ptr %ptr, i64 %val, i64 %swap) {
253 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64_mmra_noprivate(
254 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
255 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
256 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
257 ; CHECK: [[ATOMICRMW_PRIVATE]]:
258 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
259 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(5) [[TMP1]], align 8
260 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], [[VAL]]
261 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[SWAP]], i64 [[TMP2]]
262 ; CHECK-NEXT: store i64 [[TMP4]], ptr addrspace(5) [[TMP1]], align 8
263 ; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP2]], 0
264 ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i64, i1 } [[TMP5]], i1 [[TMP3]], 1
265 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
266 ; CHECK: [[ATOMICRMW_GLOBAL]]:
267 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !mmra [[META1]], !noalias.addrspace [[META0]]
268 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
269 ; CHECK: [[ATOMICRMW_PHI]]:
270 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP6]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP7]], %[[ATOMICRMW_GLOBAL]] ]
271 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
272 ; CHECK: [[ATOMICRMW_END]]:
273 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
275 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !1, !mmra !4
276 ret { i64, i1 } %result
279 ; may alias private, wrapped range
280 define { i64, i1 } @cmpxchg_flat_agent_i64__noalias_addrspace_edge_case0(ptr %ptr, i64 %val, i64 %swap) {
281 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64__noalias_addrspace_edge_case0(
282 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
283 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
284 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
285 ; CHECK: [[ATOMICRMW_PRIVATE]]:
286 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
287 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(5) [[TMP1]], align 8
288 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], [[VAL]]
289 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[SWAP]], i64 [[TMP2]]
290 ; CHECK-NEXT: store i64 [[TMP4]], ptr addrspace(5) [[TMP1]], align 8
291 ; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP2]], 0
292 ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i64, i1 } [[TMP5]], i1 [[TMP3]], 1
293 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
294 ; CHECK: [[ATOMICRMW_GLOBAL]]:
295 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0]]
296 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
297 ; CHECK: [[ATOMICRMW_PHI]]:
298 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP6]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP7]], %[[ATOMICRMW_GLOBAL]] ]
299 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
300 ; CHECK: [[ATOMICRMW_END]]:
301 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
303 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !6
304 ret { i64, i1 } %result
307 ; covers private case, but private isn't the low value.
308 define { i64, i1 } @cmpxchg_flat_agent_i64__no_2_6(ptr %ptr, i64 %val, i64 %swap) {
309 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64__no_2_6(
310 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
311 ; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
312 ; CHECK-NEXT: br i1 [[IS_PRIVATE]], label %[[ATOMICRMW_PRIVATE:.*]], label %[[ATOMICRMW_GLOBAL:.*]]
313 ; CHECK: [[ATOMICRMW_PRIVATE]]:
314 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
315 ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(5) [[TMP1]], align 8
316 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], [[VAL]]
317 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[SWAP]], i64 [[TMP2]]
318 ; CHECK-NEXT: store i64 [[TMP4]], ptr addrspace(5) [[TMP1]], align 8
319 ; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i64, i1 } poison, i64 [[TMP2]], 0
320 ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i64, i1 } [[TMP5]], i1 [[TMP3]], 1
321 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI:.*]]
322 ; CHECK: [[ATOMICRMW_GLOBAL]]:
323 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META0]]
324 ; CHECK-NEXT: br label %[[ATOMICRMW_PHI]]
325 ; CHECK: [[ATOMICRMW_PHI]]:
326 ; CHECK-NEXT: [[RESULT:%.*]] = phi { i64, i1 } [ [[TMP6]], %[[ATOMICRMW_PRIVATE]] ], [ [[TMP7]], %[[ATOMICRMW_GLOBAL]] ]
327 ; CHECK-NEXT: br label %[[ATOMICRMW_END:.*]]
328 ; CHECK: [[ATOMICRMW_END]]:
329 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
331 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !7
332 ret { i64, i1 } %result
335 define { i64, i1 } @cmpxchg_flat_agent_i64__no_2_3_5(ptr %ptr, i64 %val, i64 %swap) {
336 ; CHECK-LABEL: define { i64, i1 } @cmpxchg_flat_agent_i64__no_2_3_5(
337 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[VAL:%.*]], i64 [[SWAP:%.*]]) {
338 ; CHECK-NEXT: [[RESULT:%.*]] = cmpxchg ptr [[PTR]], i64 [[VAL]], i64 [[SWAP]] syncscope("agent") monotonic seq_cst, align 8, !noalias.addrspace [[META4:![0-9]+]]
339 ; CHECK-NEXT: ret { i64, i1 } [[RESULT]]
341 %result = cmpxchg ptr %ptr, i64 %val, i64 %swap syncscope("agent") monotonic seq_cst, !noalias.addrspace !8
342 ret { i64, i1 } %result
347 !2 = !{!"foo", !"bar"}
348 !3 = !{!"bux", !"baz"}
353 !8 = !{i32 2, i32 4, i32 5, i32 6}
356 ; CHECK: [[META0]] = !{i32 5, i32 6}
357 ; CHECK: [[META1]] = !{[[META2:![0-9]+]], [[META3:![0-9]+]]}
358 ; CHECK: [[META2]] = !{!"foo", !"bar"}
359 ; CHECK: [[META3]] = !{!"bux", !"baz"}
360 ; CHECK: [[META4]] = !{i32 2, i32 4, i32 5, i32 6}