Skip to content

Commit 05e4ac2

Browse files
committedJun 29, 2017
[CodeGenPrepare] Don't create inttoptr for ni ptrs
Summary: Arguably non-integral pointers probably shouldn't show up here at all, but since the backend doesn't complain and this takes valid (according to the Verifier) IR and makes it invalid, make sure not to introduce any inttoptr instructions if we're dealing with non-integral pointers. Reviewed By: sanjoy Differential Revision: https://reviews.llvm.org/D33110 llvm-svn: 306737
1 parent f03096b commit 05e4ac2

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed
 

Diff for: ‎llvm/lib/CodeGen/CodeGenPrepare.cpp

+23-8
Original file line numberDiff line numberDiff line change
@@ -4400,14 +4400,16 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
44004400
// If the real base value actually came from an inttoptr, then the matcher
44014401
// will look through it and provide only the integer value. In that case,
44024402
// use it here.
4403-
if (!ResultPtr && AddrMode.BaseReg) {
4404-
ResultPtr =
4405-
Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(), "sunkaddr");
4406-
AddrMode.BaseReg = nullptr;
4407-
} else if (!ResultPtr && AddrMode.Scale == 1) {
4408-
ResultPtr =
4409-
Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(), "sunkaddr");
4410-
AddrMode.Scale = 0;
4403+
if (!DL->isNonIntegralPointerType(Addr->getType())) {
4404+
if (!ResultPtr && AddrMode.BaseReg) {
4405+
ResultPtr = Builder.CreateIntToPtr(AddrMode.BaseReg, Addr->getType(),
4406+
"sunkaddr");
4407+
AddrMode.BaseReg = nullptr;
4408+
} else if (!ResultPtr && AddrMode.Scale == 1) {
4409+
ResultPtr = Builder.CreateIntToPtr(AddrMode.ScaledReg, Addr->getType(),
4410+
"sunkaddr");
4411+
AddrMode.Scale = 0;
4412+
}
44114413
}
44124414

44134415
if (!ResultPtr &&
@@ -4488,6 +4490,19 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
44884490
SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
44894491
}
44904492
} else {
4493+
// We'd require a ptrtoint/inttoptr down the line, which we can't do for
4494+
// non-integral pointers, so in that case bail out now.
4495+
Type *BaseTy = AddrMode.BaseReg ? AddrMode.BaseReg->getType() : nullptr;
4496+
Type *ScaleTy = AddrMode.Scale ? AddrMode.ScaledReg->getType() : nullptr;
4497+
PointerType *BasePtrTy = dyn_cast_or_null<PointerType>(BaseTy);
4498+
PointerType *ScalePtrTy = dyn_cast_or_null<PointerType>(ScaleTy);
4499+
if (DL->isNonIntegralPointerType(Addr->getType()) ||
4500+
(BasePtrTy && DL->isNonIntegralPointerType(BasePtrTy)) ||
4501+
(ScalePtrTy && DL->isNonIntegralPointerType(ScalePtrTy)) ||
4502+
(AddrMode.BaseGV &&
4503+
DL->isNonIntegralPointerType(AddrMode.BaseGV->getType())))
4504+
return false;
4505+
44914506
DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode << " for "
44924507
<< *MemoryInst << "\n");
44934508
Type *IntPtrTy = DL->getIntPtrType(Addr->getType());

Diff for: ‎llvm/test/Transforms/CodeGenPrepare/nonintegral.ll

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
; RUN: opt -S -codegenprepare < %s | FileCheck %s
2+
; RUN: opt -S -codegenprepare -addr-sink-using-gep=false < %s | FileCheck %s
3+
4+
; This target data layout is modified to have a non-integral addrspace(1),
5+
; in order to verify that codegenprepare does not try to introduce illegal
6+
; inttoptrs.
7+
target datalayout =
8+
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-ni:1"
9+
target triple = "x86_64-unknown-linux-gnu"
10+
11+
define void @test_simple(i1 %cond, i64 addrspace(1)* %base) {
12+
; CHECK-LABEL: @test_simple
13+
; CHECK-NOT: inttoptr {{.*}} to i64 addrspace(1)*
14+
entry:
15+
%addr = getelementptr inbounds i64, i64 addrspace(1)* %base, i64 5
16+
%casted = bitcast i64 addrspace(1)* %addr to i32 addrspace(1)*
17+
br i1 %cond, label %if.then, label %fallthrough
18+
19+
if.then:
20+
%v = load i32, i32 addrspace(1)* %casted, align 4
21+
br label %fallthrough
22+
23+
fallthrough:
24+
ret void
25+
}
26+
27+
28+
define void @test_inttoptr_base(i1 %cond, i64 %base) {
29+
; CHECK-LABEL: @test_inttoptr_base
30+
; CHECK-NOT: inttoptr {{.*}} to i64 addrspace(1)*
31+
entry:
32+
; Doing the inttoptr in the integral addrspace(0) followed by an explicit
33+
; (frontend-introduced) addrspacecast is fine. We cannot however introduce
34+
; a direct inttoptr to addrspace(1)
35+
%baseptr = inttoptr i64 %base to i64*
36+
%baseptrni = addrspacecast i64 *%baseptr to i64 addrspace(1)*
37+
%addr = getelementptr inbounds i64, i64 addrspace(1)* %baseptrni, i64 5
38+
%casted = bitcast i64 addrspace(1)* %addr to i32 addrspace(1)*
39+
br i1 %cond, label %if.then, label %fallthrough
40+
41+
if.then:
42+
%v = load i32, i32 addrspace(1)* %casted, align 4
43+
br label %fallthrough
44+
45+
fallthrough:
46+
ret void
47+
}
48+
49+
define void @test_ptrtoint_base(i1 %cond, i64 addrspace(1)* %base) {
50+
; CHECK-LABEL: @test_ptrtoint_base
51+
; CHECK-NOT: ptrtoint addrspace(1)* {{.*}} to i64
52+
entry:
53+
; This one is inserted by the frontend, so it's fine. We're not allowed to
54+
; directly ptrtoint %base ourselves though
55+
%baseptr0 = addrspacecast i64 addrspace(1)* %base to i64*
56+
%toint = ptrtoint i64* %baseptr0 to i64
57+
%added = add i64 %toint, 8
58+
%toptr = inttoptr i64 %added to i64*
59+
%geped = getelementptr i64, i64* %toptr, i64 2
60+
br i1 %cond, label %if.then, label %fallthrough
61+
62+
if.then:
63+
%v = load i64, i64* %geped, align 4
64+
br label %fallthrough
65+
66+
fallthrough:
67+
ret void
68+
}

0 commit comments

Comments
 (0)
Please sign in to comment.