Skip to content

Commit 48ae8cd

Browse files
committed
[Attributor] Don't replace AddrSpaceCast with ConstantPointerNull
`ConstantPointerNull` represents a pointer with value 0, but it doesn’t necessarily mean a nullptr. `ptr addrspace(x) null` is not the same as `addrspacecast (ptr null to ptr addrspace(x))` if the nullptr in AS x is not zero. Therefore, we can't simply replace it. Fixes #115083.
1 parent 1138983 commit 48ae8cd

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ Value *AA::getWithType(Value &V, Type &Ty) {
325325
if (isa<UndefValue>(V))
326326
return UndefValue::get(&Ty);
327327
if (auto *C = dyn_cast<Constant>(&V)) {
328-
if (C->isNullValue())
328+
if (C->isNullValue() && !Ty.isPointerTy())
329329
return Constant::getNullValue(&Ty);
330330
if (C->getType()->isPointerTy() && Ty.isPointerTy())
331331
return ConstantExpr::getPointerCast(C, &Ty);

llvm/test/CodeGen/AMDGPU/addrspacecast.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ define amdgpu_kernel void @use_flat_to_constant_addrspacecast(ptr %ptr) #0 {
217217
; HSA-LABEL: {{^}}cast_0_group_to_flat_addrspacecast:
218218

219219
; HSA-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
220-
; HSA-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0{{$}}
220+
; HSA-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], s{{[0-9]+}}
221221
; HSA-DAG: v_mov_b32_e32 v[[K:[0-9]+]], 7{{$}}
222222
; HSA: flat_store_dword v[[[LO]]:[[HI]]], v[[K]]
223223
define amdgpu_kernel void @cast_0_group_to_flat_addrspacecast() #0 {
@@ -260,7 +260,7 @@ define amdgpu_kernel void @cast_neg1_flat_to_group_addrspacecast() #0 {
260260
; FIXME: Shouldn't need to enable queue ptr
261261
; HSA-LABEL: {{^}}cast_0_private_to_flat_addrspacecast:
262262
; HSA-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0{{$}}
263-
; HSA-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0{{$}}
263+
; HSA-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], s{{[0-9]+}}
264264
; HSA-DAG: v_mov_b32_e32 v[[K:[0-9]+]], 7{{$}}
265265
; HSA: flat_store_dword v[[[LO]]:[[HI]]], v[[K]]
266266
define amdgpu_kernel void @cast_0_private_to_flat_addrspacecast() #0 {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=attributor %s -o - | FileCheck %s
3+
4+
define i32 @addrspacecast_ptr(ptr %p0, ptr addrspace(5) %p5) {
5+
; CHECK-LABEL: define i32 @addrspacecast_ptr(
6+
; CHECK-SAME: ptr nofree readonly captures(none) [[P0:%.*]], ptr addrspace(5) nofree readonly [[P5:%.*]]) #[[ATTR0:[0-9]+]] {
7+
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq ptr addrspace(5) [[P5]], addrspacecast (ptr null to ptr addrspace(5))
8+
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ICMP]], ptr [[P0]], ptr null
9+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[SELECT]], align 4
10+
; CHECK-NEXT: ret i32 [[LOAD]]
11+
;
12+
%icmp = icmp eq ptr addrspace(5) %p5, addrspacecast (ptr null to ptr addrspace(5))
13+
%select = select i1 %icmp, ptr %p0, ptr null
14+
%load = load i32, ptr %select, align 4
15+
ret i32 %load
16+
}
17+
18+
define i32 @vec_addrspacecast_ptr(ptr %p0, ptr %p1, <2 x ptr addrspace(5)> %ptrvec) {
19+
; CHECK-LABEL: define i32 @vec_addrspacecast_ptr(
20+
; CHECK-SAME: ptr nofree readonly captures(none) [[P0:%.*]], ptr nofree noundef nonnull readonly align 16 captures(none) dereferenceable(16) [[P1:%.*]], <2 x ptr addrspace(5)> [[PTRVEC:%.*]]) #[[ATTR0]] {
21+
; CHECK-NEXT: [[LOADVEC:%.*]] = load <2 x ptr addrspace(5)>, ptr [[P1]], align 16
22+
; CHECK-NEXT: [[ICMPVEC:%.*]] = icmp eq <2 x ptr addrspace(5)> [[LOADVEC]], <ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5)), ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))>
23+
; CHECK-NEXT: [[ICMP:%.*]] = extractelement <2 x i1> [[ICMPVEC]], i32 1
24+
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ICMP]], ptr [[P0]], ptr null
25+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[SELECT]], align 4
26+
; CHECK-NEXT: ret i32 [[LOAD]]
27+
;
28+
%loadvec = load <2 x ptr addrspace(5)>, ptr %p1, align 16
29+
%icmpvec = icmp eq <2 x ptr addrspace(5)> %loadvec, <ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5)), ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))>
30+
%icmp = extractelement <2 x i1> %icmpvec, i32 1
31+
%select = select i1 %icmp, ptr %p0, ptr null
32+
%load = load i32, ptr %select, align 4
33+
ret i32 %load
34+
}
35+
36+
define i32 @addrspacecast_vec_as1_ptr(ptr %p0, ptr %p1, <2 x ptr addrspace(5)> %ptrvec) {
37+
; CHECK-LABEL: define i32 @addrspacecast_vec_as1_ptr(
38+
; CHECK-SAME: ptr nofree readonly captures(none) [[P0:%.*]], ptr nofree noundef nonnull readonly align 16 captures(none) dereferenceable(16) [[P1:%.*]], <2 x ptr addrspace(5)> [[PTRVEC:%.*]]) #[[ATTR0]] {
39+
; CHECK-NEXT: [[LOADVEC:%.*]] = load <2 x ptr addrspace(5)>, ptr [[P1]], align 16
40+
; CHECK-NEXT: [[ICMPVEC:%.*]] = icmp eq <2 x ptr addrspace(5)> [[LOADVEC]], <ptr addrspace(5) addrspacecast (ptr addrspace(1) null to ptr addrspace(5)), ptr addrspace(5) addrspacecast (ptr addrspace(1) null to ptr addrspace(5))>
41+
; CHECK-NEXT: [[ICMP:%.*]] = extractelement <2 x i1> [[ICMPVEC]], i32 1
42+
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ICMP]], ptr [[P0]], ptr null
43+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[SELECT]], align 4
44+
; CHECK-NEXT: ret i32 [[LOAD]]
45+
;
46+
%loadvec = load <2 x ptr addrspace(5)>, ptr %p1, align 16
47+
%icmpvec = icmp eq <2 x ptr addrspace(5)> %loadvec, addrspacecast (<2 x ptr addrspace(1)> zeroinitializer to <2 x ptr addrspace(5)>)
48+
%icmp = extractelement <2 x i1> %icmpvec, i32 1
49+
%select = select i1 %icmp, ptr %p0, ptr null
50+
%load = load i32, ptr %select, align 4
51+
ret i32 %load
52+
}
53+
54+
define i32 @addrspacecast_vec_ptr(ptr %p0, ptr %p1, <2 x ptr addrspace(5)> %ptrvec) {
55+
; CHECK-LABEL: define i32 @addrspacecast_vec_ptr(
56+
; CHECK-SAME: ptr nofree readonly captures(none) [[P0:%.*]], ptr nofree noundef nonnull readonly align 16 captures(none) dereferenceable(16) [[P1:%.*]], <2 x ptr addrspace(5)> [[PTRVEC:%.*]]) #[[ATTR0]] {
57+
; CHECK-NEXT: [[LOADVEC:%.*]] = load <2 x ptr addrspace(5)>, ptr [[P1]], align 16
58+
; CHECK-NEXT: [[ICMPVEC:%.*]] = icmp eq <2 x ptr addrspace(5)> [[LOADVEC]], <ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5)), ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))>
59+
; CHECK-NEXT: [[ICMP:%.*]] = extractelement <2 x i1> [[ICMPVEC]], i32 1
60+
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ICMP]], ptr [[P0]], ptr null
61+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[SELECT]], align 4
62+
; CHECK-NEXT: ret i32 [[LOAD]]
63+
;
64+
%loadvec = load <2 x ptr addrspace(5)>, ptr %p1, align 16
65+
%icmpvec = icmp eq <2 x ptr addrspace(5)> %loadvec, addrspacecast (<2 x ptr> zeroinitializer to <2 x ptr addrspace(5)>)
66+
%icmp = extractelement <2 x i1> %icmpvec, i32 1
67+
%select = select i1 %icmp, ptr %p0, ptr null
68+
%load = load i32, ptr %select, align 4
69+
ret i32 %load
70+
}
71+

0 commit comments

Comments
 (0)