mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Implement PR1795, an instcombine hack for forming GEPs with integer pointer arithmetic.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45745 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4a83e963b3
commit
f9d9e45225
@ -210,7 +210,7 @@ namespace {
|
||||
Instruction *visitUIToFP(CastInst &CI);
|
||||
Instruction *visitSIToFP(CastInst &CI);
|
||||
Instruction *visitPtrToInt(CastInst &CI);
|
||||
Instruction *visitIntToPtr(CastInst &CI);
|
||||
Instruction *visitIntToPtr(IntToPtrInst &CI);
|
||||
Instruction *visitBitCast(BitCastInst &CI);
|
||||
Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI,
|
||||
Instruction *FI);
|
||||
@ -7148,8 +7148,58 @@ Instruction *InstCombiner::visitPtrToInt(CastInst &CI) {
|
||||
return commonPointerCastTransforms(CI);
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitIntToPtr(CastInst &CI) {
|
||||
return commonCastTransforms(CI);
|
||||
Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
|
||||
if (Instruction *I = commonCastTransforms(CI))
|
||||
return I;
|
||||
|
||||
const Type *DestPointee = cast<PointerType>(CI.getType())->getElementType();
|
||||
if (!DestPointee->isSized()) return 0;
|
||||
|
||||
// If this is inttoptr(add (ptrtoint x), cst), try to turn this into a GEP.
|
||||
ConstantInt *Cst;
|
||||
Value *X;
|
||||
if (match(CI.getOperand(0), m_Add(m_Cast<PtrToIntInst>(m_Value(X)),
|
||||
m_ConstantInt(Cst)))) {
|
||||
// If the source and destination operands have the same type, see if this
|
||||
// is a single-index GEP.
|
||||
if (X->getType() == CI.getType()) {
|
||||
// Get the size of the pointee type.
|
||||
uint64_t Size = TD->getABITypeSizeInBits(DestPointee);
|
||||
|
||||
// Convert the constant to intptr type.
|
||||
APInt Offset = Cst->getValue();
|
||||
Offset.sextOrTrunc(TD->getPointerSizeInBits());
|
||||
|
||||
// If Offset is evenly divisible by Size, we can do this xform.
|
||||
if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
|
||||
Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
|
||||
return new GetElementPtrInst(X, ConstantInt::get(Offset));
|
||||
}
|
||||
}
|
||||
// TODO: Could handle other cases, e.g. where add is indexing into field of
|
||||
// struct etc.
|
||||
} else if (CI.getOperand(0)->hasOneUse() &&
|
||||
match(CI.getOperand(0), m_Add(m_Value(X), m_ConstantInt(Cst)))) {
|
||||
// Otherwise, if this is inttoptr(add x, cst), try to turn this into an
|
||||
// "inttoptr+GEP" instead of "add+intptr".
|
||||
|
||||
// Get the size of the pointee type.
|
||||
uint64_t Size = TD->getABITypeSize(DestPointee);
|
||||
|
||||
// Convert the constant to intptr type.
|
||||
APInt Offset = Cst->getValue();
|
||||
Offset.sextOrTrunc(TD->getPointerSizeInBits());
|
||||
|
||||
// If Offset is evenly divisible by Size, we can do this xform.
|
||||
if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
|
||||
Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
|
||||
|
||||
Instruction *P = InsertNewInstBefore(new IntToPtrInst(X, CI.getType(),
|
||||
"tmp"), CI);
|
||||
return new GetElementPtrInst(P, ConstantInt::get(Offset), "tmp");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
|
||||
|
@ -1,6 +1,10 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
|
||||
; RUN: grep -v OK | not grep add
|
||||
|
||||
;; Target triple for gep raising case below.
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
define i64 @test1(i64 %A, i32 %B) {
|
||||
%tmp12 = zext i32 %B to i64
|
||||
%tmp3 = shl i64 %tmp12, 32
|
||||
@ -9,3 +13,19 @@ define i64 @test1(i64 %A, i32 %B) {
|
||||
ret i64 %tmp6
|
||||
}
|
||||
|
||||
; PR1795
|
||||
define void @test2(i32 %.val24) {
|
||||
EntryBlock:
|
||||
add i32 %.val24, -12
|
||||
inttoptr i32 %0 to i32*
|
||||
store i32 1, i32* %1
|
||||
add i32 %.val24, -16
|
||||
inttoptr i32 %2 to i32*
|
||||
getelementptr i32* %3, i32 1
|
||||
load i32* %4
|
||||
tail call i32 @callee( i32 %5 )
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @callee(i32)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user