1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=atomic-expand %s | FileCheck %s
4 define i8 @test_atomicrmw_xchg_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
5 ; CHECK-LABEL: @test_atomicrmw_xchg_i8_global_system(
6 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
7 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
8 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
9 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
10 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
11 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
12 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
13 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
14 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
15 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
16 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
17 ; CHECK: atomicrmw.start:
18 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
19 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
20 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[VALOPERAND_SHIFTED]]
21 ; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP6]] seq_cst seq_cst, align 4
22 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
23 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP7]], 0
24 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
25 ; CHECK: atomicrmw.end:
26 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
27 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
28 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
30 %res = atomicrmw xchg ptr addrspace(1) %ptr, i8 %value seq_cst
34 define i8 @test_atomicrmw_add_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
35 ; CHECK-LABEL: @test_atomicrmw_add_i8_global_system(
36 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
37 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
38 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
39 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
40 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
41 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
42 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
43 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
44 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
45 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
46 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
47 ; CHECK: atomicrmw.start:
48 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
49 ; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[VALOPERAND_SHIFTED]]
50 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]]
51 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
52 ; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]]
53 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4
54 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
55 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
56 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
57 ; CHECK: atomicrmw.end:
58 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
59 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
60 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
62 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst
66 define i8 @test_atomicrmw_add_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) {
67 ; CHECK-LABEL: @test_atomicrmw_add_i8_global_system_align2(
68 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
69 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
70 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
71 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
72 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
73 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
74 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
75 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
76 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
77 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
78 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
79 ; CHECK: atomicrmw.start:
80 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
81 ; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[VALOPERAND_SHIFTED]]
82 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]]
83 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
84 ; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]]
85 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4
86 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
87 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
88 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
89 ; CHECK: atomicrmw.end:
90 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
91 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
92 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
94 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst, align 2
98 define i8 @test_atomicrmw_add_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) {
99 ; CHECK-LABEL: @test_atomicrmw_add_i8_global_system_align4(
100 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[VALUE:%.*]] to i32
101 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
102 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
103 ; CHECK: atomicrmw.start:
104 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
105 ; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[TMP1]]
106 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[NEW]], 255
107 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[LOADED]], -256
108 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP3]]
109 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[TMP5]] seq_cst seq_cst, align 4
110 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
111 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
112 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
113 ; CHECK: atomicrmw.end:
114 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[NEWLOADED]] to i8
115 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
117 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst, align 4
121 define i8 @test_atomicrmw_sub_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
122 ; CHECK-LABEL: @test_atomicrmw_sub_i8_global_system(
123 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
124 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
125 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
126 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
127 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
128 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
129 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
130 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
131 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
132 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
133 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
134 ; CHECK: atomicrmw.start:
135 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
136 ; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], [[VALOPERAND_SHIFTED]]
137 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]]
138 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
139 ; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]]
140 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4
141 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
142 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
143 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
144 ; CHECK: atomicrmw.end:
145 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
146 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
147 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
149 %res = atomicrmw sub ptr addrspace(1) %ptr, i8 %value seq_cst
153 define i8 @test_atomicrmw_and_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
154 ; CHECK-LABEL: @test_atomicrmw_and_i8_global_system(
155 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
156 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
157 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
158 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
159 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
160 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
161 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
162 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
163 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
164 ; CHECK-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]]
165 ; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw and ptr addrspace(1) [[ALIGNEDADDR]], i32 [[ANDOPERAND]] seq_cst, align 4
166 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
167 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
168 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
170 %res = atomicrmw and ptr addrspace(1) %ptr, i8 %value seq_cst
174 define i8 @test_atomicrmw_nand_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
175 ; CHECK-LABEL: @test_atomicrmw_nand_i8_global_system(
176 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
177 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
178 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
179 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
180 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
181 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
182 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
183 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
184 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
185 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
186 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
187 ; CHECK: atomicrmw.start:
188 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
189 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[LOADED]], [[VALOPERAND_SHIFTED]]
190 ; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP5]], -1
191 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[NEW]], [[MASK]]
192 ; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
193 ; CHECK-NEXT: [[TMP8:%.*]] = or i32 [[TMP7]], [[TMP6]]
194 ; CHECK-NEXT: [[TMP9:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP8]] seq_cst seq_cst, align 4
195 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP9]], 1
196 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP9]], 0
197 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
198 ; CHECK: atomicrmw.end:
199 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
200 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
201 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
203 %res = atomicrmw nand ptr addrspace(1) %ptr, i8 %value seq_cst
207 define i8 @test_atomicrmw_or_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
208 ; CHECK-LABEL: @test_atomicrmw_or_i8_global_system(
209 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
210 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
211 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
212 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
213 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
214 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
215 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
216 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
217 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
218 ; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw or ptr addrspace(1) [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] seq_cst, align 4
219 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
220 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
221 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
223 %res = atomicrmw or ptr addrspace(1) %ptr, i8 %value seq_cst
227 define i8 @test_atomicrmw_xor_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
228 ; CHECK-LABEL: @test_atomicrmw_xor_i8_global_system(
229 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
230 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
231 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
232 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
233 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
234 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
235 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
236 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32
237 ; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
238 ; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr addrspace(1) [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] seq_cst, align 4
239 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
240 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
241 ; CHECK-NEXT: ret i8 [[EXTRACTED]]
243 %res = atomicrmw xor ptr addrspace(1) %ptr, i8 %value seq_cst
247 define i8 @test_atomicrmw_max_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
248 ; CHECK-LABEL: @test_atomicrmw_max_i8_global_system(
249 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
250 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
251 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
252 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
253 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
254 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
255 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
256 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
257 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
258 ; CHECK: atomicrmw.start:
259 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
260 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
261 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
262 ; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i8 [[EXTRACTED]], [[VALUE:%.*]]
263 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]]
264 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
265 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
266 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
267 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
268 ; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
269 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
270 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0
271 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
272 ; CHECK: atomicrmw.end:
273 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
274 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
275 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
277 %res = atomicrmw max ptr addrspace(1) %ptr, i8 %value seq_cst
281 define i8 @test_atomicrmw_min_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
282 ; CHECK-LABEL: @test_atomicrmw_min_i8_global_system(
283 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
284 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
285 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
286 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
287 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
288 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
289 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
290 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
291 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
292 ; CHECK: atomicrmw.start:
293 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
294 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
295 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
296 ; CHECK-NEXT: [[TMP4:%.*]] = icmp sle i8 [[EXTRACTED]], [[VALUE:%.*]]
297 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]]
298 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
299 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
300 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
301 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
302 ; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
303 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
304 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0
305 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
306 ; CHECK: atomicrmw.end:
307 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
308 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
309 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
311 %res = atomicrmw min ptr addrspace(1) %ptr, i8 %value seq_cst
315 define i8 @test_atomicrmw_umax_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
316 ; CHECK-LABEL: @test_atomicrmw_umax_i8_global_system(
317 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
318 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
319 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
320 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
321 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
322 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
323 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
324 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
325 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
326 ; CHECK: atomicrmw.start:
327 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
328 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
329 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
330 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
331 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]]
332 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
333 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
334 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
335 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
336 ; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
337 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
338 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0
339 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
340 ; CHECK: atomicrmw.end:
341 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
342 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
343 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
345 %res = atomicrmw umax ptr addrspace(1) %ptr, i8 %value seq_cst
349 define i8 @test_atomicrmw_umin_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
350 ; CHECK-LABEL: @test_atomicrmw_umin_i8_global_system(
351 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
352 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
353 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
354 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
355 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
356 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
357 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
358 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
359 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
360 ; CHECK: atomicrmw.start:
361 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
362 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
363 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
364 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i8 [[EXTRACTED]], [[VALUE:%.*]]
365 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]]
366 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
367 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
368 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
369 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
370 ; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
371 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
372 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0
373 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
374 ; CHECK: atomicrmw.end:
375 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
376 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
377 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
379 %res = atomicrmw umin ptr addrspace(1) %ptr, i8 %value seq_cst
383 define i8 @test_cmpxchg_i8_global_system(ptr addrspace(1) %out, i8 %in, i8 %old) {
384 ; CHECK-LABEL: @test_cmpxchg_i8_global_system(
385 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[OUT:%.*]], i64 4
386 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[GEP]], i64 -4)
387 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64
388 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
389 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
390 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
391 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
392 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
393 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[IN:%.*]] to i32
394 ; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
395 ; CHECK-NEXT: [[TMP5:%.*]] = zext i8 [[OLD:%.*]] to i32
396 ; CHECK-NEXT: [[TMP6:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
397 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
398 ; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], [[INV_MASK]]
399 ; CHECK-NEXT: br label [[PARTWORD_CMPXCHG_LOOP:%.*]]
400 ; CHECK: partword.cmpxchg.loop:
401 ; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[TMP0:%.*]] ], [ [[TMP15:%.*]], [[PARTWORD_CMPXCHG_FAILURE:%.*]] ]
402 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP4]]
403 ; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP9]], [[TMP6]]
404 ; CHECK-NEXT: [[TMP12:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[TMP11]], i32 [[TMP10]] seq_cst seq_cst, align 4
405 ; CHECK-NEXT: [[TMP13:%.*]] = extractvalue { i32, i1 } [[TMP12]], 0
406 ; CHECK-NEXT: [[TMP14:%.*]] = extractvalue { i32, i1 } [[TMP12]], 1
407 ; CHECK-NEXT: br i1 [[TMP14]], label [[PARTWORD_CMPXCHG_END:%.*]], label [[PARTWORD_CMPXCHG_FAILURE]]
408 ; CHECK: partword.cmpxchg.failure:
409 ; CHECK-NEXT: [[TMP15]] = and i32 [[TMP13]], [[INV_MASK]]
410 ; CHECK-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP9]], [[TMP15]]
411 ; CHECK-NEXT: br i1 [[TMP16]], label [[PARTWORD_CMPXCHG_LOOP]], label [[PARTWORD_CMPXCHG_END]]
412 ; CHECK: partword.cmpxchg.end:
413 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP13]], [[SHIFTAMT]]
414 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
415 ; CHECK-NEXT: [[TMP17:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
416 ; CHECK-NEXT: [[TMP18:%.*]] = insertvalue { i8, i1 } [[TMP17]], i1 [[TMP14]], 1
417 ; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue { i8, i1 } [[TMP18]], 0
418 ; CHECK-NEXT: ret i8 [[EXTRACT]]
420 %gep = getelementptr i8, ptr addrspace(1) %out, i64 4
421 %res = cmpxchg ptr addrspace(1) %gep, i8 %old, i8 %in seq_cst seq_cst
422 %extract = extractvalue {i8, i1} %res, 0
426 define i8 @test_atomicrmw_inc_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
427 ; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system(
428 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
429 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
430 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
431 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
432 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
433 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
434 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
435 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
436 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
437 ; CHECK: atomicrmw.start:
438 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
439 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
440 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
441 ; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1
442 ; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
443 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]]
444 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
445 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
446 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
447 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
448 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
449 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
450 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
451 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
452 ; CHECK: atomicrmw.end:
453 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
454 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
455 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
457 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst
461 define i8 @test_atomicrmw_inc_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) {
462 ; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system_align2(
463 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
464 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
465 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
466 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
467 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
468 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
469 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
470 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
471 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
472 ; CHECK: atomicrmw.start:
473 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
474 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
475 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
476 ; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1
477 ; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
478 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]]
479 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
480 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
481 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
482 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
483 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
484 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
485 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
486 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
487 ; CHECK: atomicrmw.end:
488 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
489 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
490 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
492 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 2
496 define i8 @test_atomicrmw_inc_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) {
497 ; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system_align4(
498 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
499 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
500 ; CHECK: atomicrmw.start:
501 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
502 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8
503 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[EXTRACTED]], 1
504 ; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
505 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i8 0, i8 [[TMP2]]
506 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
507 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256
508 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
509 ; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
510 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
511 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
512 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
513 ; CHECK: atomicrmw.end:
514 ; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8
515 ; CHECK-NEXT: ret i8 [[EXTRACTED1]]
517 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 4
521 define i8 @test_atomicrmw_inc_i8_flat_system(ptr %ptr, i8 %value) {
522 ; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system(
523 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
524 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
525 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
526 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
527 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
528 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
529 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
530 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
531 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
532 ; CHECK: atomicrmw.start:
533 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
534 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
535 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
536 ; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1
537 ; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
538 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]]
539 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
540 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
541 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
542 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
543 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
544 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
545 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
546 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
547 ; CHECK: atomicrmw.end:
548 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
549 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
550 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
552 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst
556 define i8 @test_atomicrmw_inc_i8_flat_system_align2(ptr %ptr, i8 %value) {
557 ; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system_align2(
558 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
559 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
560 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
561 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
562 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
563 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
564 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
565 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
566 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
567 ; CHECK: atomicrmw.start:
568 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
569 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
570 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
571 ; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1
572 ; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
573 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]]
574 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
575 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
576 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
577 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
578 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
579 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
580 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
581 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
582 ; CHECK: atomicrmw.end:
583 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
584 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
585 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
587 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst, align 2
591 define i8 @test_atomicrmw_inc_i8_flat_system_align4(ptr %ptr, i8 %value) {
592 ; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system_align4(
593 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
594 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
595 ; CHECK: atomicrmw.start:
596 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
597 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8
598 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[EXTRACTED]], 1
599 ; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
600 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i8 0, i8 [[TMP2]]
601 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
602 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256
603 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
604 ; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
605 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
606 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
607 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
608 ; CHECK: atomicrmw.end:
609 ; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8
610 ; CHECK-NEXT: ret i8 [[EXTRACTED1]]
612 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst, align 4
616 define i8 @test_atomicrmw_dec_i8_global_system(ptr addrspace(1) %ptr, i8 %value) {
617 ; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system(
618 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
619 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
620 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
621 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
622 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
623 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
624 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
625 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
626 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
627 ; CHECK: atomicrmw.start:
628 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
629 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
630 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
631 ; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1
632 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0
633 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
634 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
635 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]]
636 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
637 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
638 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
639 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
640 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
641 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
642 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
643 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
644 ; CHECK: atomicrmw.end:
645 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
646 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
647 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
649 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst
653 define i8 @test_atomicrmw_dec_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) {
654 ; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system_align2(
655 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
656 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
657 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
658 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
659 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
660 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
661 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
662 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
663 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
664 ; CHECK: atomicrmw.start:
665 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
666 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
667 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
668 ; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1
669 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0
670 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
671 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
672 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]]
673 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
674 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
675 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
676 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
677 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
678 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
679 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
680 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
681 ; CHECK: atomicrmw.end:
682 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
683 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
684 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
686 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 2
690 define i8 @test_atomicrmw_dec_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) {
691 ; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system_align4(
692 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
693 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
694 ; CHECK: atomicrmw.start:
695 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
696 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8
697 ; CHECK-NEXT: [[TMP2:%.*]] = sub i8 [[EXTRACTED]], 1
698 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[EXTRACTED]], 0
699 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
700 ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
701 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 [[VALUE]], i8 [[TMP2]]
702 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
703 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256
704 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
705 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
706 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
707 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
708 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
709 ; CHECK: atomicrmw.end:
710 ; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8
711 ; CHECK-NEXT: ret i8 [[EXTRACTED1]]
713 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 4
717 define i8 @test_atomicrmw_dec_i8_flat_system(ptr %ptr, i8 %value) {
718 ; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system(
719 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
720 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
721 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
722 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
723 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
724 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
725 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
726 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
727 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
728 ; CHECK: atomicrmw.start:
729 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
730 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
731 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
732 ; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1
733 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0
734 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
735 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
736 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]]
737 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
738 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
739 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
740 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
741 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
742 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
743 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
744 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
745 ; CHECK: atomicrmw.end:
746 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
747 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
748 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
750 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst
754 define i8 @test_atomicrmw_dec_i8_flat_system_align2(ptr %ptr, i8 %value) {
755 ; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system_align2(
756 ; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
757 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
758 ; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
759 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
760 ; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
761 ; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
762 ; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
763 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
764 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
765 ; CHECK: atomicrmw.start:
766 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
767 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
768 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
769 ; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1
770 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0
771 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
772 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
773 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]]
774 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
775 ; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
776 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
777 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
778 ; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
779 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
780 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
781 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
782 ; CHECK: atomicrmw.end:
783 ; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
784 ; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
785 ; CHECK-NEXT: ret i8 [[EXTRACTED3]]
787 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst, align 2
791 define i8 @test_atomicrmw_dec_i8_flat_system_align4(ptr %ptr, i8 %value) {
792 ; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system_align4(
793 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
794 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
795 ; CHECK: atomicrmw.start:
796 ; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
797 ; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8
798 ; CHECK-NEXT: [[TMP2:%.*]] = sub i8 [[EXTRACTED]], 1
799 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[EXTRACTED]], 0
800 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
801 ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
802 ; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 [[VALUE]], i8 [[TMP2]]
803 ; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
804 ; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256
805 ; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
806 ; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
807 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
808 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
809 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
810 ; CHECK: atomicrmw.end:
811 ; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8
812 ; CHECK-NEXT: ret i8 [[EXTRACTED1]]
814 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst, align 4