Skip to content

Commit 3b1f8fe

Browse files
arsenmgithub-actions[bot]
authored andcommitted
Automerge: InferAddressSpaces: Add more baseline tests for assume handling (#167611)
2 parents d55a556 + c1f18a2 commit 3b1f8fe

File tree

1 file changed

+200
-8
lines changed

1 file changed

+200
-8
lines changed

llvm/test/Transforms/InferAddressSpaces/AMDGPU/builtin-assumed-addrspace.ll

Lines changed: 200 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
22
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=infer-address-spaces -o - %s | FileCheck %s
33

4-
define float @f0(ptr %p) {
5-
; CHECK-LABEL: define float @f0(
4+
define float @assume_is_shared_gep(ptr %p) {
5+
; CHECK-LABEL: define float @assume_is_shared_gep(
66
; CHECK-SAME: ptr [[P:%.*]]) {
77
; CHECK-NEXT: [[ENTRY:.*:]]
88
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[P]])
@@ -24,8 +24,8 @@ entry:
2424
ret float %load
2525
}
2626

27-
define float @f1(ptr %p) {
28-
; CHECK-LABEL: define float @f1(
27+
define float @assume_is_private_gep(ptr %p) {
28+
; CHECK-LABEL: define float @assume_is_private_gep(
2929
; CHECK-SAME: ptr [[P:%.*]]) {
3030
; CHECK-NEXT: [[ENTRY:.*:]]
3131
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[P]])
@@ -47,8 +47,8 @@ entry:
4747
ret float %load
4848
}
4949

50-
define float @f2(ptr %p) {
51-
; CHECK-LABEL: define float @f2(
50+
define float @assume_not_private_and_not_shared_gep(ptr %p) {
51+
; CHECK-LABEL: define float @assume_not_private_and_not_shared_gep(
5252
; CHECK-SAME: ptr [[P:%.*]]) {
5353
; CHECK-NEXT: [[ENTRY:.*:]]
5454
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[P]])
@@ -78,8 +78,8 @@ entry:
7878
ret float %load
7979
}
8080

81-
define float @g0(i32 %c, ptr %p) {
82-
; CHECK-LABEL: define float @g0(
81+
define float @conditionally_assume_is_shared_gep(i32 %c, ptr %p) {
82+
; CHECK-LABEL: define float @conditionally_assume_is_shared_gep(
8383
; CHECK-SAME: i32 [[C:%.*]], ptr [[P:%.*]]) {
8484
; CHECK-NEXT: [[ENTRY:.*]]:
8585
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[C]], 0
@@ -127,6 +127,198 @@ if.end:
127127
ret float %add2
128128
}
129129

130+
define float @conditionally_assume_is_shared_else_assume_private(i32 %c, ptr %p) {
131+
; CHECK-LABEL: define float @conditionally_assume_is_shared_else_assume_private(
132+
; CHECK-SAME: i32 [[C:%.*]], ptr [[P:%.*]]) {
133+
; CHECK-NEXT: [[ENTRY:.*:]]
134+
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[C]], 0
135+
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label %[[IF_THEN_SHARED:.*]], label %[[IF_THEN_PRIVATE:.*]]
136+
; CHECK: [[IF_THEN_SHARED]]:
137+
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[P]])
138+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_SHARED]])
139+
; CHECK-NEXT: [[WORKITEM_ID_X_0:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
140+
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[WORKITEM_ID_X_0]] to i64
141+
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(3)
142+
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds float, ptr addrspace(3) [[TMP0]], i64 [[IDXPROM]]
143+
; CHECK-NEXT: [[LOAD0:%.*]] = load float, ptr addrspace(3) [[ARRAYIDX0]], align 4
144+
; CHECK-NEXT: [[ADD0:%.*]] = fadd float [[LOAD0]], 4.000000e+00
145+
; CHECK-NEXT: br label %[[IF_END:.*]]
146+
; CHECK: [[IF_THEN_PRIVATE]]:
147+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[P]])
148+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_PRIVATE]])
149+
; CHECK-NEXT: [[WORKITEM_ID_X_1:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
150+
; CHECK-NEXT: [[IDXPROM1:%.*]] = zext i32 [[WORKITEM_ID_X_1]] to i64
151+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(5)
152+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr addrspace(5) [[TMP1]], i64 [[IDXPROM1]]
153+
; CHECK-NEXT: [[LOAD1:%.*]] = load float, ptr addrspace(5) [[ARRAYIDX1]], align 4
154+
; CHECK-NEXT: [[ADD1:%.*]] = fadd float [[LOAD1]], 4.000000e+00
155+
; CHECK-NEXT: br label %[[IF_END]]
156+
; CHECK: [[IF_END]]:
157+
; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[ADD0]], %[[IF_THEN_SHARED]] ], [ [[ADD1]], %[[IF_THEN_PRIVATE]] ]
158+
; CHECK-NEXT: ret float [[PHI]]
159+
;
160+
entry:
161+
%tobool.not = icmp eq i32 %c, 0
162+
br i1 %tobool.not, label %if.then.shared, label %if.then.private
163+
164+
if.then.shared:
165+
%is.shared = call i1 @llvm.amdgcn.is.shared(ptr %p)
166+
tail call void @llvm.assume(i1 %is.shared)
167+
%workitem.id.x.0 = tail call i32 @llvm.amdgcn.workitem.id.x()
168+
%idxprom = zext i32 %workitem.id.x.0 to i64
169+
%arrayidx0 = getelementptr inbounds float, ptr %p, i64 %idxprom
170+
%load0 = load float, ptr %arrayidx0, align 4
171+
%add0 = fadd float %load0, 4.0
172+
br label %if.end
173+
174+
if.then.private:
175+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %p)
176+
tail call void @llvm.assume(i1 %is.private)
177+
%workitem.id.x.1 = tail call i32 @llvm.amdgcn.workitem.id.x()
178+
%idxprom1 = zext i32 %workitem.id.x.1 to i64
179+
%arrayidx1 = getelementptr inbounds float, ptr %p, i64 %idxprom1
180+
%load1 = load float, ptr %arrayidx1, align 4
181+
%add1 = fadd float %load1, 4.0
182+
br label %if.end
183+
184+
if.end:
185+
%phi = phi float [ %add0, %if.then.shared ], [ %add1, %if.then.private ]
186+
ret float %phi
187+
}
188+
189+
define float @assume_func_arg_is_shared_load(ptr %flat.ptr) {
190+
; CHECK-LABEL: define float @assume_func_arg_is_shared_load(
191+
; CHECK-SAME: ptr [[FLAT_PTR:%.*]]) {
192+
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[FLAT_PTR]])
193+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_SHARED]])
194+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[FLAT_PTR]], align 4
195+
; CHECK-NEXT: ret float [[LOAD]]
196+
;
197+
%is.shared = call i1 @llvm.amdgcn.is.shared(ptr %flat.ptr)
198+
tail call void @llvm.assume(i1 %is.shared)
199+
%load = load float, ptr %flat.ptr, align 4
200+
ret float %load
201+
}
202+
203+
define float @assume_func_arg_is_private_load(ptr %flat.ptr) {
204+
; CHECK-LABEL: define float @assume_func_arg_is_private_load(
205+
; CHECK-SAME: ptr [[FLAT_PTR:%.*]]) {
206+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[FLAT_PTR]])
207+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_PRIVATE]])
208+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[FLAT_PTR]], align 4
209+
; CHECK-NEXT: ret float [[LOAD]]
210+
;
211+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %flat.ptr)
212+
tail call void @llvm.assume(i1 %is.private)
213+
%load = load float, ptr %flat.ptr, align 4
214+
ret float %load
215+
}
216+
217+
define float @assume_func_arg_is_not_shared_not_private(ptr %flat.ptr) {
218+
; CHECK-LABEL: define float @assume_func_arg_is_not_shared_not_private(
219+
; CHECK-SAME: ptr [[FLAT_PTR:%.*]]) {
220+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[FLAT_PTR]])
221+
; CHECK-NEXT: [[NOT_PRIVATE:%.*]] = xor i1 [[IS_PRIVATE]], true
222+
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[FLAT_PTR]])
223+
; CHECK-NEXT: [[NOT_SHARED:%.*]] = xor i1 [[IS_SHARED]], true
224+
; CHECK-NEXT: [[NOT_PRIVATE_AND_NOT_SHARED:%.*]] = and i1 [[NOT_PRIVATE]], [[NOT_SHARED]]
225+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[NOT_PRIVATE_AND_NOT_SHARED]])
226+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[FLAT_PTR]], align 4
227+
; CHECK-NEXT: ret float [[LOAD]]
228+
;
229+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %flat.ptr)
230+
%not.private = xor i1 %is.private, true
231+
%is.shared = call i1 @llvm.amdgcn.is.shared(ptr %flat.ptr)
232+
%not.shared = xor i1 %is.shared, true
233+
%not.private.and.not.shared = and i1 %not.private, %not.shared
234+
tail call void @llvm.assume(i1 %not.private.and.not.shared)
235+
%load = load float, ptr %flat.ptr, align 4
236+
ret float %load
237+
}
238+
239+
define float @assume_func_arg_is_not_private_load(ptr %flat.ptr) {
240+
; CHECK-LABEL: define float @assume_func_arg_is_not_private_load(
241+
; CHECK-SAME: ptr [[FLAT_PTR:%.*]]) {
242+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[FLAT_PTR]])
243+
; CHECK-NEXT: [[NOT_IS_PRIVATE:%.*]] = xor i1 [[IS_PRIVATE]], true
244+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[NOT_IS_PRIVATE]])
245+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[FLAT_PTR]], align 4
246+
; CHECK-NEXT: ret float [[LOAD]]
247+
;
248+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %flat.ptr)
249+
%not.is.private = xor i1 %is.private, true
250+
tail call void @llvm.assume(i1 %not.is.private)
251+
%load = load float, ptr %flat.ptr, align 4
252+
ret float %load
253+
}
254+
255+
define i64 @assume_func_arg_is_not_private_atomicrmw(ptr %flat.ptr, i64 %val) {
256+
; CHECK-LABEL: define i64 @assume_func_arg_is_not_private_atomicrmw(
257+
; CHECK-SAME: ptr [[FLAT_PTR:%.*]], i64 [[VAL:%.*]]) {
258+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[FLAT_PTR]])
259+
; CHECK-NEXT: [[NOT_IS_PRIVATE:%.*]] = xor i1 [[IS_PRIVATE]], true
260+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[NOT_IS_PRIVATE]])
261+
; CHECK-NEXT: [[RMW:%.*]] = atomicrmw sub ptr [[FLAT_PTR]], i64 [[VAL]] seq_cst, align 4
262+
; CHECK-NEXT: ret i64 [[RMW]]
263+
;
264+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %flat.ptr)
265+
%not.is.private = xor i1 %is.private, true
266+
tail call void @llvm.assume(i1 %not.is.private)
267+
%rmw = atomicrmw sub ptr %flat.ptr, i64 %val seq_cst, align 4
268+
ret i64 %rmw
269+
}
270+
271+
define float @contradictory_assume_after_gep_same_block(ptr %p) {
272+
; CHECK-LABEL: define float @contradictory_assume_after_gep_same_block(
273+
; CHECK-SAME: ptr [[P:%.*]]) {
274+
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[P]])
275+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_SHARED]])
276+
; CHECK-NEXT: [[WORKITEM_ID_X:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
277+
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[WORKITEM_ID_X]] to i64
278+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(3)
279+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds float, ptr addrspace(3) [[TMP1]], i64 [[IDXPROM]]
280+
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 [[IDXPROM]]
281+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[TMP2]])
282+
; CHECK-NEXT: tail call void @llvm.assume(i1 false)
283+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr addrspace(3) [[GEP]], align 4
284+
; CHECK-NEXT: ret float [[LOAD]]
285+
;
286+
%is.shared = call i1 @llvm.amdgcn.is.shared(ptr %p)
287+
tail call void @llvm.assume(i1 %is.shared)
288+
%workitem.id.x = tail call i32 @llvm.amdgcn.workitem.id.x()
289+
%idxprom = zext i32 %workitem.id.x to i64
290+
%gep = getelementptr inbounds float, ptr %p, i64 %idxprom
291+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %gep)
292+
tail call void @llvm.assume(i1 %is.private)
293+
%load = load float, ptr %gep, align 4
294+
ret float %load
295+
}
296+
297+
define float @contradictory_assume_argument_same_block(ptr %p) {
298+
; CHECK-LABEL: define float @contradictory_assume_argument_same_block(
299+
; CHECK-SAME: ptr [[P:%.*]]) {
300+
; CHECK-NEXT: [[IS_SHARED:%.*]] = call i1 @llvm.amdgcn.is.shared(ptr [[P]])
301+
; CHECK-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[P]])
302+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_SHARED]])
303+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[IS_PRIVATE]])
304+
; CHECK-NEXT: [[WORKITEM_ID_X:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
305+
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[WORKITEM_ID_X]] to i64
306+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(3)
307+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds float, ptr addrspace(3) [[TMP1]], i64 [[IDXPROM]]
308+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr addrspace(3) [[GEP]], align 4
309+
; CHECK-NEXT: ret float [[LOAD]]
310+
;
311+
%is.shared = call i1 @llvm.amdgcn.is.shared(ptr %p)
312+
%is.private = call i1 @llvm.amdgcn.is.private(ptr %p)
313+
tail call void @llvm.assume(i1 %is.shared)
314+
tail call void @llvm.assume(i1 %is.private)
315+
%workitem.id.x = tail call i32 @llvm.amdgcn.workitem.id.x()
316+
%idxprom = zext i32 %workitem.id.x to i64
317+
%gep = getelementptr inbounds float, ptr %p, i64 %idxprom
318+
%load = load float, ptr %gep, align 4
319+
ret float %load
320+
}
321+
130322
declare void @llvm.assume(i1)
131323
declare i1 @llvm.amdgcn.is.shared(ptr nocapture)
132324
declare i1 @llvm.amdgcn.is.private(ptr nocapture)

0 commit comments

Comments
 (0)