summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp46
1 files changed, 27 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 0d96d461941c..2aecedc51f03 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -206,7 +206,7 @@ Value *InstCombinerImpl::EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP) {
!GEP->getSourceElementType()->isIntegerTy(8)) {
replaceInstUsesWith(
*Inst, Builder.CreateGEP(Builder.getInt8Ty(), GEP->getPointerOperand(),
- Offset, "", GEP->isInBounds()));
+ Offset, "", GEP->getNoWrapFlags()));
eraseInstFromFunction(*Inst);
}
return Offset;
@@ -642,9 +642,11 @@ getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op,
RHS = Op->getOperand(1);
if (TopOpcode == Instruction::Add || TopOpcode == Instruction::Sub) {
Constant *C;
- if (match(Op, m_Shl(m_Value(), m_Constant(C)))) {
+ if (match(Op, m_Shl(m_Value(), m_ImmConstant(C)))) {
// X << C --> X * (1 << C)
- RHS = ConstantExpr::getShl(ConstantInt::get(Op->getType(), 1), C);
+ RHS = ConstantFoldBinaryInstruction(
+ Instruction::Shl, ConstantInt::get(Op->getType(), 1), C);
+ assert(RHS && "Constant folding of immediate constants failed");
return Instruction::Mul;
}
// TODO: We can add other conversions e.g. shr => div etc.
@@ -872,7 +874,7 @@ Instruction *InstCombinerImpl::tryFoldInstWithCtpopWithNot(Instruction *I) {
// -> (arithmetic_shift Binop1((not X), Y), Amt)
Instruction *InstCombinerImpl::foldBinOpShiftWithShift(BinaryOperator &I) {
- const DataLayout &DL = I.getModule()->getDataLayout();
+ const DataLayout &DL = I.getDataLayout();
auto IsValidBinOpc = [](unsigned Opc) {
switch (Opc) {
default:
@@ -1668,7 +1670,7 @@ static Constant *constantFoldOperationIntoSelectOperand(Instruction &I,
ConstOps.push_back(C);
}
- return ConstantFoldInstOperands(&I, ConstOps, I.getModule()->getDataLayout());
+ return ConstantFoldInstOperands(&I, ConstOps, I.getDataLayout());
}
static Value *foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI,
@@ -2330,10 +2332,10 @@ static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
// Propagate 'inbounds' and metadata from existing instructions.
// Note: using IRBuilder to create the constants for efficiency.
SmallVector<Value *, 4> IndexC(GEP.indices());
- bool IsInBounds = GEP.isInBounds();
+ GEPNoWrapFlags NW = GEP.getNoWrapFlags();
Type *Ty = GEP.getSourceElementType();
- Value *NewTrueC = Builder.CreateGEP(Ty, TrueC, IndexC, "", IsInBounds);
- Value *NewFalseC = Builder.CreateGEP(Ty, FalseC, IndexC, "", IsInBounds);
+ Value *NewTrueC = Builder.CreateGEP(Ty, TrueC, IndexC, "", NW);
+ Value *NewFalseC = Builder.CreateGEP(Ty, FalseC, IndexC, "", NW);
return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
}
@@ -2785,9 +2787,16 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GEP.getNoWrapFlags()));
}
- // Canonicalize scalable GEPs to an explicit offset using the llvm.vscale
- // intrinsic. This has better support in BasicAA.
- if (GEPEltType->isScalableTy()) {
+ // Canonicalize
+ // - scalable GEPs to an explicit offset using the llvm.vscale intrinsic.
+ // This has better support in BasicAA.
+ // - gep i32 p, mul(O, C) -> gep i8, p, mul(O, C*4) to fold the two
+ // multiplies together.
+ if (GEPEltType->isScalableTy() ||
+ (!GEPEltType->isIntegerTy(8) && GEP.getNumIndices() == 1 &&
+ match(GEP.getOperand(1),
+ m_OneUse(m_CombineOr(m_Mul(m_Value(), m_ConstantInt()),
+ m_Shl(m_Value(), m_ConstantInt())))))) {
Value *Offset = EmitGEPOffset(cast<GEPOperator>(&GEP));
return replaceInstUsesWith(
GEP, Builder.CreatePtrAdd(PtrOp, Offset, "", GEP.isInBounds()));
@@ -2939,10 +2948,9 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
m_SpecificInt(countr_zero(TyAllocSize)))))) ||
match(GEP.getOperand(1),
m_Exact(m_IDiv(m_Value(V), m_SpecificInt(TyAllocSize))))) {
- GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
- Builder.getInt8Ty(), GEP.getPointerOperand(), V);
- NewGEP->setIsInBounds(GEP.isInBounds());
- return NewGEP;
+ return GetElementPtrInst::Create(Builder.getInt8Ty(),
+ GEP.getPointerOperand(), V,
+ GEP.getNoWrapFlags());
}
}
}
@@ -2973,10 +2981,10 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
cast<OverflowingBinaryOperator>(GEP.getOperand(1))->hasNoSignedWrap(),
Idx1, Idx2);
auto *NewPtr =
- Builder.CreateGEP(GEP.getResultElementType(), GEP.getPointerOperand(),
+ Builder.CreateGEP(GEP.getSourceElementType(), GEP.getPointerOperand(),
Idx1, "", IsInBounds);
return replaceInstUsesWith(
- GEP, Builder.CreateGEP(GEP.getResultElementType(), NewPtr, Idx2, "",
+ GEP, Builder.CreateGEP(GEP.getSourceElementType(), NewPtr, Idx2, "",
IsInBounds));
}
ConstantInt *C;
@@ -2991,12 +2999,12 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
bool IsInBounds = CanPreserveInBounds(
/*IsNSW=*/true, Idx1, C);
auto *NewPtr = Builder.CreateGEP(
- GEP.getResultElementType(), GEP.getPointerOperand(),
+ GEP.getSourceElementType(), GEP.getPointerOperand(),
Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()), "",
IsInBounds);
return replaceInstUsesWith(
GEP,
- Builder.CreateGEP(GEP.getResultElementType(), NewPtr,
+ Builder.CreateGEP(GEP.getSourceElementType(), NewPtr,
Builder.CreateSExt(C, GEP.getOperand(1)->getType()),
"", IsInBounds));
}