Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / AtomicExpand / AMDGPU / expand-atomic-rmw-fsub.ll
blobb4e999e58d015192cae75d8f18b23db6726c401b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -passes=atomic-expand %s | FileCheck -check-prefix=GCN %s
3 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=atomic-expand %s | FileCheck -check-prefix=GCN %s
5 define float @test_atomicrmw_fsub_f32_flat(ptr %ptr, float %value) {
6 ; GCN-LABEL: @test_atomicrmw_fsub_f32_flat(
7 ; GCN-NEXT:    [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
8 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
9 ; GCN:       atomicrmw.start:
10 ; GCN-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
11 ; GCN-NEXT:    [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]]
12 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
13 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
14 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
15 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
16 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
17 ; GCN-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
18 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
19 ; GCN:       atomicrmw.end:
20 ; GCN-NEXT:    ret float [[TMP5]]
22   %res = atomicrmw fsub ptr %ptr, float %value seq_cst
23   ret float %res
26 define float @test_atomicrmw_fsub_f32_global(ptr addrspace(1) %ptr, float %value) {
27 ; GCN-LABEL: @test_atomicrmw_fsub_f32_global(
28 ; GCN-NEXT:    [[TMP1:%.*]] = load float, ptr addrspace(1) [[PTR:%.*]], align 4
29 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
30 ; GCN:       atomicrmw.start:
31 ; GCN-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
32 ; GCN-NEXT:    [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]]
33 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
34 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
35 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
36 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
37 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
38 ; GCN-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
39 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
40 ; GCN:       atomicrmw.end:
41 ; GCN-NEXT:    ret float [[TMP5]]
43   %res = atomicrmw fsub ptr addrspace(1) %ptr, float %value seq_cst
44   ret float %res
47 define float @test_atomicrmw_fsub_f32_local(ptr addrspace(3) %ptr, float %value) {
48 ; GCN-LABEL: @test_atomicrmw_fsub_f32_local(
49 ; GCN-NEXT:    [[TMP1:%.*]] = load float, ptr addrspace(3) [[PTR:%.*]], align 4
50 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
51 ; GCN:       atomicrmw.start:
52 ; GCN-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
53 ; GCN-NEXT:    [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]]
54 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
55 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
56 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(3) [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
57 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
58 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
59 ; GCN-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
60 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
61 ; GCN:       atomicrmw.end:
62 ; GCN-NEXT:    ret float [[TMP5]]
64   %res = atomicrmw fsub ptr addrspace(3) %ptr, float %value seq_cst
65   ret float %res
68 define half @test_atomicrmw_fsub_f16_flat(ptr %ptr, half %value) {
69 ; GCN-LABEL: @test_atomicrmw_fsub_f16_flat(
70 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
71 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
72 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
73 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
74 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
75 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
76 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
77 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
78 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
79 ; GCN:       atomicrmw.start:
80 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
81 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
82 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
83 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half
84 ; GCN-NEXT:    [[NEW:%.*]] = fsub half [[TMP4]], [[VALUE:%.*]]
85 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast half [[NEW]] to i16
86 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
87 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
88 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
89 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
90 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
91 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
92 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
93 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
94 ; GCN:       atomicrmw.end:
95 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
96 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
97 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to half
98 ; GCN-NEXT:    ret half [[TMP7]]
100   %res = atomicrmw fsub ptr %ptr, half %value seq_cst
101   ret half %res
104 define half @test_atomicrmw_fsub_f16_global(ptr addrspace(1) %ptr, half %value) {
105 ; GCN-LABEL: @test_atomicrmw_fsub_f16_global(
106 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
107 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
108 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
109 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
110 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
111 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
112 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
113 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
114 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
115 ; GCN:       atomicrmw.start:
116 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
117 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
118 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
119 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half
120 ; GCN-NEXT:    [[NEW:%.*]] = fsub half [[TMP4]], [[VALUE:%.*]]
121 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast half [[NEW]] to i16
122 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
123 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
124 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
125 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
126 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
127 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
128 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
129 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
130 ; GCN:       atomicrmw.end:
131 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
132 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
133 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to half
134 ; GCN-NEXT:    ret half [[TMP7]]
136   %res = atomicrmw fsub ptr addrspace(1) %ptr, half %value seq_cst
137   ret half %res
140 define half @test_atomicrmw_fsub_f16_global_align4(ptr addrspace(1) %ptr, half %value) {
141 ; GCN-LABEL: @test_atomicrmw_fsub_f16_global_align4(
142 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
143 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
144 ; GCN:       atomicrmw.start:
145 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
146 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
147 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to half
148 ; GCN-NEXT:    [[NEW:%.*]] = fsub half [[TMP2]], [[VALUE:%.*]]
149 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast half [[NEW]] to i16
150 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
151 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
152 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
153 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
154 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
155 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
156 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
157 ; GCN:       atomicrmw.end:
158 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
159 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to half
160 ; GCN-NEXT:    ret half [[TMP5]]
162   %res = atomicrmw fsub ptr addrspace(1) %ptr, half %value seq_cst, align 4
163   ret half %res
166 define half @test_atomicrmw_fsub_f16_local(ptr addrspace(3) %ptr, half %value) {
167 ; GCN-LABEL: @test_atomicrmw_fsub_f16_local(
168 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4)
169 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32
170 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
171 ; GCN-NEXT:    [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
172 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[TMP2]]
173 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
174 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4
175 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
176 ; GCN:       atomicrmw.start:
177 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
178 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]]
179 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
180 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half
181 ; GCN-NEXT:    [[NEW:%.*]] = fsub half [[TMP4]], [[VALUE:%.*]]
182 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast half [[NEW]] to i16
183 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
184 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]]
185 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
186 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
187 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4
188 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
189 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
190 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
191 ; GCN:       atomicrmw.end:
192 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]]
193 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
194 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to half
195 ; GCN-NEXT:    ret half [[TMP7]]
197   %res = atomicrmw fsub ptr addrspace(3) %ptr, half %value seq_cst
198   ret half %res
201 define double @test_atomicrmw_fsub_f64_flat__noprivate(ptr %ptr, double %value) {
202 ; GCN-LABEL: @test_atomicrmw_fsub_f64_flat__noprivate(
203 ; GCN-NEXT:    [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
204 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
205 ; GCN:       atomicrmw.start:
206 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
207 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
208 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
209 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
210 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8, !noalias.addrspace [[META0:![0-9]+]]
211 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
212 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
213 ; GCN-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
214 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
215 ; GCN:       atomicrmw.end:
216 ; GCN-NEXT:    ret double [[TMP5]]
218   %res = atomicrmw fsub ptr %ptr, double %value seq_cst, !noalias.addrspace !0
219   ret double %res
222 define double @test_atomicrmw_fsub_f64_flat(ptr %ptr, double %value) {
223 ; GCN-LABEL: @test_atomicrmw_fsub_f64_flat(
224 ; GCN-NEXT:    [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR:%.*]])
225 ; GCN-NEXT:    br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]]
226 ; GCN:       atomicrmw.private:
227 ; GCN-NEXT:    [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
228 ; GCN-NEXT:    [[LOADED_PRIVATE:%.*]] = load double, ptr addrspace(5) [[TMP1]], align 8
229 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED_PRIVATE]], [[VALUE:%.*]]
230 ; GCN-NEXT:    store double [[NEW]], ptr addrspace(5) [[TMP1]], align 8
231 ; GCN-NEXT:    br label [[ATOMICRMW_PHI:%.*]]
232 ; GCN:       atomicrmw.global:
233 ; GCN-NEXT:    [[TMP2:%.*]] = load double, ptr [[PTR]], align 8
234 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
235 ; GCN:       atomicrmw.start:
236 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP2]], [[ATOMICRMW_GLOBAL]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
237 ; GCN-NEXT:    [[NEW2:%.*]] = fsub double [[LOADED]], [[VALUE]]
238 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[NEW2]] to i64
239 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
240 ; GCN-NEXT:    [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8, !noalias.addrspace [[META0]]
241 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
242 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
243 ; GCN-NEXT:    [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
244 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END1:%.*]], label [[ATOMICRMW_START]]
245 ; GCN:       atomicrmw.end1:
246 ; GCN-NEXT:    br label [[ATOMICRMW_PHI]]
247 ; GCN:       atomicrmw.phi:
248 ; GCN-NEXT:    [[RES:%.*]] = phi double [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP6]], [[ATOMICRMW_END1]] ]
249 ; GCN-NEXT:    br label [[ATOMICRMW_END:%.*]]
250 ; GCN:       atomicrmw.end:
251 ; GCN-NEXT:    ret double [[RES]]
253   %res = atomicrmw fsub ptr %ptr, double %value seq_cst
254   ret double %res
257 define double @test_atomicrmw_fsub_f64_global(ptr addrspace(1) %ptr, double %value) {
258 ; GCN-LABEL: @test_atomicrmw_fsub_f64_global(
259 ; GCN-NEXT:    [[TMP1:%.*]] = load double, ptr addrspace(1) [[PTR:%.*]], align 8
260 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
261 ; GCN:       atomicrmw.start:
262 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
263 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
264 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
265 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
266 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
267 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
268 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
269 ; GCN-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
270 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
271 ; GCN:       atomicrmw.end:
272 ; GCN-NEXT:    ret double [[TMP5]]
274   %res = atomicrmw fsub ptr addrspace(1) %ptr, double %value seq_cst
275   ret double %res
278 define double @test_atomicrmw_fsub_f64_local(ptr addrspace(3) %ptr, double %value) {
279 ; GCN-LABEL: @test_atomicrmw_fsub_f64_local(
280 ; GCN-NEXT:    [[TMP1:%.*]] = load double, ptr addrspace(3) [[PTR:%.*]], align 8
281 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
282 ; GCN:       atomicrmw.start:
283 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
284 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
285 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
286 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
287 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(3) [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
288 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
289 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
290 ; GCN-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
291 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
292 ; GCN:       atomicrmw.end:
293 ; GCN-NEXT:    ret double [[TMP5]]
295   %res = atomicrmw fsub ptr addrspace(3) %ptr, double %value seq_cst
296   ret double %res
299 define float @test_atomicrmw_fsub_f32_global_strictfp(ptr addrspace(1) %ptr, float %value) strictfp {
300 ; GCN-LABEL: @test_atomicrmw_fsub_f32_global_strictfp(
301 ; GCN-NEXT:    [[TMP1:%.*]] = load float, ptr addrspace(1) [[PTR:%.*]], align 4
302 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
303 ; GCN:       atomicrmw.start:
304 ; GCN-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
305 ; GCN-NEXT:    [[NEW:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[LOADED]], float [[VALUE:%.*]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4:[0-9]+]]
306 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
307 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
308 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
309 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
310 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
311 ; GCN-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
312 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
313 ; GCN:       atomicrmw.end:
314 ; GCN-NEXT:    ret float [[TMP5]]
316   %res = atomicrmw fsub ptr addrspace(1) %ptr, float %value seq_cst
317   ret float %res
320 define bfloat @test_atomicrmw_fadd_bf16_local(ptr addrspace(3) %ptr, bfloat %value) {
321 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local(
322 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4)
323 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32
324 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
325 ; GCN-NEXT:    [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
326 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[TMP2]]
327 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
328 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4
329 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
330 ; GCN:       atomicrmw.start:
331 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
332 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]]
333 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
334 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
335 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
336 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
337 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
338 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]]
339 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
340 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
341 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
342 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
343 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
344 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
345 ; GCN:       atomicrmw.end:
346 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]]
347 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
348 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
349 ; GCN-NEXT:    ret bfloat [[TMP7]]
351   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic
352   ret bfloat %res
355 define bfloat @test_atomicrmw_fadd_bf16_local_align4(ptr addrspace(3) %ptr, bfloat %value) {
356 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local_align4(
357 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) [[PTR:%.*]], align 4
358 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
359 ; GCN:       atomicrmw.start:
360 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
361 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
362 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
363 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
364 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
365 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
366 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
367 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
368 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(3) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
369 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
370 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
371 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
372 ; GCN:       atomicrmw.end:
373 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
374 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
375 ; GCN-NEXT:    ret bfloat [[TMP5]]
377   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic, align 4
378   ret bfloat %res
381 define bfloat @test_atomicrmw_fadd_bf16_global_agent(ptr addrspace(1) %ptr, bfloat %value) {
382 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_agent(
383 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
384 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
385 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
386 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
387 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
388 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
389 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
390 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
391 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
392 ; GCN:       atomicrmw.start:
393 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
394 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
395 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
396 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
397 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
398 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
399 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
400 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
401 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
402 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
403 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
404 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
405 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
406 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
407 ; GCN:       atomicrmw.end:
408 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
409 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
410 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
411 ; GCN-NEXT:    ret bfloat [[TMP7]]
413   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value syncscope("agent") monotonic
414   ret bfloat %res
417 define bfloat @test_atomicrmw_fadd_bf16_global_agent_align4(ptr addrspace(1) %ptr, bfloat %value) {
418 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_agent_align4(
419 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
420 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
421 ; GCN:       atomicrmw.start:
422 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
423 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
424 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
425 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
426 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
427 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
428 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
429 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
430 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
431 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
432 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
433 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
434 ; GCN:       atomicrmw.end:
435 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
436 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
437 ; GCN-NEXT:    ret bfloat [[TMP5]]
439   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value syncscope("agent") monotonic, align 4
440   ret bfloat %res
443 define bfloat @test_atomicrmw_fadd_bf16_global_system(ptr addrspace(1) %ptr, bfloat %value) {
444 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_system(
445 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
446 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
447 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
448 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
449 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
450 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
451 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
452 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
453 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
454 ; GCN:       atomicrmw.start:
455 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
456 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
457 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
458 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
459 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
460 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
461 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
462 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
463 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
464 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
465 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
466 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
467 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
468 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
469 ; GCN:       atomicrmw.end:
470 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
471 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
472 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
473 ; GCN-NEXT:    ret bfloat [[TMP7]]
475   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value monotonic
476   ret bfloat %res
479 define bfloat @test_atomicrmw_fadd_bf16_global_system_align4(ptr addrspace(1) %ptr, bfloat %value) {
480 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_system_align4(
481 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
482 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
483 ; GCN:       atomicrmw.start:
484 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
485 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
486 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
487 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
488 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
489 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
490 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
491 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
492 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
493 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
494 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
495 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
496 ; GCN:       atomicrmw.end:
497 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
498 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
499 ; GCN-NEXT:    ret bfloat [[TMP5]]
501   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value monotonic, align 4
502   ret bfloat %res
505 define bfloat @test_atomicrmw_fadd_bf16_local_strictfp(ptr addrspace(3) %ptr, bfloat %value) #2 {
506 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local_strictfp(
507 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4)
508 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32
509 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
510 ; GCN-NEXT:    [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
511 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[TMP2]]
512 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
513 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4
514 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
515 ; GCN:       atomicrmw.start:
516 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
517 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]]
518 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
519 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
520 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
521 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
522 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
523 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]]
524 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
525 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
526 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
527 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
528 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
529 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
530 ; GCN:       atomicrmw.end:
531 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]]
532 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
533 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
534 ; GCN-NEXT:    ret bfloat [[TMP7]]
536   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic
537   ret bfloat %res
540 define bfloat @test_atomicrmw_fadd_bf16_flat_agent(ptr %ptr, bfloat %value) {
541 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_agent(
542 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
543 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
544 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
545 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
546 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
547 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
548 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
549 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
550 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
551 ; GCN:       atomicrmw.start:
552 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
553 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
554 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
555 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
556 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
557 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
558 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
559 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
560 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
561 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
562 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
563 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
564 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
565 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
566 ; GCN:       atomicrmw.end:
567 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
568 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
569 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
570 ; GCN-NEXT:    ret bfloat [[TMP7]]
572   %res = atomicrmw fadd ptr %ptr, bfloat %value syncscope("agent") monotonic
573   ret bfloat %res
576 define bfloat @test_atomicrmw_fadd_bf16_flat_agent_align4(ptr %ptr, bfloat %value) {
577 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_agent_align4(
578 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
579 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
580 ; GCN:       atomicrmw.start:
581 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
582 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
583 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
584 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
585 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
586 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
587 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
588 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
589 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
590 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
591 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
592 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
593 ; GCN:       atomicrmw.end:
594 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
595 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
596 ; GCN-NEXT:    ret bfloat [[TMP5]]
598   %res = atomicrmw fadd ptr %ptr, bfloat %value syncscope("agent") monotonic, align 4
599   ret bfloat %res
602 define bfloat @test_atomicrmw_fadd_bf16_flat_system(ptr %ptr, bfloat %value) {
603 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_system(
604 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
605 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
606 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
607 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
608 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
609 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
610 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
611 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
612 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
613 ; GCN:       atomicrmw.start:
614 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
615 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
616 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
617 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
618 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
619 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
620 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
621 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
622 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
623 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
624 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
625 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
626 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
627 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
628 ; GCN:       atomicrmw.end:
629 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
630 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
631 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
632 ; GCN-NEXT:    ret bfloat [[TMP7]]
634   %res = atomicrmw fadd ptr %ptr, bfloat %value monotonic
635   ret bfloat %res
638 define bfloat @test_atomicrmw_fadd_bf16_flat_system_align4(ptr %ptr, bfloat %value) {
639 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_system_align4(
640 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
641 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
642 ; GCN:       atomicrmw.start:
643 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
644 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
645 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
646 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
647 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
648 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
649 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
650 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
651 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
652 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
653 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
654 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
655 ; GCN:       atomicrmw.end:
656 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
657 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
658 ; GCN-NEXT:    ret bfloat [[TMP5]]
660   %res = atomicrmw fadd ptr %ptr, bfloat %value monotonic, align 4
661   ret bfloat %res
664 !0 = !{i32 5, i32 6}