summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-08-27 05:16:04 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-08-27 05:16:04 +0000
commit54e97d5dc02867201f193f61be6edaaca8398d2c (patch)
tree2e50b3df1bce536a2e3dd271d8d0f855bf67228c /llvm/lib/Transforms
parentce46adb4f860e4075ecd1b6ee9b26c432e580194 (diff)
downloadbcm5719-llvm-54e97d5dc02867201f193f61be6edaaca8398d2c.tar.gz
bcm5719-llvm-54e97d5dc02867201f193f61be6edaaca8398d2c.zip
InstCombine: Optimize GEP's involving ptrtoint better
We supported transforming: (gep i8* X, -(ptrtoint Y)) to: (inttoptr (sub (ptrtoint X), (ptrtoint Y))) However, this only fired if 'X' had type i8*. Generalize this to support various types of different sizes. This results in much better CodeGen, especially for pointers to packed structs. llvm-svn: 216523
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index f01dca7fab8..46789711bc8 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1508,19 +1508,37 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GetElementPtrInst::Create(Src->getOperand(0), Indices, GEP.getName());
}
- // Canonicalize (gep i8* X, -(ptrtoint Y)) to (sub (ptrtoint X), (ptrtoint Y))
- // The GEP pattern is emitted by the SCEV expander for certain kinds of
- // pointer arithmetic.
- if (DL && GEP.getNumIndices() == 1 &&
- match(GEP.getOperand(1), m_Neg(m_PtrToInt(m_Value())))) {
+ if (DL && GEP.getNumIndices() == 1) {
unsigned AS = GEP.getPointerAddressSpace();
- if (GEP.getType() == Builder->getInt8PtrTy(AS) &&
- GEP.getOperand(1)->getType()->getScalarSizeInBits() ==
+ if (GEP.getOperand(1)->getType()->getScalarSizeInBits() ==
DL->getPointerSizeInBits(AS)) {
- Operator *Index = cast<Operator>(GEP.getOperand(1));
- Value *PtrToInt = Builder->CreatePtrToInt(PtrOp, Index->getType());
- Value *NewSub = Builder->CreateSub(PtrToInt, Index->getOperand(1));
- return CastInst::Create(Instruction::IntToPtr, NewSub, GEP.getType());
+ Type *PtrTy = GEP.getPointerOperandType();
+ Type *Ty = PtrTy->getPointerElementType();
+ uint64_t TyAllocSize = DL->getTypeAllocSize(Ty);
+
+ // Canonicalize (gep i8* X, -(ptrtoint Y)) to (sub (ptrtoint X), (ptrtoint Y))
+ // The GEP pattern is emitted by the SCEV expander for certain kinds of
+ // pointer arithmetic.
+ uint64_t C;
+ Value *NegPtrToInt = nullptr;
+ if (TyAllocSize == 1) {
+ NegPtrToInt = GEP.getOperand(1);
+ } else if (match(GEP.getOperand(1),
+ m_AShr(m_Value(NegPtrToInt), m_ConstantInt(C)))) {
+ if (TyAllocSize != 1ULL << C)
+ NegPtrToInt = nullptr;
+ } else if (match(GEP.getOperand(1),
+ m_SDiv(m_Value(NegPtrToInt), m_ConstantInt(C)))) {
+ if (TyAllocSize != C)
+ NegPtrToInt = nullptr;
+ }
+
+ if (NegPtrToInt && match(NegPtrToInt, m_Neg(m_PtrToInt(m_Value())))) {
+ Operator *Index = cast<Operator>(NegPtrToInt);
+ Value *PtrToInt = Builder->CreatePtrToInt(PtrOp, Index->getType());
+ Value *NewSub = Builder->CreateSub(PtrToInt, Index->getOperand(1));
+ return CastInst::Create(Instruction::IntToPtr, NewSub, GEP.getType());
+ }
}
}
OpenPOWER on IntegriCloud