Skip to content

Commit 52fbb78

Browse files
committed
InferAddressSpaces: Fix assert on inferred source for inttoptr/ptrtoint
If we had some source value we could infer an address space from that went through a ptrtoint/inttoptr pair, this would fail since bitcast can't change the address space. Fixes issue 53665.
1 parent e9c0720 commit 52fbb78

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,10 +655,13 @@ Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
655655
case Instruction::IntToPtr: {
656656
assert(isNoopPtrIntCastPair(cast<Operator>(I), *DL, TTI));
657657
Value *Src = cast<Operator>(I->getOperand(0))->getOperand(0);
658-
assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
659-
if (Src->getType() != NewPtrType)
660-
return new BitCastInst(Src, NewPtrType);
661-
return Src;
658+
if (Src->getType() == NewPtrType)
659+
return Src;
660+
661+
// If we had a no-op inttoptr/ptrtoint pair, we may still have inferred a
662+
// source address space from a generic pointer source need to insert a cast
663+
// back.
664+
return CastInst::CreatePointerBitCastOrAddrSpaceCast(Src, NewPtrType);
662665
}
663666
default:
664667
llvm_unreachable("Unexpected opcode");
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces -o - %s | FileCheck %s
3+
; https://github.com/llvm/llvm-project/issues/53665
4+
5+
define i32 @addrspacecast_ptrtoint_inttoptr(i8 addrspace(1)* %arg) {
6+
; CHECK-LABEL: @addrspacecast_ptrtoint_inttoptr(
7+
; CHECK-NEXT: bb:
8+
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8 addrspace(1)* [[ARG:%.*]] to i32 addrspace(1)*
9+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32 addrspace(1)* [[TMP0]], align 4
10+
; CHECK-NEXT: ret i32 [[LOAD]]
11+
;
12+
bb:
13+
%asc = addrspacecast i8 addrspace(1)* %arg to i8*
14+
%p2i = ptrtoint i8* %asc to i64
15+
%i2p = inttoptr i64 %p2i to i32*
16+
%load = load i32, i32* %i2p
17+
ret i32 %load
18+
}
19+
20+
define i32 @assumed_ptrtoint_inttoptr(i8* %arg) {
21+
bb:
22+
%is.priv = call i1 @llvm.amdgcn.is.private(i8* %arg)
23+
%not.is.priv = xor i1 %is.priv, -1
24+
%is.shared = call i1 @llvm.amdgcn.is.shared(i8* %arg)
25+
%not.is.shared = xor i1 %is.shared, -1
26+
%and = and i1 %not.is.priv, %not.is.shared
27+
tail call void @llvm.assume(i1 %and)
28+
%p2i = ptrtoint i8* %arg to i64
29+
%i2p = inttoptr i64 %p2i to i32*
30+
%load = load i32, i32* %i2p
31+
ret i32 %load
32+
}
33+
34+
define i32 @addrspacecast_ptrtoint_inttptr_nontrivial(i8 addrspace(3)* %arg) {
35+
; CHECK-LABEL: @addrspacecast_ptrtoint_inttptr_nontrivial(
36+
; CHECK-NEXT: bb:
37+
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8 addrspace(3)* [[ARG:%.*]] to i32 addrspace(3)*
38+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32 addrspace(3)* [[TMP0]], align 4
39+
; CHECK-NEXT: ret i32 [[LOAD]]
40+
;
41+
bb:
42+
%asc = addrspacecast i8 addrspace(3)* %arg to i8*
43+
%p2i = ptrtoint i8* %asc to i64
44+
%i2p = inttoptr i64 %p2i to i32*
45+
%load = load i32, i32* %i2p
46+
ret i32 %load
47+
}
48+
49+
declare void @llvm.assume(i1 noundef) #0
50+
declare i1 @llvm.amdgcn.is.shared(i8* nocapture) #1
51+
declare i1 @llvm.amdgcn.is.private(i8* nocapture) #1
52+
53+
attributes #0 = { inaccessiblememonly nofree nosync nounwind willreturn }
54+
attributes #1 = { nounwind readnone speculatable willreturn }

0 commit comments

Comments
 (0)