Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / AtomicExpand / AMDGPU / expand-atomic-rmw-fsub.ll
blob9805c317b9215e59ddcc75537065543798e3ccd7
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -atomic-expand %s | FileCheck -check-prefix=GCN %s
3 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -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(ptr %ptr, double %value) {
202 ; GCN-LABEL: @test_atomicrmw_fsub_f64_flat(
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
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
219   ret double %res
222 define double @test_atomicrmw_fsub_f64_global(ptr addrspace(1) %ptr, double %value) {
223 ; GCN-LABEL: @test_atomicrmw_fsub_f64_global(
224 ; GCN-NEXT:    [[TMP1:%.*]] = load double, ptr addrspace(1) [[PTR:%.*]], align 8
225 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
226 ; GCN:       atomicrmw.start:
227 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
228 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
229 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
230 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
231 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
232 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
233 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
234 ; GCN-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
235 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
236 ; GCN:       atomicrmw.end:
237 ; GCN-NEXT:    ret double [[TMP5]]
239   %res = atomicrmw fsub ptr addrspace(1) %ptr, double %value seq_cst
240   ret double %res
243 define double @test_atomicrmw_fsub_f64_local(ptr addrspace(3) %ptr, double %value) {
244 ; GCN-LABEL: @test_atomicrmw_fsub_f64_local(
245 ; GCN-NEXT:    [[TMP1:%.*]] = load double, ptr addrspace(3) [[PTR:%.*]], align 8
246 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
247 ; GCN:       atomicrmw.start:
248 ; GCN-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
249 ; GCN-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
250 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
251 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
252 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(3) [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
253 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
254 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
255 ; GCN-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
256 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
257 ; GCN:       atomicrmw.end:
258 ; GCN-NEXT:    ret double [[TMP5]]
260   %res = atomicrmw fsub ptr addrspace(3) %ptr, double %value seq_cst
261   ret double %res
264 define float @test_atomicrmw_fsub_f32_global_strictfp(ptr addrspace(1) %ptr, float %value) strictfp {
265 ; GCN-LABEL: @test_atomicrmw_fsub_f32_global_strictfp(
266 ; GCN-NEXT:    [[TMP1:%.*]] = load float, ptr addrspace(1) [[PTR:%.*]], align 4
267 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
268 ; GCN:       atomicrmw.start:
269 ; GCN-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
270 ; GCN-NEXT:    [[NEW:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[LOADED]], float [[VALUE:%.*]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4:[0-9]+]]
271 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
272 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
273 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
274 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
275 ; GCN-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
276 ; GCN-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
277 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
278 ; GCN:       atomicrmw.end:
279 ; GCN-NEXT:    ret float [[TMP5]]
281   %res = atomicrmw fsub ptr addrspace(1) %ptr, float %value seq_cst
282   ret float %res
285 define bfloat @test_atomicrmw_fadd_bf16_local(ptr addrspace(3) %ptr, bfloat %value) {
286 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local(
287 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4)
288 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32
289 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
290 ; GCN-NEXT:    [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
291 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[TMP2]]
292 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
293 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4
294 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
295 ; GCN:       atomicrmw.start:
296 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
297 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]]
298 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
299 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
300 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
301 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
302 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
303 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]]
304 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
305 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
306 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
307 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
308 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
309 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
310 ; GCN:       atomicrmw.end:
311 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]]
312 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
313 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
314 ; GCN-NEXT:    ret bfloat [[TMP7]]
316   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic
317   ret bfloat %res
320 define bfloat @test_atomicrmw_fadd_bf16_local_align4(ptr addrspace(3) %ptr, bfloat %value) {
321 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local_align4(
322 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) [[PTR:%.*]], align 4
323 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
324 ; GCN:       atomicrmw.start:
325 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
326 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
327 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
328 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
329 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
330 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
331 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
332 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
333 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(3) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
334 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
335 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
336 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
337 ; GCN:       atomicrmw.end:
338 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
339 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
340 ; GCN-NEXT:    ret bfloat [[TMP5]]
342   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic, align 4
343   ret bfloat %res
346 define bfloat @test_atomicrmw_fadd_bf16_global_agent(ptr addrspace(1) %ptr, bfloat %value) {
347 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_agent(
348 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
349 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
350 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
351 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
352 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
353 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
354 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
355 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
356 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
357 ; GCN:       atomicrmw.start:
358 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
359 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
360 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
361 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
362 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
363 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
364 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
365 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
366 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
367 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
368 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
369 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
370 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
371 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
372 ; GCN:       atomicrmw.end:
373 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
374 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
375 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
376 ; GCN-NEXT:    ret bfloat [[TMP7]]
378   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value syncscope("agent") monotonic
379   ret bfloat %res
382 define bfloat @test_atomicrmw_fadd_bf16_global_agent_align4(ptr addrspace(1) %ptr, bfloat %value) {
383 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_agent_align4(
384 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
385 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
386 ; GCN:       atomicrmw.start:
387 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
388 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
389 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
390 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
391 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
392 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
393 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
394 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
395 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
396 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
397 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
398 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
399 ; GCN:       atomicrmw.end:
400 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
401 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
402 ; GCN-NEXT:    ret bfloat [[TMP5]]
404   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value syncscope("agent") monotonic, align 4
405   ret bfloat %res
408 define bfloat @test_atomicrmw_fadd_bf16_global_system(ptr addrspace(1) %ptr, bfloat %value) {
409 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_system(
410 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4)
411 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
412 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
413 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
414 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
415 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
416 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
417 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4
418 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
419 ; GCN:       atomicrmw.start:
420 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
421 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
422 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
423 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
424 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
425 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
426 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
427 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
428 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
429 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
430 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
431 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
432 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
433 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
434 ; GCN:       atomicrmw.end:
435 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
436 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
437 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
438 ; GCN-NEXT:    ret bfloat [[TMP7]]
440   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value monotonic
441   ret bfloat %res
444 define bfloat @test_atomicrmw_fadd_bf16_global_system_align4(ptr addrspace(1) %ptr, bfloat %value) {
445 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_global_system_align4(
446 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4
447 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
448 ; GCN:       atomicrmw.start:
449 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
450 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
451 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
452 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
453 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
454 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
455 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
456 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
457 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
458 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
459 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
460 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
461 ; GCN:       atomicrmw.end:
462 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
463 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
464 ; GCN-NEXT:    ret bfloat [[TMP5]]
466   %res = atomicrmw fadd ptr addrspace(1) %ptr, bfloat %value monotonic, align 4
467   ret bfloat %res
470 define bfloat @test_atomicrmw_fadd_bf16_local_strictfp(ptr addrspace(3) %ptr, bfloat %value) #2 {
471 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_local_strictfp(
472 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4)
473 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32
474 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
475 ; GCN-NEXT:    [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
476 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[TMP2]]
477 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
478 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4
479 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
480 ; GCN:       atomicrmw.start:
481 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
482 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]]
483 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
484 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
485 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
486 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
487 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
488 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]]
489 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
490 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
491 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
492 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
493 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
494 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
495 ; GCN:       atomicrmw.end:
496 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]]
497 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
498 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
499 ; GCN-NEXT:    ret bfloat [[TMP7]]
501   %res = atomicrmw fadd ptr addrspace(3) %ptr, bfloat %value monotonic
502   ret bfloat %res
505 define bfloat @test_atomicrmw_fadd_bf16_flat_agent(ptr %ptr, bfloat %value) {
506 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_agent(
507 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
508 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
509 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
510 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
511 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
512 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
513 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
514 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
515 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
516 ; GCN:       atomicrmw.start:
517 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
518 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
519 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
520 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
521 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
522 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
523 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
524 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
525 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
526 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
527 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
528 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
529 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
530 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
531 ; GCN:       atomicrmw.end:
532 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
533 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
534 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
535 ; GCN-NEXT:    ret bfloat [[TMP7]]
537   %res = atomicrmw fadd ptr %ptr, bfloat %value syncscope("agent") monotonic
538   ret bfloat %res
541 define bfloat @test_atomicrmw_fadd_bf16_flat_agent_align4(ptr %ptr, bfloat %value) {
542 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_agent_align4(
543 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
544 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
545 ; GCN:       atomicrmw.start:
546 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
547 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
548 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
549 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
550 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
551 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
552 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
553 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
554 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] syncscope("agent") monotonic monotonic, align 4
555 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
556 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
557 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
558 ; GCN:       atomicrmw.end:
559 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
560 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
561 ; GCN-NEXT:    ret bfloat [[TMP5]]
563   %res = atomicrmw fadd ptr %ptr, bfloat %value syncscope("agent") monotonic, align 4
564   ret bfloat %res
567 define bfloat @test_atomicrmw_fadd_bf16_flat_system(ptr %ptr, bfloat %value) {
568 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_system(
569 ; GCN-NEXT:    [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
570 ; GCN-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
571 ; GCN-NEXT:    [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
572 ; GCN-NEXT:    [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
573 ; GCN-NEXT:    [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
574 ; GCN-NEXT:    [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
575 ; GCN-NEXT:    [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
576 ; GCN-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4
577 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
578 ; GCN:       atomicrmw.start:
579 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
580 ; GCN-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
581 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
582 ; GCN-NEXT:    [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
583 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP4]], [[VALUE:%.*]]
584 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast bfloat [[NEW]] to i16
585 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP5]] to i32
586 ; GCN-NEXT:    [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
587 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
588 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
589 ; GCN-NEXT:    [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
590 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
591 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
592 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
593 ; GCN:       atomicrmw.end:
594 ; GCN-NEXT:    [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
595 ; GCN-NEXT:    [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
596 ; GCN-NEXT:    [[TMP7:%.*]] = bitcast i16 [[EXTRACTED3]] to bfloat
597 ; GCN-NEXT:    ret bfloat [[TMP7]]
599   %res = atomicrmw fadd ptr %ptr, bfloat %value monotonic
600   ret bfloat %res
603 define bfloat @test_atomicrmw_fadd_bf16_flat_system_align4(ptr %ptr, bfloat %value) {
604 ; GCN-LABEL: @test_atomicrmw_fadd_bf16_flat_system_align4(
605 ; GCN-NEXT:    [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4
606 ; GCN-NEXT:    br label [[ATOMICRMW_START:%.*]]
607 ; GCN:       atomicrmw.start:
608 ; GCN-NEXT:    [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
609 ; GCN-NEXT:    [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16
610 ; GCN-NEXT:    [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to bfloat
611 ; GCN-NEXT:    [[NEW:%.*]] = fadd bfloat [[TMP2]], [[VALUE:%.*]]
612 ; GCN-NEXT:    [[TMP3:%.*]] = bitcast bfloat [[NEW]] to i16
613 ; GCN-NEXT:    [[EXTENDED:%.*]] = zext i16 [[TMP3]] to i32
614 ; GCN-NEXT:    [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536
615 ; GCN-NEXT:    [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]]
616 ; GCN-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
617 ; GCN-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
618 ; GCN-NEXT:    [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
619 ; GCN-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
620 ; GCN:       atomicrmw.end:
621 ; GCN-NEXT:    [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16
622 ; GCN-NEXT:    [[TMP5:%.*]] = bitcast i16 [[EXTRACTED1]] to bfloat
623 ; GCN-NEXT:    ret bfloat [[TMP5]]
625   %res = atomicrmw fadd ptr %ptr, bfloat %value monotonic, align 4
626   ret bfloat %res