Skip to content

Commit 822b19a

Browse files
maleadtvchuravy
authored andcommitted
Don't sink ptrtoint/inttoptr sequences into non-noop addrspacecasts.
Differential Revision: https://reviews.llvm.org/D92210
1 parent 6104e14 commit 822b19a

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5224,18 +5224,29 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
52245224
WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
52255225

52265226
Value * SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr;
5227+
Type *IntPtrTy = DL->getIntPtrType(Addr->getType());
52275228
if (SunkAddr) {
52285229
LLVM_DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode
52295230
<< " for " << *MemoryInst << "\n");
5230-
if (SunkAddr->getType() != Addr->getType())
5231-
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5231+
if (SunkAddr->getType() != Addr->getType()) {
5232+
// Even though we only considered no-op addrspacecasts,
5233+
// semantically-meaningful conversions may still be present due to
5234+
// ptrtoint/inttoptr sequences.
5235+
if (SunkAddr->getType()->getPointerAddressSpace() !=
5236+
Addr->getType()->getPointerAddressSpace() &&
5237+
!DL->isNonIntegralPointerType(Addr->getType())) {
5238+
SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy, "sunkaddr");
5239+
SunkAddr =
5240+
Builder.CreateIntToPtr(SunkAddr, Addr->getType(), "sunkaddr");
5241+
} else
5242+
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5243+
}
52325244
} else if (AddrSinkUsingGEPs || (!AddrSinkUsingGEPs.getNumOccurrences() &&
52335245
SubtargetInfo->addrSinkUsingGEPs())) {
52345246
// By default, we use the GEP-based method when AA is used later. This
52355247
// prevents new inttoptr/ptrtoint pairs from degrading AA capabilities.
52365248
LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode
52375249
<< " for " << *MemoryInst << "\n");
5238-
Type *IntPtrTy = DL->getIntPtrType(Addr->getType());
52395250
Value *ResultPtr = nullptr, *ResultIndex = nullptr;
52405251

52415252
// First, find the pointer.
@@ -5364,8 +5375,19 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
53645375
: Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr");
53655376
}
53665377

5367-
if (SunkAddr->getType() != Addr->getType())
5368-
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5378+
if (SunkAddr->getType() != Addr->getType()) {
5379+
// Even though we only considered no-op addrspacecasts,
5380+
// semantically-meaningful conversions may still be present due to
5381+
// ptrtoint/inttoptr sequences.
5382+
if (SunkAddr->getType()->getPointerAddressSpace() !=
5383+
Addr->getType()->getPointerAddressSpace() &&
5384+
!DL->isNonIntegralPointerType(Addr->getType())) {
5385+
SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy, "sunkaddr");
5386+
SunkAddr =
5387+
Builder.CreateIntToPtr(SunkAddr, Addr->getType(), "sunkaddr");
5388+
} else
5389+
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5390+
}
53695391
}
53705392
} else {
53715393
// We'd require a ptrtoint/inttoptr down the line, which we can't do for
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: opt -S -codegenprepare < %s | FileCheck %s
2+
3+
target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
4+
target triple = "nvptx64-nvidia-cuda"
5+
6+
7+
; ptrtoint/inttoptr combinations can introduce semantically-meaningful address space casts
8+
; which we can't sink into an addrspacecast
9+
10+
; CHECK-LABEL: @test
11+
define void @test(i8* %input_ptr) {
12+
; CHECK-LABEL: l1:
13+
; CHECK-NOT: addrspacecast
14+
%intptr = ptrtoint i8* %input_ptr to i64
15+
%ptr = inttoptr i64 %intptr to i32 addrspace(3)*
16+
17+
br label %l1
18+
l1:
19+
20+
store atomic i32 1, i32 addrspace(3)* %ptr unordered, align 4
21+
ret void
22+
}
23+
24+
25+
; we still should be able to look through multiple sequences of inttoptr/ptrtoint
26+
27+
; CHECK-LABEL: @test2
28+
define void @test2(i8* %input_ptr) {
29+
; CHECK-LABEL: l2:
30+
; CHECK: bitcast
31+
; CHECK-NEXT: store
32+
%intptr = ptrtoint i8* %input_ptr to i64
33+
%ptr = inttoptr i64 %intptr to i32 addrspace(3)*
34+
35+
%intptr2 = ptrtoint i32 addrspace(3)* %ptr to i64
36+
%ptr2 = inttoptr i64 %intptr2 to i32*
37+
38+
br label %l2
39+
l2:
40+
41+
store atomic i32 1, i32* %ptr2 unordered, align 4
42+
ret void
43+
}

0 commit comments

Comments
 (0)