Skip to content

Commit fcdf8f2

Browse files
maleadtvchuravy
authored andcommitted
Don't sink ptrtoint/inttoptr sequences into non-noop addrspacecasts.
Differential Revision: https://reviews.llvm.org/D92210 (cherry picked from commit 822b19a)
1 parent f252e17 commit fcdf8f2

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
@@ -5044,18 +5044,29 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
50445044
WeakTrackingVH SunkAddrVH = SunkAddrs[Addr];
50455045

50465046
Value * SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr;
5047+
Type *IntPtrTy = DL->getIntPtrType(Addr->getType());
50475048
if (SunkAddr) {
50485049
LLVM_DEBUG(dbgs() << "CGP: Reusing nonlocal addrmode: " << AddrMode
50495050
<< " for " << *MemoryInst << "\n");
5050-
if (SunkAddr->getType() != Addr->getType())
5051-
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5051+
if (SunkAddr->getType() != Addr->getType()) {
5052+
// Even though we only considered no-op addrspacecasts,
5053+
// semantically-meaningful conversions may still be present due to
5054+
// ptrtoint/inttoptr sequences.
5055+
if (SunkAddr->getType()->getPointerAddressSpace() !=
5056+
Addr->getType()->getPointerAddressSpace() &&
5057+
!DL->isNonIntegralPointerType(Addr->getType())) {
5058+
SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy, "sunkaddr");
5059+
SunkAddr =
5060+
Builder.CreateIntToPtr(SunkAddr, Addr->getType(), "sunkaddr");
5061+
} else
5062+
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5063+
}
50525064
} else if (AddrSinkUsingGEPs || (!AddrSinkUsingGEPs.getNumOccurrences() &&
50535065
SubtargetInfo->addrSinkUsingGEPs())) {
50545066
// By default, we use the GEP-based method when AA is used later. This
50555067
// prevents new inttoptr/ptrtoint pairs from degrading AA capabilities.
50565068
LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode
50575069
<< " for " << *MemoryInst << "\n");
5058-
Type *IntPtrTy = DL->getIntPtrType(Addr->getType());
50595070
Value *ResultPtr = nullptr, *ResultIndex = nullptr;
50605071

50615072
// First, find the pointer.
@@ -5184,8 +5195,19 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
51845195
: Builder.CreateGEP(I8Ty, ResultPtr, ResultIndex, "sunkaddr");
51855196
}
51865197

5187-
if (SunkAddr->getType() != Addr->getType())
5188-
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5198+
if (SunkAddr->getType() != Addr->getType()) {
5199+
// Even though we only considered no-op addrspacecasts,
5200+
// semantically-meaningful conversions may still be present due to
5201+
// ptrtoint/inttoptr sequences.
5202+
if (SunkAddr->getType()->getPointerAddressSpace() !=
5203+
Addr->getType()->getPointerAddressSpace() &&
5204+
!DL->isNonIntegralPointerType(Addr->getType())) {
5205+
SunkAddr = Builder.CreatePtrToInt(SunkAddr, IntPtrTy, "sunkaddr");
5206+
SunkAddr =
5207+
Builder.CreateIntToPtr(SunkAddr, Addr->getType(), "sunkaddr");
5208+
} else
5209+
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
5210+
}
51895211
}
51905212
} else {
51915213
// 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)