1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -atomic-expand %s | FileCheck -check-prefix=GFX908 %s
3 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -atomic-expand %s | FileCheck -check-prefix=GFX90A %s
4 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx940 -atomic-expand %s | FileCheck -check-prefix=GFX940 %s
5 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -atomic-expand %s | FileCheck -check-prefix=GFX1100 %s
7 define float @syncscope_system(ptr %addr, float %val) #0 {
8 ; GFX908-LABEL: @syncscope_system(
9 ; GFX908-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
10 ; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]]
11 ; GFX908: atomicrmw.start:
12 ; GFX908-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
13 ; GFX908-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
14 ; GFX908-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
15 ; GFX908-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
16 ; GFX908-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
17 ; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
18 ; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
19 ; GFX908-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
20 ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
21 ; GFX908: atomicrmw.end:
22 ; GFX908-NEXT: ret float [[TMP5]]
24 ; GFX90A-LABEL: @syncscope_system(
25 ; GFX90A-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
26 ; GFX90A-NEXT: br label [[ATOMICRMW_START:%.*]]
27 ; GFX90A: atomicrmw.start:
28 ; GFX90A-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
29 ; GFX90A-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
30 ; GFX90A-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
31 ; GFX90A-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
32 ; GFX90A-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
33 ; GFX90A-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
34 ; GFX90A-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
35 ; GFX90A-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
36 ; GFX90A-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
37 ; GFX90A: atomicrmw.end:
38 ; GFX90A-NEXT: ret float [[TMP5]]
40 ; GFX940-LABEL: @syncscope_system(
41 ; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] seq_cst, align 4
42 ; GFX940-NEXT: ret float [[RES]]
44 ; GFX1100-LABEL: @syncscope_system(
45 ; GFX1100-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
46 ; GFX1100-NEXT: br label [[ATOMICRMW_START:%.*]]
47 ; GFX1100: atomicrmw.start:
48 ; GFX1100-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
49 ; GFX1100-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
50 ; GFX1100-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
51 ; GFX1100-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
52 ; GFX1100-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
53 ; GFX1100-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
54 ; GFX1100-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
55 ; GFX1100-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
56 ; GFX1100-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
57 ; GFX1100: atomicrmw.end:
58 ; GFX1100-NEXT: ret float [[TMP5]]
60 ; GFX11-LABEL: @syncscope_system(
61 ; GFX11-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
62 ; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]]
63 ; GFX11: atomicrmw.start:
64 ; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
65 ; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
66 ; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32
67 ; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
68 ; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
69 ; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
70 ; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
71 ; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
72 ; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
73 ; GFX11: atomicrmw.end:
74 ; GFX11-NEXT: ret float [[TMP6]]
75 %res = atomicrmw fadd ptr %addr, float %val seq_cst
79 define float @syncscope_workgroup_rtn(ptr %addr, float %val) #0 {
80 ; GFX908-LABEL: @syncscope_workgroup_rtn(
81 ; GFX908-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
82 ; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]]
83 ; GFX908: atomicrmw.start:
84 ; GFX908-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
85 ; GFX908-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
86 ; GFX908-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
87 ; GFX908-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
88 ; GFX908-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] syncscope("workgroup") seq_cst seq_cst, align 4
89 ; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
90 ; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
91 ; GFX908-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
92 ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
93 ; GFX908: atomicrmw.end:
94 ; GFX908-NEXT: ret float [[TMP5]]
96 ; GFX90A-LABEL: @syncscope_workgroup_rtn(
97 ; GFX90A-NEXT: br label [[ATOMICRMW_CHECK_SHARED:%.*]]
98 ; GFX90A: atomicrmw.check.shared:
99 ; GFX90A-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[ADDR:%.*]])
100 ; GFX90A-NEXT: br i1 [[IS_SHARED]], label [[ATOMICRMW_SHARED:%.*]], label [[ATOMICRMW_CHECK_PRIVATE:%.*]]
101 ; GFX90A: atomicrmw.shared:
102 ; GFX90A-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(3)
103 ; GFX90A-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspace(3) [[TMP1]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
104 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI:%.*]]
105 ; GFX90A: atomicrmw.check.private:
106 ; GFX90A-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[ADDR]])
107 ; GFX90A-NEXT: br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]]
108 ; GFX90A: atomicrmw.private:
109 ; GFX90A-NEXT: [[TMP3:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(5)
110 ; GFX90A-NEXT: [[LOADED_PRIVATE:%.*]] = load float, ptr addrspace(5) [[TMP3]], align 4
111 ; GFX90A-NEXT: [[VAL_NEW:%.*]] = fadd float [[LOADED_PRIVATE]], [[VAL]]
112 ; GFX90A-NEXT: store float [[VAL_NEW]], ptr addrspace(5) [[TMP3]], align 4
113 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI]]
114 ; GFX90A: atomicrmw.global:
115 ; GFX90A-NEXT: [[TMP4:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(1)
116 ; GFX90A-NEXT: [[TMP5:%.*]] = atomicrmw fadd ptr addrspace(1) [[TMP4]], float [[VAL]] syncscope("workgroup") seq_cst, align 4
117 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI]]
118 ; GFX90A: atomicrmw.phi:
119 ; GFX90A-NEXT: [[LOADED_PHI:%.*]] = phi float [ [[TMP2]], [[ATOMICRMW_SHARED]] ], [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP5]], [[ATOMICRMW_GLOBAL]] ]
120 ; GFX90A-NEXT: br label [[ATOMICRMW_END:%.*]]
121 ; GFX90A: atomicrmw.end:
122 ; GFX90A-NEXT: ret float [[LOADED_PHI]]
124 ; GFX940-LABEL: @syncscope_workgroup_rtn(
125 ; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
126 ; GFX940-NEXT: ret float [[RES]]
128 ; GFX1100-LABEL: @syncscope_workgroup_rtn(
129 ; GFX1100-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
130 ; GFX1100-NEXT: ret float [[RES]]
132 ; GFX11-LABEL: @syncscope_workgroup_rtn(
133 ; GFX11-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
134 ; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]]
135 ; GFX11: atomicrmw.start:
136 ; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
137 ; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
138 ; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32
139 ; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
140 ; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP4]], i32 [[TMP3]] syncscope("workgroup") seq_cst seq_cst, align 4
141 ; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
142 ; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
143 ; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
144 ; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
145 ; GFX11: atomicrmw.end:
146 ; GFX11-NEXT: ret float [[TMP6]]
147 %res = atomicrmw fadd ptr %addr, float %val syncscope("workgroup") seq_cst
151 define void @syncscope_workgroup_nortn(ptr %addr, float %val) #0 {
152 ; GFX908-LABEL: @syncscope_workgroup_nortn(
153 ; GFX908-NEXT: br label [[ATOMICRMW_CHECK_SHARED:%.*]]
154 ; GFX908: atomicrmw.check.shared:
155 ; GFX908-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[ADDR:%.*]])
156 ; GFX908-NEXT: br i1 [[IS_SHARED]], label [[ATOMICRMW_SHARED:%.*]], label [[ATOMICRMW_CHECK_PRIVATE:%.*]]
157 ; GFX908: atomicrmw.shared:
158 ; GFX908-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(3)
159 ; GFX908-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspace(3) [[TMP1]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
160 ; GFX908-NEXT: br label [[ATOMICRMW_PHI:%.*]]
161 ; GFX908: atomicrmw.check.private:
162 ; GFX908-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[ADDR]])
163 ; GFX908-NEXT: br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]]
164 ; GFX908: atomicrmw.private:
165 ; GFX908-NEXT: [[TMP3:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(5)
166 ; GFX908-NEXT: [[LOADED_PRIVATE:%.*]] = load float, ptr addrspace(5) [[TMP3]], align 4
167 ; GFX908-NEXT: [[VAL_NEW:%.*]] = fadd float [[LOADED_PRIVATE]], [[VAL]]
168 ; GFX908-NEXT: store float [[VAL_NEW]], ptr addrspace(5) [[TMP3]], align 4
169 ; GFX908-NEXT: br label [[ATOMICRMW_PHI]]
170 ; GFX908: atomicrmw.global:
171 ; GFX908-NEXT: [[TMP4:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(1)
172 ; GFX908-NEXT: [[TMP5:%.*]] = atomicrmw fadd ptr addrspace(1) [[TMP4]], float [[VAL]] syncscope("workgroup") seq_cst, align 4
173 ; GFX908-NEXT: br label [[ATOMICRMW_PHI]]
174 ; GFX908: atomicrmw.phi:
175 ; GFX908-NEXT: [[LOADED_PHI:%.*]] = phi float [ [[TMP2]], [[ATOMICRMW_SHARED]] ], [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP5]], [[ATOMICRMW_GLOBAL]] ]
176 ; GFX908-NEXT: br label [[ATOMICRMW_END:%.*]]
177 ; GFX908: atomicrmw.end:
178 ; GFX908-NEXT: ret void
180 ; GFX90A-LABEL: @syncscope_workgroup_nortn(
181 ; GFX90A-NEXT: br label [[ATOMICRMW_CHECK_SHARED:%.*]]
182 ; GFX90A: atomicrmw.check.shared:
183 ; GFX90A-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[ADDR:%.*]])
184 ; GFX90A-NEXT: br i1 [[IS_SHARED]], label [[ATOMICRMW_SHARED:%.*]], label [[ATOMICRMW_CHECK_PRIVATE:%.*]]
185 ; GFX90A: atomicrmw.shared:
186 ; GFX90A-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(3)
187 ; GFX90A-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspace(3) [[TMP1]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
188 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI:%.*]]
189 ; GFX90A: atomicrmw.check.private:
190 ; GFX90A-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[ADDR]])
191 ; GFX90A-NEXT: br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]]
192 ; GFX90A: atomicrmw.private:
193 ; GFX90A-NEXT: [[TMP3:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(5)
194 ; GFX90A-NEXT: [[LOADED_PRIVATE:%.*]] = load float, ptr addrspace(5) [[TMP3]], align 4
195 ; GFX90A-NEXT: [[VAL_NEW:%.*]] = fadd float [[LOADED_PRIVATE]], [[VAL]]
196 ; GFX90A-NEXT: store float [[VAL_NEW]], ptr addrspace(5) [[TMP3]], align 4
197 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI]]
198 ; GFX90A: atomicrmw.global:
199 ; GFX90A-NEXT: [[TMP4:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(1)
200 ; GFX90A-NEXT: [[TMP5:%.*]] = atomicrmw fadd ptr addrspace(1) [[TMP4]], float [[VAL]] syncscope("workgroup") seq_cst, align 4
201 ; GFX90A-NEXT: br label [[ATOMICRMW_PHI]]
202 ; GFX90A: atomicrmw.phi:
203 ; GFX90A-NEXT: [[LOADED_PHI:%.*]] = phi float [ [[TMP2]], [[ATOMICRMW_SHARED]] ], [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP5]], [[ATOMICRMW_GLOBAL]] ]
204 ; GFX90A-NEXT: br label [[ATOMICRMW_END:%.*]]
205 ; GFX90A: atomicrmw.end:
206 ; GFX90A-NEXT: ret void
208 ; GFX940-LABEL: @syncscope_workgroup_nortn(
209 ; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
210 ; GFX940-NEXT: ret void
212 ; GFX1100-LABEL: @syncscope_workgroup_nortn(
213 ; GFX1100-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
214 ; GFX1100-NEXT: ret void
216 ; GFX11-LABEL: @syncscope_workgroup_nortn(
217 ; GFX11-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
218 ; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]]
219 ; GFX11: atomicrmw.start:
220 ; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
221 ; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
222 ; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32
223 ; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
224 ; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP4]], i32 [[TMP3]] syncscope("workgroup") seq_cst seq_cst, align 4
225 ; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
226 ; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
227 ; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
228 ; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
229 ; GFX11: atomicrmw.end:
230 ; GFX11-NEXT: ret void
231 %res = atomicrmw fadd ptr %addr, float %val syncscope("workgroup") seq_cst
235 define float @no_unsafe(ptr %addr, float %val) {
236 ; GFX908-LABEL: @no_unsafe(
237 ; GFX908-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
238 ; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]]
239 ; GFX908: atomicrmw.start:
240 ; GFX908-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
241 ; GFX908-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
242 ; GFX908-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
243 ; GFX908-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
244 ; GFX908-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] syncscope("workgroup") seq_cst seq_cst, align 4
245 ; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
246 ; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
247 ; GFX908-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
248 ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
249 ; GFX908: atomicrmw.end:
250 ; GFX908-NEXT: ret float [[TMP5]]
252 ; GFX90A-LABEL: @no_unsafe(
253 ; GFX90A-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
254 ; GFX90A-NEXT: br label [[ATOMICRMW_START:%.*]]
255 ; GFX90A: atomicrmw.start:
256 ; GFX90A-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
257 ; GFX90A-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
258 ; GFX90A-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
259 ; GFX90A-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
260 ; GFX90A-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] syncscope("workgroup") seq_cst seq_cst, align 4
261 ; GFX90A-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
262 ; GFX90A-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
263 ; GFX90A-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
264 ; GFX90A-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
265 ; GFX90A: atomicrmw.end:
266 ; GFX90A-NEXT: ret float [[TMP5]]
268 ; GFX940-LABEL: @no_unsafe(
269 ; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float [[VAL:%.*]] syncscope("workgroup") seq_cst, align 4
270 ; GFX940-NEXT: ret float [[RES]]
272 ; GFX1100-LABEL: @no_unsafe(
273 ; GFX1100-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
274 ; GFX1100-NEXT: br label [[ATOMICRMW_START:%.*]]
275 ; GFX1100: atomicrmw.start:
276 ; GFX1100-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
277 ; GFX1100-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
278 ; GFX1100-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32
279 ; GFX1100-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
280 ; GFX1100-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP3]], i32 [[TMP2]] syncscope("workgroup") seq_cst seq_cst, align 4
281 ; GFX1100-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
282 ; GFX1100-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
283 ; GFX1100-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
284 ; GFX1100-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
285 ; GFX1100: atomicrmw.end:
286 ; GFX1100-NEXT: ret float [[TMP5]]
288 ; GFX11-LABEL: @no_unsafe(
289 ; GFX11-NEXT: [[TMP1:%.*]] = load float, ptr [[ADDR:%.*]], align 4
290 ; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]]
291 ; GFX11: atomicrmw.start:
292 ; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
293 ; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VAL:%.*]]
294 ; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32
295 ; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
296 ; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[ADDR]], i32 [[TMP4]], i32 [[TMP3]] syncscope("workgroup") seq_cst seq_cst, align 4
297 ; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
298 ; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
299 ; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
300 ; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
301 ; GFX11: atomicrmw.end:
302 ; GFX11-NEXT: ret float [[TMP6]]
303 %res = atomicrmw fadd ptr %addr, float %val syncscope("workgroup") seq_cst
307 attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" }