diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 46 |
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)); } |
