// Implementation of r = rand (); a = b - r; a = a - c; a = a + r void Substitution::subRand2(BinaryOperator *bo) { BinaryOperator *op = NULL; if (bo->getOpcode() == Instruction::Sub) { Type *ty = bo->getType(); ConstantInt *co = (ConstantInt *)ConstantInt::get(ty, llvm::cryptoutils->get_uint64_t()); op = BinaryOperator::Create(Instruction::Sub, bo->getOperand(0), co, "", bo); op = BinaryOperator::Create(Instruction::Sub, op, bo->getOperand(1), "", bo); op = BinaryOperator::Create(Instruction::Add, op, co, "", bo); // Check signed wrap op->setHasNoSignedWrap(bo->hasNoSignedWrap()); op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap()); bo->replaceAllUsesWith(op); } /* else { Type *ty = bo->getType(); ConstantFP *co = (ConstantFP*)ConstantFP::get(ty,(float)llvm::cryptoutils->get_uint64_t()); op = BinaryOperator::Create(Instruction::FSub,bo->getOperand(0),co,"",bo); op = BinaryOperator::Create(Instruction::FSub,op,bo->getOperand(1),"",bo); op = BinaryOperator::Create(Instruction::FAdd,op,co,"",bo); } */ }
Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) { if (ChainIndex == 0) { assert(isa<ConstantInt>(UserChain[ChainIndex])); return ConstantInt::getNullValue(UserChain[ChainIndex]->getType()); } BinaryOperator *BO = cast<BinaryOperator>(UserChain[ChainIndex]); unsigned OpNo = (BO->getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1); assert(BO->getOperand(OpNo) == UserChain[ChainIndex - 1]); Value *NextInChain = removeConstOffset(ChainIndex - 1); Value *TheOther = BO->getOperand(1 - OpNo); // If NextInChain is 0 and not the LHS of a sub, we can simplify the // sub-expression to be just TheOther. if (ConstantInt *CI = dyn_cast<ConstantInt>(NextInChain)) { if (CI->isZero() && !(BO->getOpcode() == Instruction::Sub && OpNo == 0)) return TheOther; } if (BO->getOpcode() == Instruction::Or) { // Rebuild "or" as "add", because "or" may be invalid for the new // epxression. // // For instance, given // a | (b + 5) where a and b + 5 have no common bits, // we can extract 5 as the constant offset. // // However, reusing the "or" in the new index would give us // (a | b) + 5 // which does not equal a | (b + 5). // // Replacing the "or" with "add" is fine, because // a | (b + 5) = a + (b + 5) = (a + b) + 5 if (OpNo == 0) { return BinaryOperator::CreateAdd(NextInChain, TheOther, BO->getName(), IP); } else { return BinaryOperator::CreateAdd(TheOther, NextInChain, BO->getName(), IP); } } // We can reuse BO in this case, because the new expression shares the same // instruction type and BO is used at most once. assert(BO->getNumUses() <= 1 && "distributeExtsAndCloneChain clones each BinaryOperator in " "UserChain, so no one should be used more than " "once"); BO->setOperand(OpNo, NextInChain); BO->setHasNoSignedWrap(false); BO->setHasNoUnsignedWrap(false); // Make sure it appears after all instructions we've inserted so far. BO->moveBefore(IP); return BO; }
Value *AMDGPUCodeGenPrepare::copyFlags( const BinaryOperator &I, Value *V) const { assert(isa<BinaryOperator>(V) && "V must be binary operation"); BinaryOperator *BinOp = cast<BinaryOperator>(V); if (isa<OverflowingBinaryOperator>(BinOp)) { BinOp->setHasNoSignedWrap(I.hasNoSignedWrap()); BinOp->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); } else if (isa<PossiblyExactOperator>(BinOp)) BinOp->setIsExact(I.isExact()); return V; }
// Implementation of a = b + (-c) void Substitution::subNeg(BinaryOperator *bo) { BinaryOperator *op = NULL; if (bo->getOpcode() == Instruction::Sub) { op = BinaryOperator::CreateNeg(bo->getOperand(1), "", bo); op = BinaryOperator::Create(Instruction::Add, bo->getOperand(0), op, "", bo); // Check signed wrap op->setHasNoSignedWrap(bo->hasNoSignedWrap()); op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap()); } else { op = BinaryOperator::CreateFNeg(bo->getOperand(1), "", bo); op = BinaryOperator::Create(Instruction::FAdd, bo->getOperand(0), op, "", bo); } bo->replaceAllUsesWith(op); }
TEST(CloneInstruction, OverflowBits) { LLVMContext context; Value *V = new Argument(Type::getInt32Ty(context)); BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V); BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(); Sub->setHasNoUnsignedWrap(); Mul->setHasNoUnsignedWrap(); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoSignedWrap(); Sub->setHasNoSignedWrap(); Mul->setHasNoSignedWrap(); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(false); Sub->setHasNoUnsignedWrap(false); Mul->setHasNoUnsignedWrap(false); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); }
Instruction *InstCombiner::visitSub(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Value *V = SimplifySubInst(Op0, Op1, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); // (A*B)-(A*C) -> A*(B-C) etc if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); // If this is a 'B = x-(-A)', change to B = x+A. This preserves NSW/NUW. if (Value *V = dyn_castNegVal(Op1)) { BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V); Res->setHasNoSignedWrap(I.hasNoSignedWrap()); Res->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); return Res; } if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateXor(Op0, Op1); // Replace (-1 - A) with (~A). if (match(Op0, m_AllOnes())) return BinaryOperator::CreateNot(Op1); if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) { // C - ~X == X + (1+C) Value *X = 0; if (match(Op1, m_Not(m_Value(X)))) return BinaryOperator::CreateAdd(X, AddOne(C)); // -(X >>u 31) -> (X >>s 31) // -(X >>s 31) -> (X >>u 31) if (C->isZero()) { Value *X; ConstantInt *CI; if (match(Op1, m_LShr(m_Value(X), m_ConstantInt(CI))) && // Verify we are shifting out everything but the sign bit. CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1) return BinaryOperator::CreateAShr(X, CI); if (match(Op1, m_AShr(m_Value(X), m_ConstantInt(CI))) && // Verify we are shifting out everything but the sign bit. CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1) return BinaryOperator::CreateLShr(X, CI); } // Try to fold constant sub into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; // C - zext(bool) -> bool ? C - 1 : C if (ZExtInst *ZI = dyn_cast<ZExtInst>(Op1)) if (ZI->getSrcTy()->isIntegerTy(1)) return SelectInst::Create(ZI->getOperand(0), SubOne(C), C); // C-(X+C2) --> (C-C2)-X ConstantInt *C2; if (match(Op1, m_Add(m_Value(X), m_ConstantInt(C2)))) return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); } { Value *Y; // X-(X+Y) == -Y X-(Y+X) == -Y if (match(Op1, m_Add(m_Specific(Op0), m_Value(Y))) || match(Op1, m_Add(m_Value(Y), m_Specific(Op0)))) return BinaryOperator::CreateNeg(Y); // (X-Y)-X == -Y if (match(Op0, m_Sub(m_Specific(Op1), m_Value(Y)))) return BinaryOperator::CreateNeg(Y); } if (Op1->hasOneUse()) { Value *X = 0, *Y = 0, *Z = 0; Constant *C = 0; ConstantInt *CI = 0; // (X - (Y - Z)) --> (X + (Z - Y)). if (match(Op1, m_Sub(m_Value(Y), m_Value(Z)))) return BinaryOperator::CreateAdd(Op0, Builder->CreateSub(Z, Y, Op1->getName())); // (X - (X & Y)) --> (X & ~Y) // if (match(Op1, m_And(m_Value(Y), m_Specific(Op0))) || match(Op1, m_And(m_Specific(Op0), m_Value(Y)))) return BinaryOperator::CreateAnd(Op0, Builder->CreateNot(Y, Y->getName() + ".not")); // 0 - (X sdiv C) -> (X sdiv -C) if (match(Op1, m_SDiv(m_Value(X), m_Constant(C))) && match(Op0, m_Zero())) return BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C)); // 0 - (X << Y) -> (-X << Y) when X is freely negatable. if (match(Op1, m_Shl(m_Value(X), m_Value(Y))) && match(Op0, m_Zero())) if (Value *XNeg = dyn_castNegVal(X)) return BinaryOperator::CreateShl(XNeg, Y); // X - X*C --> X * (1-C) if (match(Op1, m_Mul(m_Specific(Op0), m_ConstantInt(CI)))) { Constant *CP1 = ConstantExpr::getSub(ConstantInt::get(I.getType(),1), CI); return BinaryOperator::CreateMul(Op0, CP1); } // X - X<<C --> X * (1-(1<<C)) if (match(Op1, m_Shl(m_Specific(Op0), m_ConstantInt(CI)))) { Constant *One = ConstantInt::get(I.getType(), 1); C = ConstantExpr::getSub(One, ConstantExpr::getShl(One, CI)); return BinaryOperator::CreateMul(Op0, C); } // X - A*-B -> X + A*B // X - -A*B -> X + A*B Value *A, *B; if (match(Op1, m_Mul(m_Value(A), m_Neg(m_Value(B)))) || match(Op1, m_Mul(m_Neg(m_Value(A)), m_Value(B)))) return BinaryOperator::CreateAdd(Op0, Builder->CreateMul(A, B)); // X - A*CI -> X + A*-CI // X - CI*A -> X + A*-CI if (match(Op1, m_Mul(m_Value(A), m_ConstantInt(CI))) || match(Op1, m_Mul(m_ConstantInt(CI), m_Value(A)))) { Value *NewMul = Builder->CreateMul(A, ConstantExpr::getNeg(CI)); return BinaryOperator::CreateAdd(Op0, NewMul); } } ConstantInt *C1; if (Value *X = dyn_castFoldableMul(Op0, C1)) { if (X == Op1) // X*C - X --> X * (C-1) return BinaryOperator::CreateMul(Op1, SubOne(C1)); ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2) if (X == dyn_castFoldableMul(Op1, C2)) return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2)); } // Optimize pointer differences into the same array into a size. Consider: // &A[10] - &A[0]: we should compile this to "10". if (TD) { Value *LHSOp, *RHSOp; if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && match(Op1, m_PtrToInt(m_Value(RHSOp)))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType())) return ReplaceInstUsesWith(I, Res); // trunc(p)-trunc(q) -> trunc(p-q) if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) && match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp))))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType())) return ReplaceInstUsesWith(I, Res); } return 0; }
bool SimplifyIndvar::eliminateOverflowIntrinsic(CallInst *CI) { auto *F = CI->getCalledFunction(); if (!F) return false; typedef const SCEV *(ScalarEvolution::*OperationFunctionTy)( const SCEV *, const SCEV *, SCEV::NoWrapFlags, unsigned); typedef const SCEV *(ScalarEvolution::*ExtensionFunctionTy)( const SCEV *, Type *, unsigned); OperationFunctionTy Operation; ExtensionFunctionTy Extension; Instruction::BinaryOps RawOp; // We always have exactly one of nsw or nuw. If NoSignedOverflow is false, we // have nuw. bool NoSignedOverflow; switch (F->getIntrinsicID()) { default: return false; case Intrinsic::sadd_with_overflow: Operation = &ScalarEvolution::getAddExpr; Extension = &ScalarEvolution::getSignExtendExpr; RawOp = Instruction::Add; NoSignedOverflow = true; break; case Intrinsic::uadd_with_overflow: Operation = &ScalarEvolution::getAddExpr; Extension = &ScalarEvolution::getZeroExtendExpr; RawOp = Instruction::Add; NoSignedOverflow = false; break; case Intrinsic::ssub_with_overflow: Operation = &ScalarEvolution::getMinusSCEV; Extension = &ScalarEvolution::getSignExtendExpr; RawOp = Instruction::Sub; NoSignedOverflow = true; break; case Intrinsic::usub_with_overflow: Operation = &ScalarEvolution::getMinusSCEV; Extension = &ScalarEvolution::getZeroExtendExpr; RawOp = Instruction::Sub; NoSignedOverflow = false; break; } const SCEV *LHS = SE->getSCEV(CI->getArgOperand(0)); const SCEV *RHS = SE->getSCEV(CI->getArgOperand(1)); auto *NarrowTy = cast<IntegerType>(LHS->getType()); auto *WideTy = IntegerType::get(NarrowTy->getContext(), NarrowTy->getBitWidth() * 2); const SCEV *A = (SE->*Extension)((SE->*Operation)(LHS, RHS, SCEV::FlagAnyWrap, 0), WideTy, 0); const SCEV *B = (SE->*Operation)((SE->*Extension)(LHS, WideTy, 0), (SE->*Extension)(RHS, WideTy, 0), SCEV::FlagAnyWrap, 0); if (A != B) return false; // Proved no overflow, nuke the overflow check and, if possible, the overflow // intrinsic as well. BinaryOperator *NewResult = BinaryOperator::Create( RawOp, CI->getArgOperand(0), CI->getArgOperand(1), "", CI); if (NoSignedOverflow) NewResult->setHasNoSignedWrap(true); else NewResult->setHasNoUnsignedWrap(true); SmallVector<ExtractValueInst *, 4> ToDelete; for (auto *U : CI->users()) { if (auto *EVI = dyn_cast<ExtractValueInst>(U)) { if (EVI->getIndices()[0] == 1) EVI->replaceAllUsesWith(ConstantInt::getFalse(CI->getContext())); else { assert(EVI->getIndices()[0] == 0 && "Only two possibilities!"); EVI->replaceAllUsesWith(NewResult); } ToDelete.push_back(EVI); } } for (auto *EVI : ToDelete) EVI->eraseFromParent(); if (CI->use_empty()) CI->eraseFromParent(); return true; }
/// FoldSelectIntoOp - Try fold the select into one of the operands to /// facilitate further optimization. Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal, Value *FalseVal) { // See the comment above GetSelectFoldableOperands for a description of the // transformation we are doing here. if (Instruction *TVI = dyn_cast<Instruction>(TrueVal)) { if (TVI->hasOneUse() && TVI->getNumOperands() == 2 && !isa<Constant>(FalseVal)) { if (unsigned SFO = GetSelectFoldableOperands(TVI)) { unsigned OpToFold = 0; if ((SFO & 1) && FalseVal == TVI->getOperand(0)) { OpToFold = 1; } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) { OpToFold = 2; } if (OpToFold) { Constant *C = GetSelectFoldableConstant(TVI); Value *OOp = TVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Value *NewSel = Builder->CreateSelect(SI.getCondition(), OOp, C); NewSel->takeName(TVI); BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI); BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(), FalseVal, NewSel); if (isa<PossiblyExactOperator>(BO)) BO->setIsExact(TVI_BO->isExact()); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap()); BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap()); } return BO; } } } } } if (Instruction *FVI = dyn_cast<Instruction>(FalseVal)) { if (FVI->hasOneUse() && FVI->getNumOperands() == 2 && !isa<Constant>(TrueVal)) { if (unsigned SFO = GetSelectFoldableOperands(FVI)) { unsigned OpToFold = 0; if ((SFO & 1) && TrueVal == FVI->getOperand(0)) { OpToFold = 1; } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) { OpToFold = 2; } if (OpToFold) { Constant *C = GetSelectFoldableConstant(FVI); Value *OOp = FVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Value *NewSel = Builder->CreateSelect(SI.getCondition(), C, OOp); NewSel->takeName(FVI); BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI); BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(), TrueVal, NewSel); if (isa<PossiblyExactOperator>(BO)) BO->setIsExact(FVI_BO->isExact()); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap()); BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap()); } return BO; } } } } } return nullptr; }
/// Rebuild a new instruction just like 'I' but with the new operands given. /// In the event of type mismatch, the type of the operands is correct. static Value *BuildNew(Instruction *I, ArrayRef<Value*> NewOps) { // We don't want to use the IRBuilder here because we want the replacement // instructions to appear next to 'I', not the builder's insertion point. switch (I->getOpcode()) { case Instruction::Add: case Instruction::FAdd: case Instruction::Sub: case Instruction::FSub: case Instruction::Mul: case Instruction::FMul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: case Instruction::URem: case Instruction::SRem: case Instruction::FRem: case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: case Instruction::And: case Instruction::Or: case Instruction::Xor: { BinaryOperator *BO = cast<BinaryOperator>(I); assert(NewOps.size() == 2 && "binary operator with #ops != 2"); BinaryOperator *New = BinaryOperator::Create(cast<BinaryOperator>(I)->getOpcode(), NewOps[0], NewOps[1], "", BO); if (isa<OverflowingBinaryOperator>(BO)) { New->setHasNoUnsignedWrap(BO->hasNoUnsignedWrap()); New->setHasNoSignedWrap(BO->hasNoSignedWrap()); } if (isa<PossiblyExactOperator>(BO)) { New->setIsExact(BO->isExact()); } return New; } case Instruction::ICmp: assert(NewOps.size() == 2 && "icmp with #ops != 2"); return new ICmpInst(I, cast<ICmpInst>(I)->getPredicate(), NewOps[0], NewOps[1]); case Instruction::FCmp: assert(NewOps.size() == 2 && "fcmp with #ops != 2"); return new FCmpInst(I, cast<FCmpInst>(I)->getPredicate(), NewOps[0], NewOps[1]); case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: case Instruction::FPToUI: case Instruction::FPToSI: case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::FPTrunc: case Instruction::FPExt: { // It's possible that the mask has a different number of elements from // the original cast. We recompute the destination type to match the mask. Type *DestTy = VectorType::get(I->getType()->getScalarType(), NewOps[0]->getType()->getVectorNumElements()); assert(NewOps.size() == 1 && "cast with #ops != 1"); return CastInst::Create(cast<CastInst>(I)->getOpcode(), NewOps[0], DestTy, "", I); } case Instruction::GetElementPtr: { Value *Ptr = NewOps[0]; ArrayRef<Value*> Idx = NewOps.slice(1); GetElementPtrInst *GEP = GetElementPtrInst::Create(Ptr, Idx, "", I); GEP->setIsInBounds(cast<GetElementPtrInst>(I)->isInBounds()); return GEP; } } llvm_unreachable("failed to rebuild vector instructions"); }
Instruction *InstCombiner::visitMul(BinaryOperator &I) { bool Changed = SimplifyAssociativeOrCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Value *V = SimplifyMulInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); if (match(Op1, m_AllOnes())) // X * -1 == 0 - X return BinaryOperator::CreateNeg(Op0, I.getName()); if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) { // ((X << C1)*C2) == (X * (C2 << C1)) if (BinaryOperator *SI = dyn_cast<BinaryOperator>(Op0)) if (SI->getOpcode() == Instruction::Shl) if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1))) return BinaryOperator::CreateMul(SI->getOperand(0), ConstantExpr::getShl(CI, ShOp)); const APInt &Val = CI->getValue(); if (Val.isPowerOf2()) { // Replace X*(2^C) with X << C Constant *NewCst = ConstantInt::get(Op0->getType(), Val.logBase2()); BinaryOperator *Shl = BinaryOperator::CreateShl(Op0, NewCst); if (I.hasNoSignedWrap()) Shl->setHasNoSignedWrap(); if (I.hasNoUnsignedWrap()) Shl->setHasNoUnsignedWrap(); return Shl; } // Canonicalize (X+C1)*CI -> X*CI+C1*CI. { Value *X; ConstantInt *C1; if (Op0->hasOneUse() && match(Op0, m_Add(m_Value(X), m_ConstantInt(C1)))) { Value *Add = Builder->CreateMul(X, CI); return BinaryOperator::CreateAdd(Add, Builder->CreateMul(C1, CI)); } } // (Y - X) * (-(2**n)) -> (X - Y) * (2**n), for positive nonzero n // (Y + const) * (-(2**n)) -> (-constY) * (2**n), for positive nonzero n // The "* (2**n)" thus becomes a potential shifting opportunity. { const APInt & Val = CI->getValue(); const APInt &PosVal = Val.abs(); if (Val.isNegative() && PosVal.isPowerOf2()) { Value *X = 0, *Y = 0; if (Op0->hasOneUse()) { ConstantInt *C1; Value *Sub = 0; if (match(Op0, m_Sub(m_Value(Y), m_Value(X)))) Sub = Builder->CreateSub(X, Y, "suba"); else if (match(Op0, m_Add(m_Value(Y), m_ConstantInt(C1)))) Sub = Builder->CreateSub(Builder->CreateNeg(C1), Y, "subc"); if (Sub) return BinaryOperator::CreateMul(Sub, ConstantInt::get(Y->getType(), PosVal)); } } } } // Simplify mul instructions with a constant RHS. if (isa<Constant>(Op1)) { // Try to fold constant mul into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; if (isa<PHINode>(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; } if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y if (Value *Op1v = dyn_castNegVal(Op1)) return BinaryOperator::CreateMul(Op0v, Op1v); // (X / Y) * Y = X - (X % Y) // (X / Y) * -Y = (X % Y) - X { Value *Op1C = Op1; BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0); if (!BO || (BO->getOpcode() != Instruction::UDiv && BO->getOpcode() != Instruction::SDiv)) { Op1C = Op0; BO = dyn_cast<BinaryOperator>(Op1); } Value *Neg = dyn_castNegVal(Op1C); if (BO && BO->hasOneUse() && (BO->getOperand(1) == Op1C || BO->getOperand(1) == Neg) && (BO->getOpcode() == Instruction::UDiv || BO->getOpcode() == Instruction::SDiv)) { Value *Op0BO = BO->getOperand(0), *Op1BO = BO->getOperand(1); // If the division is exact, X % Y is zero, so we end up with X or -X. if (PossiblyExactOperator *SDiv = dyn_cast<PossiblyExactOperator>(BO)) if (SDiv->isExact()) { if (Op1BO == Op1C) return ReplaceInstUsesWith(I, Op0BO); return BinaryOperator::CreateNeg(Op0BO); } Value *Rem; if (BO->getOpcode() == Instruction::UDiv) Rem = Builder->CreateURem(Op0BO, Op1BO); else Rem = Builder->CreateSRem(Op0BO, Op1BO); Rem->takeName(BO); if (Op1BO == Op1C) return BinaryOperator::CreateSub(Op0BO, Rem); return BinaryOperator::CreateSub(Rem, Op0BO); } } /// i1 mul -> i1 and. if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateAnd(Op0, Op1); // X*(1 << Y) --> X << Y // (1 << Y)*X --> X << Y { Value *Y; if (match(Op0, m_Shl(m_One(), m_Value(Y)))) return BinaryOperator::CreateShl(Op1, Y); if (match(Op1, m_Shl(m_One(), m_Value(Y)))) return BinaryOperator::CreateShl(Op0, Y); } // If one of the operands of the multiply is a cast from a boolean value, then // we know the bool is either zero or one, so this is a 'masking' multiply. // X * Y (where Y is 0 or 1) -> X & (0-Y) if (!I.getType()->isVectorTy()) { // -2 is "-1 << 1" so it is all bits set except the low one. APInt Negative2(I.getType()->getPrimitiveSizeInBits(), (uint64_t)-2, true); Value *BoolCast = 0, *OtherOp = 0; if (MaskedValueIsZero(Op0, Negative2)) BoolCast = Op0, OtherOp = Op1; else if (MaskedValueIsZero(Op1, Negative2)) BoolCast = Op1, OtherOp = Op0; if (BoolCast) { Value *V = Builder->CreateSub(Constant::getNullValue(I.getType()), BoolCast); return BinaryOperator::CreateAnd(V, OtherOp); } } return Changed ? &I : 0; }
static Value *genVal(int &Budget, unsigned Width, bool ConstOK, bool ArgOK) { if (Budget > 0 && Choose(2)) { if (Verbose) errs() << "adding a phi, budget = " << Budget << "\n"; --Budget; Value *V = Builder->CreatePHI(Type::getIntNTy(*C, Width), N); Vals.push_back(V); return V; } if (Budget > 0 && Budget != N && Choose(2)) { if (Verbose) errs() << "adding a branch, budget = " << Budget << "\n"; --Budget; BranchInst *Br; if (0 && Builder->GetInsertBlock()->size() > 0 && Choose(2)) { Br = Builder->CreateBr(BBs[0]); } else { Value *C = genVal(Budget, 1, false, ArgOK); Br = Builder->CreateCondBr(C, BBs[0], BBs[0]); } Branches.push_back(Br); BasicBlock *BB = BasicBlock::Create(*C, "", F); BBs.push_back(BB); Builder->SetInsertPoint(BB); return genVal(Budget, Width, ConstOK, ArgOK); } if (Budget > 0 && Width == W && Choose(2)) { if (Verbose) errs() << "adding a select with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Value *L, *R; genLR(L, R, Budget, Width); Value *C = genVal(Budget, 1, false); Value *V = Builder->CreateSelect(C, L, R); Vals.push_back(V); return V; } if (Budget > 0 && Width == 1 && Choose(2)) { if (Verbose) errs() << "adding an icmp with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Value *L, *R; genLR(L, R, Budget, Width); CmpInst::Predicate P; switch (OneICmp ? 0 : Choose(10)) { case 0: P = CmpInst::ICMP_EQ; break; case 1: P = CmpInst::ICMP_NE; break; case 2: P = CmpInst::ICMP_UGT; break; case 3: P = CmpInst::ICMP_UGE; break; case 4: P = CmpInst::ICMP_ULT; break; case 5: P = CmpInst::ICMP_ULE; break; case 6: P = CmpInst::ICMP_SGT; break; case 7: P = CmpInst::ICMP_SGE; break; case 8: P = CmpInst::ICMP_SLT; break; case 9: P = CmpInst::ICMP_SLE; break; } Value *V = Builder->CreateICmp(P, L, R); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { unsigned OldW = Width * 2; if (Verbose) errs() << "adding a trunc from " << OldW << " to " << Width << " and budget = " << Budget << "\n"; --Budget; Value *V = Builder->CreateTrunc(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { unsigned OldW = Width / 2; if (OldW > 1 && Choose(2)) OldW = 1; if (Verbose) errs() << "adding a zext from " << OldW << " to " << Width << " and budget = " << Budget << "\n"; --Budget; Value *V; if (Choose(2)) V = Builder->CreateZExt(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); else V = Builder->CreateSExt(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { if (Verbose) errs() << "adding a binop with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Instruction::BinaryOps Op; switch (OneBinop ? 0 : Choose(10)) { case 0: Op = Instruction::Add; break; case 1: Op = Instruction::Sub; break; case 2: Op = Instruction::Mul; break; case 3: Op = Instruction::SDiv; break; case 4: Op = Instruction::UDiv; break; case 5: Op = Instruction::SRem; break; case 6: Op = Instruction::URem; break; case 7: Op = Instruction::And; break; case 8: Op = Instruction::Or; break; case 9: Op = Instruction::Xor; break; } Value *L, *R; genLR(L, R, Budget, Width); Value *V = Builder->CreateBinOp(Op, L, R); if (!NoUB) { if ((Op == Instruction::Add || Op == Instruction::Sub || Op == Instruction::Mul || Op == Instruction::Shl) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setHasNoSignedWrap(true); } if ((Op == Instruction::Add || Op == Instruction::Sub || Op == Instruction::Mul || Op == Instruction::Shl) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setHasNoUnsignedWrap(true); } if ((Op == Instruction::UDiv || Op == Instruction::SDiv || Op == Instruction::LShr || Op == Instruction::AShr) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setIsExact(true); } } Vals.push_back(V); return V; } if (ConstOK && Choose(2)) { if (Verbose) errs() << "adding a const with width = " << Width << " and budget = " << Budget << "\n"; if (OneConst) { return ConstantInt::get(*C, APInt(Width, 1)); } else { int n = Choose((1 << Width) + 1); if (n == (1 << Width)) return UndefValue::get(Type::getIntNTy(*C, Width)); else return ConstantInt::get(*C, APInt(Width, n)); } } if (Verbose) errs() << "using existing val with width = " << Width << " and budget = " << Budget << " and ArgOK = " << ArgOK << "\n"; std::vector<Value *> Vs; for (auto &it : Vals) if (it->getType()->getPrimitiveSizeInBits() == Width) Vs.push_back(it); unsigned choices = Vs.size() + (ArgOK ? 1 : 0); if (choices == 0) exit(0); unsigned which = Choose(choices); if (which == Vs.size()) { Value *V = 0; for (auto it = F->arg_begin(); it != F->arg_end(); ++it) { if (UsedArgs.find(it) == UsedArgs.end() && it->getType()->getPrimitiveSizeInBits() == Width) { UsedArgs.insert(it); V = it; Vals.push_back(V); break; } } ensure(V); return V; } else { return Vs.at(which); } }
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// Value *PHITransAddr:: InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl<Instruction*> &NewInsts) { // See if we have a version of this value already available and dominating // PredBB. If so, there is no need to insert a new instance of it. PHITransAddr Tmp(InVal, TD); if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT)) return Tmp.getAddr(); // If we don't have an available version of this value, it must be an // instruction. Instruction *Inst = cast<Instruction>(InVal); // Handle bitcast of PHI translatable value. if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) { Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; // Otherwise insert a bitcast at the end of PredBB. BitCastInst *New = new BitCastInst(OpVal, InVal->getType(), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); NewInsts.push_back(New); return New; } // Handle getelementptr with at least one PHI operand. if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) { SmallVector<Value*, 8> GEPOps; BasicBlock *CurBB = GEP->getParent(); for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; GEPOps.push_back(OpVal); } GetElementPtrInst *Result = GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); return Result; } #if 0 // FIXME: This code works, but it is unclear that we actually want to insert // a big chain of computation in order to make a value available in a block. // This needs to be evaluated carefully to consider its cost trade offs. // Handle add with a constant RHS. if (Inst->getOpcode() == Instruction::Add && isa<ConstantInt>(Inst->getOperand(1))) { // PHI translate the LHS. Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap()); Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap()); NewInsts.push_back(Res); return Res; } #endif return 0; }
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I) { bool isLeftShift = I.getOpcode() == Instruction::Shl; ConstantInt *COp1 = nullptr; if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(Op1)) COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()); else if (ConstantVector *CV = dyn_cast<ConstantVector>(Op1)) COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()); else COp1 = dyn_cast<ConstantInt>(Op1); if (!COp1) return nullptr; // See if we can propagate this shift into the input, this covers the trivial // cast of lshr(shl(x,c1),c2) as well as other more complex cases. if (I.getOpcode() != Instruction::AShr && CanEvaluateShifted(Op0, COp1->getZExtValue(), isLeftShift, *this)) { DEBUG(dbgs() << "ICE: GetShiftedValue propagating shift through expression" " to eliminate shift:\n IN: " << *Op0 << "\n SH: " << I <<"\n"); return ReplaceInstUsesWith(I, GetShiftedValue(Op0, COp1->getZExtValue(), isLeftShift, *this)); } // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. uint32_t TypeBits = Op0->getType()->getScalarSizeInBits(); assert(!COp1->uge(TypeBits) && "Shift over the type width should have been removed already"); // ((X*C1) << C2) == (X * (C1 << C2)) if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) if (BO->getOpcode() == Instruction::Mul && isLeftShift) if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1))) return BinaryOperator::CreateMul(BO->getOperand(0), ConstantExpr::getShl(BOOp, Op1)); // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; if (isa<PHINode>(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; // Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2)) if (TruncInst *TI = dyn_cast<TruncInst>(Op0)) { Instruction *TrOp = dyn_cast<Instruction>(TI->getOperand(0)); // If 'shift2' is an ashr, we would have to get the sign bit into a funny // place. Don't try to do this transformation in this case. Also, we // require that the input operand is a shift-by-constant so that we have // confidence that the shifts will get folded together. We could do this // xform in more cases, but it is unlikely to be profitable. if (TrOp && I.isLogicalShift() && TrOp->isShift() && isa<ConstantInt>(TrOp->getOperand(1))) { // Okay, we'll do this xform. Make the shift of shift. Constant *ShAmt = ConstantExpr::getZExt(COp1, TrOp->getType()); // (shift2 (shift1 & 0x00FF), c2) Value *NSh = Builder->CreateBinOp(I.getOpcode(), TrOp, ShAmt,I.getName()); // For logical shifts, the truncation has the effect of making the high // part of the register be zeros. Emulate this by inserting an AND to // clear the top bits as needed. This 'and' will usually be zapped by // other xforms later if dead. unsigned SrcSize = TrOp->getType()->getScalarSizeInBits(); unsigned DstSize = TI->getType()->getScalarSizeInBits(); APInt MaskV(APInt::getLowBitsSet(SrcSize, DstSize)); // The mask we constructed says what the trunc would do if occurring // between the shifts. We want to know the effect *after* the second // shift. We know that it is a logical shift by a constant, so adjust the // mask as appropriate. if (I.getOpcode() == Instruction::Shl) MaskV <<= COp1->getZExtValue(); else { assert(I.getOpcode() == Instruction::LShr && "Unknown logical shift"); MaskV = MaskV.lshr(COp1->getZExtValue()); } // shift1 & 0x00FF Value *And = Builder->CreateAnd(NSh, ConstantInt::get(I.getContext(), MaskV), TI->getName()); // Return the value truncated to the interesting size. return new TruncInst(And, I.getType()); } } if (Op0->hasOneUse()) { if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) { // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) Value *V1, *V2; ConstantInt *CC; switch (Op0BO->getOpcode()) { default: break; case Instruction::Add: case Instruction::And: case Instruction::Or: case Instruction::Xor: { // These operators commute. // Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() && match(Op0BO->getOperand(1), m_Shr(m_Value(V1), m_Specific(Op1)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName()); // (X + (Y << C)) Value *X = Builder->CreateBinOp(Op0BO->getOpcode(), YS, V1, Op0BO->getOperand(1)->getName()); uint32_t Op1Val = COp1->getLimitedValue(TypeBits); APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val); Constant *Mask = ConstantInt::get(I.getContext(), Bits); if (VectorType *VT = dyn_cast<VectorType>(X->getType())) Mask = ConstantVector::getSplat(VT->getNumElements(), Mask); return BinaryOperator::CreateAnd(X, Mask); } // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C)) Value *Op0BOOp1 = Op0BO->getOperand(1); if (isLeftShift && Op0BOOp1->hasOneUse() && match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))), m_ConstantInt(CC)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName()); // X & (CC << C) Value *XM = Builder->CreateAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); return BinaryOperator::Create(Op0BO->getOpcode(), YS, XM); } } // FALL THROUGH. case Instruction::Sub: { // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), m_Shr(m_Value(V1), m_Specific(Op1)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName()); // (X + (Y << C)) Value *X = Builder->CreateBinOp(Op0BO->getOpcode(), V1, YS, Op0BO->getOperand(0)->getName()); uint32_t Op1Val = COp1->getLimitedValue(TypeBits); APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val); Constant *Mask = ConstantInt::get(I.getContext(), Bits); if (VectorType *VT = dyn_cast<VectorType>(X->getType())) Mask = ConstantVector::getSplat(VT->getNumElements(), Mask); return BinaryOperator::CreateAnd(X, Mask); } // Turn (((X >> C)&CC) + Y) << C -> (X + (Y << C)) & (CC << C) if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), m_And(m_OneUse(m_Shr(m_Value(V1), m_Value(V2))), m_ConstantInt(CC))) && V2 == Op1) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName()); // X & (CC << C) Value *XM = Builder->CreateAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); return BinaryOperator::Create(Op0BO->getOpcode(), XM, YS); } break; } } // If the operand is an bitwise operator with a constant RHS, and the // shift is the only use, we can pull it out of the shift. if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) { bool isValid = true; // Valid only for And, Or, Xor bool highBitSet = false; // Transform if high bit of constant set? switch (Op0BO->getOpcode()) { default: isValid = false; break; // Do not perform transform! case Instruction::Add: isValid = isLeftShift; break; case Instruction::Or: case Instruction::Xor: highBitSet = false; break; case Instruction::And: highBitSet = true; break; } // If this is a signed shift right, and the high bit is modified // by the logical operation, do not perform the transformation. // The highBitSet boolean indicates the value of the high bit of // the constant which would cause it to be modified for this // operation. // if (isValid && I.getOpcode() == Instruction::AShr) isValid = Op0C->getValue()[TypeBits-1] == highBitSet; if (isValid) { Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1); Value *NewShift = Builder->CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), Op1); NewShift->takeName(Op0BO); return BinaryOperator::Create(Op0BO->getOpcode(), NewShift, NewRHS); } } } } // Find out if this is a shift of a shift by a constant. BinaryOperator *ShiftOp = dyn_cast<BinaryOperator>(Op0); if (ShiftOp && !ShiftOp->isShift()) ShiftOp = nullptr; if (ShiftOp && isa<ConstantInt>(ShiftOp->getOperand(1))) { // This is a constant shift of a constant shift. Be careful about hiding // shl instructions behind bit masks. They are used to represent multiplies // by a constant, and it is important that simple arithmetic expressions // are still recognizable by scalar evolution. // // The transforms applied to shl are very similar to the transforms applied // to mul by constant. We can be more aggressive about optimizing right // shifts. // // Combinations of right and left shifts will still be optimized in // DAGCombine where scalar evolution no longer applies. ConstantInt *ShiftAmt1C = cast<ConstantInt>(ShiftOp->getOperand(1)); uint32_t ShiftAmt1 = ShiftAmt1C->getLimitedValue(TypeBits); uint32_t ShiftAmt2 = COp1->getLimitedValue(TypeBits); assert(ShiftAmt2 != 0 && "Should have been simplified earlier"); if (ShiftAmt1 == 0) return nullptr; // Will be simplified in the future. Value *X = ShiftOp->getOperand(0); IntegerType *Ty = cast<IntegerType>(I.getType()); // Check for (X << c1) << c2 and (X >> c1) >> c2 if (I.getOpcode() == ShiftOp->getOpcode()) { uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift. // If this is oversized composite shift, then unsigned shifts get 0, ashr // saturates. if (AmtSum >= TypeBits) { if (I.getOpcode() != Instruction::AShr) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); AmtSum = TypeBits-1; // Saturate to 31 for i32 ashr. } return BinaryOperator::Create(I.getOpcode(), X, ConstantInt::get(Ty, AmtSum)); } if (ShiftAmt1 == ShiftAmt2) { // If we have ((X << C) >>u C), turn this into X & (-1 >>u C). if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1)); return BinaryOperator::CreateAnd(X, ConstantInt::get(I.getContext(), Mask)); } } else if (ShiftAmt1 < ShiftAmt2) { uint32_t ShiftDiff = ShiftAmt2-ShiftAmt1; // (X >>?,exact C1) << C2 --> X << (C2-C1) // The inexact version is deferred to DAGCombine so we don't hide shl // behind a bit mask. if (I.getOpcode() == Instruction::Shl && ShiftOp->getOpcode() != Instruction::Shl && ShiftOp->isExact()) { assert(ShiftOp->getOpcode() == Instruction::LShr || ShiftOp->getOpcode() == Instruction::AShr); ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); NewShl->setHasNoSignedWrap(I.hasNoSignedWrap()); return NewShl; } // (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2) if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); // (X <<nuw C1) >>u C2 --> X >>u (C2-C1) if (ShiftOp->hasNoUnsignedWrap()) { BinaryOperator *NewLShr = BinaryOperator::Create(Instruction::LShr, X, ShiftDiffCst); NewLShr->setIsExact(I.isExact()); return NewLShr; } Value *Shift = Builder->CreateLShr(X, ShiftDiffCst); APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt2)); return BinaryOperator::CreateAnd(Shift, ConstantInt::get(I.getContext(),Mask)); } // We can't handle (X << C1) >>s C2, it shifts arbitrary bits in. However, // we can handle (X <<nsw C1) >>s C2 since it only shifts in sign bits. if (I.getOpcode() == Instruction::AShr && ShiftOp->getOpcode() == Instruction::Shl) { if (ShiftOp->hasNoSignedWrap()) { // (X <<nsw C1) >>s C2 --> X >>s (C2-C1) ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewAShr = BinaryOperator::Create(Instruction::AShr, X, ShiftDiffCst); NewAShr->setIsExact(I.isExact()); return NewAShr; } } } else { assert(ShiftAmt2 < ShiftAmt1); uint32_t ShiftDiff = ShiftAmt1-ShiftAmt2; // (X >>?exact C1) << C2 --> X >>?exact (C1-C2) // The inexact version is deferred to DAGCombine so we don't hide shl // behind a bit mask. if (I.getOpcode() == Instruction::Shl && ShiftOp->getOpcode() != Instruction::Shl && ShiftOp->isExact()) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShr = BinaryOperator::Create(ShiftOp->getOpcode(), X, ShiftDiffCst); NewShr->setIsExact(true); return NewShr; } // (X << C1) >>u C2 --> X << (C1-C2) & (-1 >> C2) if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); if (ShiftOp->hasNoUnsignedWrap()) { // (X <<nuw C1) >>u C2 --> X <<nuw (C1-C2) BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoUnsignedWrap(true); return NewShl; } Value *Shift = Builder->CreateShl(X, ShiftDiffCst); APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt2)); return BinaryOperator::CreateAnd(Shift, ConstantInt::get(I.getContext(),Mask)); } // We can't handle (X << C1) >>s C2, it shifts arbitrary bits in. However, // we can handle (X <<nsw C1) >>s C2 since it only shifts in sign bits. if (I.getOpcode() == Instruction::AShr && ShiftOp->getOpcode() == Instruction::Shl) { if (ShiftOp->hasNoSignedWrap()) { // (X <<nsw C1) >>s C2 --> X <<nsw (C1-C2) ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoSignedWrap(true); return NewShl; } } } } return nullptr; }
/// GetShiftedValue - When CanEvaluateShifted returned true for an expression, /// this value inserts the new computation that produces the shifted value. static Value *GetShiftedValue(Value *V, unsigned NumBits, bool isLeftShift, InstCombiner &IC) { // We can always evaluate constants shifted. if (Constant *C = dyn_cast<Constant>(V)) { if (isLeftShift) V = IC.Builder->CreateShl(C, NumBits); else V = IC.Builder->CreateLShr(C, NumBits); // If we got a constantexpr back, try to simplify it with TD info. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) V = ConstantFoldConstantExpression(CE, IC.getDataLayout(), IC.getTargetLibraryInfo()); return V; } Instruction *I = cast<Instruction>(V); IC.Worklist.Add(I); switch (I->getOpcode()) { default: llvm_unreachable("Inconsistency with CanEvaluateShifted"); case Instruction::And: case Instruction::Or: case Instruction::Xor: // Bitwise operators can all arbitrarily be arbitrarily evaluated shifted. I->setOperand(0, GetShiftedValue(I->getOperand(0), NumBits,isLeftShift,IC)); I->setOperand(1, GetShiftedValue(I->getOperand(1), NumBits,isLeftShift,IC)); return I; case Instruction::Shl: { BinaryOperator *BO = cast<BinaryOperator>(I); unsigned TypeWidth = BO->getType()->getScalarSizeInBits(); // We only accept shifts-by-a-constant in CanEvaluateShifted. ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1)); // We can always fold shl(c1)+shl(c2) -> shl(c1+c2). if (isLeftShift) { // If this is oversized composite shift, then unsigned shifts get 0. unsigned NewShAmt = NumBits+CI->getZExtValue(); if (NewShAmt >= TypeWidth) return Constant::getNullValue(I->getType()); BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt)); BO->setHasNoUnsignedWrap(false); BO->setHasNoSignedWrap(false); return I; } // We turn shl(c)+lshr(c) -> and(c2) if the input doesn't already have // zeros. if (CI->getValue() == NumBits) { APInt Mask(APInt::getLowBitsSet(TypeWidth, TypeWidth - NumBits)); V = IC.Builder->CreateAnd(BO->getOperand(0), ConstantInt::get(BO->getContext(), Mask)); if (Instruction *VI = dyn_cast<Instruction>(V)) { VI->moveBefore(BO); VI->takeName(BO); } return V; } // We turn shl(c1)+shr(c2) -> shl(c3)+and(c4), but only when we know that // the and won't be needed. assert(CI->getZExtValue() > NumBits); BO->setOperand(1, ConstantInt::get(BO->getType(), CI->getZExtValue() - NumBits)); BO->setHasNoUnsignedWrap(false); BO->setHasNoSignedWrap(false); return BO; } case Instruction::LShr: { BinaryOperator *BO = cast<BinaryOperator>(I); unsigned TypeWidth = BO->getType()->getScalarSizeInBits(); // We only accept shifts-by-a-constant in CanEvaluateShifted. ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1)); // We can always fold lshr(c1)+lshr(c2) -> lshr(c1+c2). if (!isLeftShift) { // If this is oversized composite shift, then unsigned shifts get 0. unsigned NewShAmt = NumBits+CI->getZExtValue(); if (NewShAmt >= TypeWidth) return Constant::getNullValue(BO->getType()); BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt)); BO->setIsExact(false); return I; } // We turn lshr(c)+shl(c) -> and(c2) if the input doesn't already have // zeros. if (CI->getValue() == NumBits) { APInt Mask(APInt::getHighBitsSet(TypeWidth, TypeWidth - NumBits)); V = IC.Builder->CreateAnd(I->getOperand(0), ConstantInt::get(BO->getContext(), Mask)); if (Instruction *VI = dyn_cast<Instruction>(V)) { VI->moveBefore(I); VI->takeName(I); } return V; } // We turn lshr(c1)+shl(c2) -> lshr(c3)+and(c4), but only when we know that // the and won't be needed. assert(CI->getZExtValue() > NumBits); BO->setOperand(1, ConstantInt::get(BO->getType(), CI->getZExtValue() - NumBits)); BO->setIsExact(false); return BO; } case Instruction::Select: I->setOperand(1, GetShiftedValue(I->getOperand(1), NumBits,isLeftShift,IC)); I->setOperand(2, GetShiftedValue(I->getOperand(2), NumBits,isLeftShift,IC)); return I; case Instruction::PHI: { // We can change a phi if we can change all operands. Note that we never // get into trouble with cyclic PHIs here because we only consider // instructions with a single use. PHINode *PN = cast<PHINode>(I); for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) PN->setIncomingValue(i, GetShiftedValue(PN->getIncomingValue(i), NumBits, isLeftShift, IC)); return PN; } } }
Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyAssociativeOrCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); if (Value *V = SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); // (A*B)+(A*C) -> A*(B+C) etc if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { // X + (signbit) --> X ^ signbit const APInt &Val = CI->getValue(); if (Val.isSignBit()) return BinaryOperator::CreateXor(LHS, RHS); // See if SimplifyDemandedBits can simplify this. This handles stuff like // (X & 254)+1 -> (X&254)|1 if (SimplifyDemandedInstructionBits(I)) return &I; // zext(bool) + C -> bool ? C + 1 : C if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS)) if (ZI->getSrcTy()->isIntegerTy(1)) return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI); Value *XorLHS = 0; ConstantInt *XorRHS = 0; if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); const APInt &RHSVal = CI->getValue(); unsigned ExtendAmt = 0; // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. if (XorRHS->getValue() == -RHSVal) { if (RHSVal.isPowerOf2()) ExtendAmt = TySizeBits - RHSVal.logBase2() - 1; else if (XorRHS->getValue().isPowerOf2()) ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1; } if (ExtendAmt) { APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt); if (!MaskedValueIsZero(XorLHS, Mask)) ExtendAmt = 0; } if (ExtendAmt) { Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt); Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext"); return BinaryOperator::CreateAShr(NewShl, ShAmt); } } } if (isa<Constant>(RHS) && isa<PHINode>(LHS)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateXor(LHS, RHS); // X + X --> X << 1 if (LHS == RHS) { BinaryOperator *New = BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1)); New->setHasNoSignedWrap(I.hasNoSignedWrap()); New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); return New; } // -A + B --> B - A // -A + -B --> -(A + B) if (Value *LHSV = dyn_castNegVal(LHS)) { if (Value *RHSV = dyn_castNegVal(RHS)) { Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum"); return BinaryOperator::CreateNeg(NewAdd); } return BinaryOperator::CreateSub(RHS, LHSV); } // A + -B --> A - B if (!isa<Constant>(RHS)) if (Value *V = dyn_castNegVal(RHS)) return BinaryOperator::CreateSub(LHS, V); ConstantInt *C2; if (Value *X = dyn_castFoldableMul(LHS, C2)) { if (X == RHS) // X*C + X --> X * (C+1) return BinaryOperator::CreateMul(RHS, AddOne(C2)); // X*C1 + X*C2 --> X * (C1+C2) ConstantInt *C1; if (X == dyn_castFoldableMul(RHS, C1)) return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2)); } // X + X*C --> X * (C+1) if (dyn_castFoldableMul(RHS, C2) == LHS) return BinaryOperator::CreateMul(LHS, AddOne(C2)); // A+B --> A|B iff A and B have no bits set in common. if (const IntegerType *IT = dyn_cast<IntegerType>(I.getType())) { APInt Mask = APInt::getAllOnesValue(IT->getBitWidth()); APInt LHSKnownOne(IT->getBitWidth(), 0); APInt LHSKnownZero(IT->getBitWidth(), 0); ComputeMaskedBits(LHS, Mask, LHSKnownZero, LHSKnownOne); if (LHSKnownZero != 0) { APInt RHSKnownOne(IT->getBitWidth(), 0); APInt RHSKnownZero(IT->getBitWidth(), 0); ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne); // No bits in common -> bitwise or. if ((LHSKnownZero|RHSKnownZero).isAllOnesValue()) return BinaryOperator::CreateOr(LHS, RHS); } } // W*X + Y*Z --> W * (X+Z) iff W == Y { Value *W, *X, *Y, *Z; if (match(LHS, m_Mul(m_Value(W), m_Value(X))) && match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) { if (W != Y) { if (W == Z) { std::swap(Y, Z); } else if (Y == X) { std::swap(W, X); } else if (X == Z) { std::swap(Y, Z); std::swap(W, X); } } if (W == Y) { Value *NewAdd = Builder->CreateAdd(X, Z, LHS->getName()); return BinaryOperator::CreateMul(W, NewAdd); } } } if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) { Value *X = 0; if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X return BinaryOperator::CreateSub(SubOne(CRHS), X); // (X & FF00) + xx00 -> (X+xx00) & FF00 if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) && CRHS->getValue() == (CRHS->getValue() & C2->getValue())) { // See if all bits from the first bit set in the Add RHS up are included // in the mask. First, get the rightmost bit. const APInt &AddRHSV = CRHS->getValue(); // Form a mask of all bits from the lowest bit added through the top. APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1)); // See if the and mask includes all of these bits. APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue()); if (AddRHSHighBits == AddRHSHighBitsAnd) { // Okay, the xform is safe. Insert the new add pronto. Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->getName()); return BinaryOperator::CreateAnd(NewAdd, C2); } } // Try to fold constant add into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(LHS)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; } // add (select X 0 (sub n A)) A --> select X A n { SelectInst *SI = dyn_cast<SelectInst>(LHS); Value *A = RHS; if (!SI) { SI = dyn_cast<SelectInst>(RHS); A = LHS; } if (SI && SI->hasOneUse()) { Value *TV = SI->getTrueValue(); Value *FV = SI->getFalseValue(); Value *N; // Can we fold the add into the argument of the select? // We check both true and false select arguments for a matching subtract. if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A)))) // Fold the add into the true select value. return SelectInst::Create(SI->getCondition(), N, A); if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A)))) // Fold the add into the false select value. return SelectInst::Create(SI->getCondition(), A, N); } } // Check for (add (sext x), y), see if we can merge this into an // integer add followed by a sext. if (SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) { // (add (sext x), cst) --> (sext (add x, cst')) if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) { Constant *CI = ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType()); if (LHSConv->hasOneUse() && ConstantExpr::getSExt(CI, I.getType()) == RHSC && WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) { // Insert the new, smaller add. Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), CI, "addconv"); return new SExtInst(NewAdd, I.getType()); } } // (add (sext x), (sext y)) --> (sext (add int x, y)) if (SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) { // Only do this if x/y have the same type, if at last one of them has a // single use (so we don't increase the number of sexts), and if the // integer add will not overflow. if (LHSConv->getOperand(0)->getType()==RHSConv->getOperand(0)->getType()&& (LHSConv->hasOneUse() || RHSConv->hasOneUse()) && WillNotOverflowSignedAdd(LHSConv->getOperand(0), RHSConv->getOperand(0))) { // Insert the new integer add. Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), RHSConv->getOperand(0), "addconv"); return new SExtInst(NewAdd, I.getType()); } } } return Changed ? &I : 0; }
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// Value *PHITransAddr:: InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl<Instruction*> &NewInsts) { // See if we have a version of this value already available and dominating // PredBB. If so, there is no need to insert a new instance of it. PHITransAddr Tmp(InVal, DL, AC); if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT, /*MustDominate=*/true)) return Tmp.getAddr(); // We don't need to PHI translate values which aren't instructions. auto *Inst = dyn_cast<Instruction>(InVal); if (!Inst) return nullptr; // Handle cast of PHI translatable value. if (CastInst *Cast = dyn_cast<CastInst>(Inst)) { if (!isSafeToSpeculativelyExecute(Cast)) return nullptr; Value *OpVal = InsertPHITranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB, DT, NewInsts); if (!OpVal) return nullptr; // Otherwise insert a cast at the end of PredBB. CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(), InVal->getName() + ".phi.trans.insert", PredBB->getTerminator()); New->setDebugLoc(Inst->getDebugLoc()); NewInsts.push_back(New); return New; } // Handle getelementptr with at least one PHI operand. if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) { SmallVector<Value*, 8> GEPOps; BasicBlock *CurBB = GEP->getParent(); for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i), CurBB, PredBB, DT, NewInsts); if (!OpVal) return nullptr; GEPOps.push_back(OpVal); } GetElementPtrInst *Result = GetElementPtrInst::Create( GEP->getSourceElementType(), GEPOps[0], makeArrayRef(GEPOps).slice(1), InVal->getName() + ".phi.trans.insert", PredBB->getTerminator()); Result->setDebugLoc(Inst->getDebugLoc()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); return Result; } #if 0 // FIXME: This code works, but it is unclear that we actually want to insert // a big chain of computation in order to make a value available in a block. // This needs to be evaluated carefully to consider its cost trade offs. // Handle add with a constant RHS. if (Inst->getOpcode() == Instruction::Add && isa<ConstantInt>(Inst->getOperand(1))) { // PHI translate the LHS. Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap()); Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap()); NewInsts.push_back(Res); return Res; } #endif return nullptr; }
/// This function implements the transforms common to both integer division /// instructions (udiv and sdiv). It is called by the visitors to those integer /// division instructions. /// @brief Common integer divide transforms Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // The RHS is known non-zero. if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this)) { I.setOperand(1, V); return &I; } // Handle cases involving: [su]div X, (select Cond, Y, Z) // This does not apply for fdiv. if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I)) return &I; if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { if (Instruction *LHS = dyn_cast<Instruction>(Op0)) { // (X / C1) / C2 -> X / (C1*C2) if (Instruction::BinaryOps(LHS->getOpcode()) == I.getOpcode()) if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) { if (MultiplyOverflows(RHS, LHSRHS, I.getOpcode() == Instruction::SDiv)) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); return BinaryOperator::Create(I.getOpcode(), LHS->getOperand(0), ConstantExpr::getMul(RHS, LHSRHS)); } Value *X; const APInt *C1, *C2; if (match(RHS, m_APInt(C2))) { bool IsSigned = I.getOpcode() == Instruction::SDiv; if ((IsSigned && match(LHS, m_NSWMul(m_Value(X), m_APInt(C1)))) || (!IsSigned && match(LHS, m_NUWMul(m_Value(X), m_APInt(C1))))) { APInt Quotient(C1->getBitWidth(), /*Val=*/0ULL, IsSigned); // (X * C1) / C2 -> X / (C2 / C1) if C2 is a multiple of C1. if (IsMultiple(*C2, *C1, Quotient, IsSigned)) { BinaryOperator *BO = BinaryOperator::Create( I.getOpcode(), X, ConstantInt::get(X->getType(), Quotient)); BO->setIsExact(I.isExact()); return BO; } // (X * C1) / C2 -> X * (C1 / C2) if C1 is a multiple of C2. if (IsMultiple(*C1, *C2, Quotient, IsSigned)) { BinaryOperator *BO = BinaryOperator::Create( Instruction::Mul, X, ConstantInt::get(X->getType(), Quotient)); BO->setHasNoUnsignedWrap( !IsSigned && cast<OverflowingBinaryOperator>(LHS)->hasNoUnsignedWrap()); BO->setHasNoSignedWrap( cast<OverflowingBinaryOperator>(LHS)->hasNoSignedWrap()); return BO; } } if ((IsSigned && match(LHS, m_NSWShl(m_Value(X), m_APInt(C1)))) || (!IsSigned && match(LHS, m_NUWShl(m_Value(X), m_APInt(C1))))) { APInt Quotient(C1->getBitWidth(), /*Val=*/0ULL, IsSigned); APInt C1Shifted = APInt::getOneBitSet( C1->getBitWidth(), static_cast<unsigned>(C1->getLimitedValue())); // (X << C1) / C2 -> X / (C2 >> C1) if C2 is a multiple of C1. if (IsMultiple(*C2, C1Shifted, Quotient, IsSigned)) { BinaryOperator *BO = BinaryOperator::Create( I.getOpcode(), X, ConstantInt::get(X->getType(), Quotient)); BO->setIsExact(I.isExact()); return BO; } // (X << C1) / C2 -> X * (C2 >> C1) if C1 is a multiple of C2. if (IsMultiple(C1Shifted, *C2, Quotient, IsSigned)) { BinaryOperator *BO = BinaryOperator::Create( Instruction::Mul, X, ConstantInt::get(X->getType(), Quotient)); BO->setHasNoUnsignedWrap( !IsSigned && cast<OverflowingBinaryOperator>(LHS)->hasNoUnsignedWrap()); BO->setHasNoSignedWrap( cast<OverflowingBinaryOperator>(LHS)->hasNoSignedWrap()); return BO; } } } } if (!RHS->isZero()) { // avoid X udiv 0 if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; if (isa<PHINode>(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; } } if (ConstantInt *One = dyn_cast<ConstantInt>(Op0)) { if (One->isOne() && !I.getType()->isIntegerTy(1)) { bool isSigned = I.getOpcode() == Instruction::SDiv; if (isSigned) { // If Op1 is 0 then it's undefined behaviour, if Op1 is 1 then the // result is one, if Op1 is -1 then the result is minus one, otherwise // it's zero. Value *Inc = Builder->CreateAdd(Op1, One); Value *Cmp = Builder->CreateICmpULT( Inc, ConstantInt::get(I.getType(), 3)); return SelectInst::Create(Cmp, Op1, ConstantInt::get(I.getType(), 0)); } else { // If Op1 is 0 then it's undefined behaviour. If Op1 is 1 then the // result is one, otherwise it's zero. return new ZExtInst(Builder->CreateICmpEQ(Op1, One), I.getType()); } } } // See if we can fold away this div instruction. if (SimplifyDemandedInstructionBits(I)) return &I; // (X - (X rem Y)) / Y -> X / Y; usually originates as ((X / Y) * Y) / Y Value *X = nullptr, *Z = nullptr; if (match(Op0, m_Sub(m_Value(X), m_Value(Z)))) { // (X - Z) / Y; Y = Op1 bool isSigned = I.getOpcode() == Instruction::SDiv; if ((isSigned && match(Z, m_SRem(m_Specific(X), m_Specific(Op1)))) || (!isSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1))))) return BinaryOperator::Create(I.getOpcode(), X, Op1); } return nullptr; }