Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
35269 views
//===- InstCombineMulDivRem.cpp -------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the visit functions for mul, fmul, sdiv, udiv, fdiv,9// srem, urem, frem.10//11//===----------------------------------------------------------------------===//1213#include "InstCombineInternal.h"14#include "llvm/ADT/APInt.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/Analysis/InstructionSimplify.h"17#include "llvm/Analysis/ValueTracking.h"18#include "llvm/IR/BasicBlock.h"19#include "llvm/IR/Constant.h"20#include "llvm/IR/Constants.h"21#include "llvm/IR/InstrTypes.h"22#include "llvm/IR/Instruction.h"23#include "llvm/IR/Instructions.h"24#include "llvm/IR/IntrinsicInst.h"25#include "llvm/IR/Intrinsics.h"26#include "llvm/IR/Operator.h"27#include "llvm/IR/PatternMatch.h"28#include "llvm/IR/Type.h"29#include "llvm/IR/Value.h"30#include "llvm/Support/Casting.h"31#include "llvm/Support/ErrorHandling.h"32#include "llvm/Transforms/InstCombine/InstCombiner.h"33#include "llvm/Transforms/Utils/BuildLibCalls.h"34#include <cassert>3536#define DEBUG_TYPE "instcombine"37#include "llvm/Transforms/Utils/InstructionWorklist.h"3839using namespace llvm;40using namespace PatternMatch;4142/// The specific integer value is used in a context where it is known to be43/// non-zero. If this allows us to simplify the computation, do so and return44/// the new operand, otherwise return null.45static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,46Instruction &CxtI) {47// If V has multiple uses, then we would have to do more analysis to determine48// if this is safe. For example, the use could be in dynamically unreached49// code.50if (!V->hasOneUse()) return nullptr;5152bool MadeChange = false;5354// ((1 << A) >>u B) --> (1 << (A-B))55// Because V cannot be zero, we know that B is less than A.56Value *A = nullptr, *B = nullptr, *One = nullptr;57if (match(V, m_LShr(m_OneUse(m_Shl(m_Value(One), m_Value(A))), m_Value(B))) &&58match(One, m_One())) {59A = IC.Builder.CreateSub(A, B);60return IC.Builder.CreateShl(One, A);61}6263// (PowerOfTwo >>u B) --> isExact since shifting out the result would make it64// inexact. Similarly for <<.65BinaryOperator *I = dyn_cast<BinaryOperator>(V);66if (I && I->isLogicalShift() &&67IC.isKnownToBeAPowerOfTwo(I->getOperand(0), false, 0, &CxtI)) {68// We know that this is an exact/nuw shift and that the input is a69// non-zero context as well.70if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC, CxtI)) {71IC.replaceOperand(*I, 0, V2);72MadeChange = true;73}7475if (I->getOpcode() == Instruction::LShr && !I->isExact()) {76I->setIsExact();77MadeChange = true;78}7980if (I->getOpcode() == Instruction::Shl && !I->hasNoUnsignedWrap()) {81I->setHasNoUnsignedWrap();82MadeChange = true;83}84}8586// TODO: Lots more we could do here:87// If V is a phi node, we can call this on each of its operands.88// "select cond, X, 0" can simplify to "X".8990return MadeChange ? V : nullptr;91}9293// TODO: This is a specific form of a much more general pattern.94// We could detect a select with any binop identity constant, or we95// could use SimplifyBinOp to see if either arm of the select reduces.96// But that needs to be done carefully and/or while removing potential97// reverse canonicalizations as in InstCombiner::foldSelectIntoOp().98static Value *foldMulSelectToNegate(BinaryOperator &I,99InstCombiner::BuilderTy &Builder) {100Value *Cond, *OtherOp;101102// mul (select Cond, 1, -1), OtherOp --> select Cond, OtherOp, -OtherOp103// mul OtherOp, (select Cond, 1, -1) --> select Cond, OtherOp, -OtherOp104if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_One(), m_AllOnes())),105m_Value(OtherOp)))) {106bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();107Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);108return Builder.CreateSelect(Cond, OtherOp, Neg);109}110// mul (select Cond, -1, 1), OtherOp --> select Cond, -OtherOp, OtherOp111// mul OtherOp, (select Cond, -1, 1) --> select Cond, -OtherOp, OtherOp112if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_AllOnes(), m_One())),113m_Value(OtherOp)))) {114bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();115Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);116return Builder.CreateSelect(Cond, Neg, OtherOp);117}118119// fmul (select Cond, 1.0, -1.0), OtherOp --> select Cond, OtherOp, -OtherOp120// fmul OtherOp, (select Cond, 1.0, -1.0) --> select Cond, OtherOp, -OtherOp121if (match(&I, m_c_FMul(m_OneUse(m_Select(m_Value(Cond), m_SpecificFP(1.0),122m_SpecificFP(-1.0))),123m_Value(OtherOp)))) {124IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);125Builder.setFastMathFlags(I.getFastMathFlags());126return Builder.CreateSelect(Cond, OtherOp, Builder.CreateFNeg(OtherOp));127}128129// fmul (select Cond, -1.0, 1.0), OtherOp --> select Cond, -OtherOp, OtherOp130// fmul OtherOp, (select Cond, -1.0, 1.0) --> select Cond, -OtherOp, OtherOp131if (match(&I, m_c_FMul(m_OneUse(m_Select(m_Value(Cond), m_SpecificFP(-1.0),132m_SpecificFP(1.0))),133m_Value(OtherOp)))) {134IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);135Builder.setFastMathFlags(I.getFastMathFlags());136return Builder.CreateSelect(Cond, Builder.CreateFNeg(OtherOp), OtherOp);137}138139return nullptr;140}141142/// Reduce integer multiplication patterns that contain a (+/-1 << Z) factor.143/// Callers are expected to call this twice to handle commuted patterns.144static Value *foldMulShl1(BinaryOperator &Mul, bool CommuteOperands,145InstCombiner::BuilderTy &Builder) {146Value *X = Mul.getOperand(0), *Y = Mul.getOperand(1);147if (CommuteOperands)148std::swap(X, Y);149150const bool HasNSW = Mul.hasNoSignedWrap();151const bool HasNUW = Mul.hasNoUnsignedWrap();152153// X * (1 << Z) --> X << Z154Value *Z;155if (match(Y, m_Shl(m_One(), m_Value(Z)))) {156bool PropagateNSW = HasNSW && cast<ShlOperator>(Y)->hasNoSignedWrap();157return Builder.CreateShl(X, Z, Mul.getName(), HasNUW, PropagateNSW);158}159160// Similar to above, but an increment of the shifted value becomes an add:161// X * ((1 << Z) + 1) --> (X * (1 << Z)) + X --> (X << Z) + X162// This increases uses of X, so it may require a freeze, but that is still163// expected to be an improvement because it removes the multiply.164BinaryOperator *Shift;165if (match(Y, m_OneUse(m_Add(m_BinOp(Shift), m_One()))) &&166match(Shift, m_OneUse(m_Shl(m_One(), m_Value(Z))))) {167bool PropagateNSW = HasNSW && Shift->hasNoSignedWrap();168Value *FrX = X;169if (!isGuaranteedNotToBeUndef(X))170FrX = Builder.CreateFreeze(X, X->getName() + ".fr");171Value *Shl = Builder.CreateShl(FrX, Z, "mulshl", HasNUW, PropagateNSW);172return Builder.CreateAdd(Shl, FrX, Mul.getName(), HasNUW, PropagateNSW);173}174175// Similar to above, but a decrement of the shifted value is disguised as176// 'not' and becomes a sub:177// X * (~(-1 << Z)) --> X * ((1 << Z) - 1) --> (X << Z) - X178// This increases uses of X, so it may require a freeze, but that is still179// expected to be an improvement because it removes the multiply.180if (match(Y, m_OneUse(m_Not(m_OneUse(m_Shl(m_AllOnes(), m_Value(Z))))))) {181Value *FrX = X;182if (!isGuaranteedNotToBeUndef(X))183FrX = Builder.CreateFreeze(X, X->getName() + ".fr");184Value *Shl = Builder.CreateShl(FrX, Z, "mulshl");185return Builder.CreateSub(Shl, FrX, Mul.getName());186}187188return nullptr;189}190191static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,192bool AssumeNonZero, bool DoFold);193194Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {195Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);196if (Value *V =197simplifyMulInst(Op0, Op1, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),198SQ.getWithInstruction(&I)))199return replaceInstUsesWith(I, V);200201if (SimplifyAssociativeOrCommutative(I))202return &I;203204if (Instruction *X = foldVectorBinop(I))205return X;206207if (Instruction *Phi = foldBinopWithPhiOperands(I))208return Phi;209210if (Value *V = foldUsingDistributiveLaws(I))211return replaceInstUsesWith(I, V);212213Type *Ty = I.getType();214const unsigned BitWidth = Ty->getScalarSizeInBits();215const bool HasNSW = I.hasNoSignedWrap();216const bool HasNUW = I.hasNoUnsignedWrap();217218// X * -1 --> 0 - X219if (match(Op1, m_AllOnes())) {220return HasNSW ? BinaryOperator::CreateNSWNeg(Op0)221: BinaryOperator::CreateNeg(Op0);222}223224// Also allow combining multiply instructions on vectors.225{226Value *NewOp;227Constant *C1, *C2;228const APInt *IVal;229if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_ImmConstant(C2)),230m_ImmConstant(C1))) &&231match(C1, m_APInt(IVal))) {232// ((X << C2)*C1) == (X * (C1 << C2))233Constant *Shl =234ConstantFoldBinaryOpOperands(Instruction::Shl, C1, C2, DL);235assert(Shl && "Constant folding of immediate constants failed");236BinaryOperator *Mul = cast<BinaryOperator>(I.getOperand(0));237BinaryOperator *BO = BinaryOperator::CreateMul(NewOp, Shl);238if (HasNUW && Mul->hasNoUnsignedWrap())239BO->setHasNoUnsignedWrap();240if (HasNSW && Mul->hasNoSignedWrap() && Shl->isNotMinSignedValue())241BO->setHasNoSignedWrap();242return BO;243}244245if (match(&I, m_Mul(m_Value(NewOp), m_Constant(C1)))) {246// Replace X*(2^C) with X << C, where C is either a scalar or a vector.247if (Constant *NewCst = ConstantExpr::getExactLogBase2(C1)) {248BinaryOperator *Shl = BinaryOperator::CreateShl(NewOp, NewCst);249250if (HasNUW)251Shl->setHasNoUnsignedWrap();252if (HasNSW) {253const APInt *V;254if (match(NewCst, m_APInt(V)) && *V != V->getBitWidth() - 1)255Shl->setHasNoSignedWrap();256}257258return Shl;259}260}261}262263if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) {264// Interpret X * (-1<<C) as (-X) * (1<<C) and try to sink the negation.265// The "* (1<<C)" thus becomes a potential shifting opportunity.266if (Value *NegOp0 =267Negator::Negate(/*IsNegation*/ true, HasNSW, Op0, *this)) {268auto *Op1C = cast<Constant>(Op1);269return replaceInstUsesWith(270I, Builder.CreateMul(NegOp0, ConstantExpr::getNeg(Op1C), "",271/* HasNUW */ false,272HasNSW && Op1C->isNotMinSignedValue()));273}274275// Try to convert multiply of extended operand to narrow negate and shift276// for better analysis.277// This is valid if the shift amount (trailing zeros in the multiplier278// constant) clears more high bits than the bitwidth difference between279// source and destination types:280// ({z/s}ext X) * (-1<<C) --> (zext (-X)) << C281const APInt *NegPow2C;282Value *X;283if (match(Op0, m_ZExtOrSExt(m_Value(X))) &&284match(Op1, m_APIntAllowPoison(NegPow2C))) {285unsigned SrcWidth = X->getType()->getScalarSizeInBits();286unsigned ShiftAmt = NegPow2C->countr_zero();287if (ShiftAmt >= BitWidth - SrcWidth) {288Value *N = Builder.CreateNeg(X, X->getName() + ".neg");289Value *Z = Builder.CreateZExt(N, Ty, N->getName() + ".z");290return BinaryOperator::CreateShl(Z, ConstantInt::get(Ty, ShiftAmt));291}292}293}294295if (Instruction *FoldedMul = foldBinOpIntoSelectOrPhi(I))296return FoldedMul;297298if (Value *FoldedMul = foldMulSelectToNegate(I, Builder))299return replaceInstUsesWith(I, FoldedMul);300301// Simplify mul instructions with a constant RHS.302Constant *MulC;303if (match(Op1, m_ImmConstant(MulC))) {304// Canonicalize (X+C1)*MulC -> X*MulC+C1*MulC.305// Canonicalize (X|C1)*MulC -> X*MulC+C1*MulC.306Value *X;307Constant *C1;308if (match(Op0, m_OneUse(m_AddLike(m_Value(X), m_ImmConstant(C1))))) {309// C1*MulC simplifies to a tidier constant.310Value *NewC = Builder.CreateMul(C1, MulC);311auto *BOp0 = cast<BinaryOperator>(Op0);312bool Op0NUW =313(BOp0->getOpcode() == Instruction::Or || BOp0->hasNoUnsignedWrap());314Value *NewMul = Builder.CreateMul(X, MulC);315auto *BO = BinaryOperator::CreateAdd(NewMul, NewC);316if (HasNUW && Op0NUW) {317// If NewMulBO is constant we also can set BO to nuw.318if (auto *NewMulBO = dyn_cast<BinaryOperator>(NewMul))319NewMulBO->setHasNoUnsignedWrap();320BO->setHasNoUnsignedWrap();321}322return BO;323}324}325326// abs(X) * abs(X) -> X * X327Value *X;328if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))))329return BinaryOperator::CreateMul(X, X);330331{332Value *Y;333// abs(X) * abs(Y) -> abs(X * Y)334if (I.hasNoSignedWrap() &&335match(Op0,336m_OneUse(m_Intrinsic<Intrinsic::abs>(m_Value(X), m_One()))) &&337match(Op1, m_OneUse(m_Intrinsic<Intrinsic::abs>(m_Value(Y), m_One()))))338return replaceInstUsesWith(339I, Builder.CreateBinaryIntrinsic(Intrinsic::abs,340Builder.CreateNSWMul(X, Y),341Builder.getTrue()));342}343344// -X * C --> X * -C345Value *Y;346Constant *Op1C;347if (match(Op0, m_Neg(m_Value(X))) && match(Op1, m_Constant(Op1C)))348return BinaryOperator::CreateMul(X, ConstantExpr::getNeg(Op1C));349350// -X * -Y --> X * Y351if (match(Op0, m_Neg(m_Value(X))) && match(Op1, m_Neg(m_Value(Y)))) {352auto *NewMul = BinaryOperator::CreateMul(X, Y);353if (HasNSW && cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap() &&354cast<OverflowingBinaryOperator>(Op1)->hasNoSignedWrap())355NewMul->setHasNoSignedWrap();356return NewMul;357}358359// -X * Y --> -(X * Y)360// X * -Y --> -(X * Y)361if (match(&I, m_c_Mul(m_OneUse(m_Neg(m_Value(X))), m_Value(Y))))362return BinaryOperator::CreateNeg(Builder.CreateMul(X, Y));363364// (-X * Y) * -X --> (X * Y) * X365// (-X << Y) * -X --> (X << Y) * X366if (match(Op1, m_Neg(m_Value(X)))) {367if (Value *NegOp0 = Negator::Negate(false, /*IsNSW*/ false, Op0, *this))368return BinaryOperator::CreateMul(NegOp0, X);369}370371if (Op0->hasOneUse()) {372// (mul (div exact X, C0), C1)373// -> (div exact X, C0 / C1)374// iff C0 % C1 == 0 and X / (C0 / C1) doesn't create UB.375const APInt *C1;376auto UDivCheck = [&C1](const APInt &C) { return C.urem(*C1).isZero(); };377auto SDivCheck = [&C1](const APInt &C) {378APInt Quot, Rem;379APInt::sdivrem(C, *C1, Quot, Rem);380return Rem.isZero() && !Quot.isAllOnes();381};382if (match(Op1, m_APInt(C1)) &&383(match(Op0, m_Exact(m_UDiv(m_Value(X), m_CheckedInt(UDivCheck)))) ||384match(Op0, m_Exact(m_SDiv(m_Value(X), m_CheckedInt(SDivCheck)))))) {385auto BOpc = cast<BinaryOperator>(Op0)->getOpcode();386return BinaryOperator::CreateExact(387BOpc, X,388Builder.CreateBinOp(BOpc, cast<BinaryOperator>(Op0)->getOperand(1),389Op1));390}391}392393// (X / Y) * Y = X - (X % Y)394// (X / Y) * -Y = (X % Y) - X395{396Value *Y = Op1;397BinaryOperator *Div = dyn_cast<BinaryOperator>(Op0);398if (!Div || (Div->getOpcode() != Instruction::UDiv &&399Div->getOpcode() != Instruction::SDiv)) {400Y = Op0;401Div = dyn_cast<BinaryOperator>(Op1);402}403Value *Neg = dyn_castNegVal(Y);404if (Div && Div->hasOneUse() &&405(Div->getOperand(1) == Y || Div->getOperand(1) == Neg) &&406(Div->getOpcode() == Instruction::UDiv ||407Div->getOpcode() == Instruction::SDiv)) {408Value *X = Div->getOperand(0), *DivOp1 = Div->getOperand(1);409410// If the division is exact, X % Y is zero, so we end up with X or -X.411if (Div->isExact()) {412if (DivOp1 == Y)413return replaceInstUsesWith(I, X);414return BinaryOperator::CreateNeg(X);415}416417auto RemOpc = Div->getOpcode() == Instruction::UDiv ? Instruction::URem418: Instruction::SRem;419// X must be frozen because we are increasing its number of uses.420Value *XFreeze = X;421if (!isGuaranteedNotToBeUndef(X))422XFreeze = Builder.CreateFreeze(X, X->getName() + ".fr");423Value *Rem = Builder.CreateBinOp(RemOpc, XFreeze, DivOp1);424if (DivOp1 == Y)425return BinaryOperator::CreateSub(XFreeze, Rem);426return BinaryOperator::CreateSub(Rem, XFreeze);427}428}429430// Fold the following two scenarios:431// 1) i1 mul -> i1 and.432// 2) X * Y --> X & Y, iff X, Y can be only {0,1}.433// Note: We could use known bits to generalize this and related patterns with434// shifts/truncs435if (Ty->isIntOrIntVectorTy(1) ||436(match(Op0, m_And(m_Value(), m_One())) &&437match(Op1, m_And(m_Value(), m_One()))))438return BinaryOperator::CreateAnd(Op0, Op1);439440if (Value *R = foldMulShl1(I, /* CommuteOperands */ false, Builder))441return replaceInstUsesWith(I, R);442if (Value *R = foldMulShl1(I, /* CommuteOperands */ true, Builder))443return replaceInstUsesWith(I, R);444445// (zext bool X) * (zext bool Y) --> zext (and X, Y)446// (sext bool X) * (sext bool Y) --> zext (and X, Y)447// Note: -1 * -1 == 1 * 1 == 1 (if the extends match, the result is the same)448if (((match(Op0, m_ZExt(m_Value(X))) && match(Op1, m_ZExt(m_Value(Y)))) ||449(match(Op0, m_SExt(m_Value(X))) && match(Op1, m_SExt(m_Value(Y))))) &&450X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&451(Op0->hasOneUse() || Op1->hasOneUse() || X == Y)) {452Value *And = Builder.CreateAnd(X, Y, "mulbool");453return CastInst::Create(Instruction::ZExt, And, Ty);454}455// (sext bool X) * (zext bool Y) --> sext (and X, Y)456// (zext bool X) * (sext bool Y) --> sext (and X, Y)457// Note: -1 * 1 == 1 * -1 == -1458if (((match(Op0, m_SExt(m_Value(X))) && match(Op1, m_ZExt(m_Value(Y)))) ||459(match(Op0, m_ZExt(m_Value(X))) && match(Op1, m_SExt(m_Value(Y))))) &&460X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&461(Op0->hasOneUse() || Op1->hasOneUse())) {462Value *And = Builder.CreateAnd(X, Y, "mulbool");463return CastInst::Create(Instruction::SExt, And, Ty);464}465466// (zext bool X) * Y --> X ? Y : 0467// Y * (zext bool X) --> X ? Y : 0468if (match(Op0, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))469return SelectInst::Create(X, Op1, ConstantInt::getNullValue(Ty));470if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))471return SelectInst::Create(X, Op0, ConstantInt::getNullValue(Ty));472473// mul (sext X), Y -> select X, -Y, 0474// mul Y, (sext X) -> select X, -Y, 0475if (match(&I, m_c_Mul(m_OneUse(m_SExt(m_Value(X))), m_Value(Y))) &&476X->getType()->isIntOrIntVectorTy(1))477return SelectInst::Create(X, Builder.CreateNeg(Y, "", I.hasNoSignedWrap()),478ConstantInt::getNullValue(Op0->getType()));479480Constant *ImmC;481if (match(Op1, m_ImmConstant(ImmC))) {482// (sext bool X) * C --> X ? -C : 0483if (match(Op0, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {484Constant *NegC = ConstantExpr::getNeg(ImmC);485return SelectInst::Create(X, NegC, ConstantInt::getNullValue(Ty));486}487488// (ashr i32 X, 31) * C --> (X < 0) ? -C : 0489const APInt *C;490if (match(Op0, m_OneUse(m_AShr(m_Value(X), m_APInt(C)))) &&491*C == C->getBitWidth() - 1) {492Constant *NegC = ConstantExpr::getNeg(ImmC);493Value *IsNeg = Builder.CreateIsNeg(X, "isneg");494return SelectInst::Create(IsNeg, NegC, ConstantInt::getNullValue(Ty));495}496}497498// (lshr X, 31) * Y --> (X < 0) ? Y : 0499// TODO: We are not checking one-use because the elimination of the multiply500// is better for analysis?501const APInt *C;502if (match(&I, m_c_BinOp(m_LShr(m_Value(X), m_APInt(C)), m_Value(Y))) &&503*C == C->getBitWidth() - 1) {504Value *IsNeg = Builder.CreateIsNeg(X, "isneg");505return SelectInst::Create(IsNeg, Y, ConstantInt::getNullValue(Ty));506}507508// (and X, 1) * Y --> (trunc X) ? Y : 0509if (match(&I, m_c_BinOp(m_OneUse(m_And(m_Value(X), m_One())), m_Value(Y)))) {510Value *Tr = Builder.CreateTrunc(X, CmpInst::makeCmpResultType(Ty));511return SelectInst::Create(Tr, Y, ConstantInt::getNullValue(Ty));512}513514// ((ashr X, 31) | 1) * X --> abs(X)515// X * ((ashr X, 31) | 1) --> abs(X)516if (match(&I, m_c_BinOp(m_Or(m_AShr(m_Value(X),517m_SpecificIntAllowPoison(BitWidth - 1)),518m_One()),519m_Deferred(X)))) {520Value *Abs = Builder.CreateBinaryIntrinsic(521Intrinsic::abs, X, ConstantInt::getBool(I.getContext(), HasNSW));522Abs->takeName(&I);523return replaceInstUsesWith(I, Abs);524}525526if (Instruction *Ext = narrowMathIfNoOverflow(I))527return Ext;528529if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I))530return Res;531532// (mul Op0 Op1):533// if Log2(Op0) folds away ->534// (shl Op1, Log2(Op0))535// if Log2(Op1) folds away ->536// (shl Op0, Log2(Op1))537if (takeLog2(Builder, Op0, /*Depth*/ 0, /*AssumeNonZero*/ false,538/*DoFold*/ false)) {539Value *Res = takeLog2(Builder, Op0, /*Depth*/ 0, /*AssumeNonZero*/ false,540/*DoFold*/ true);541BinaryOperator *Shl = BinaryOperator::CreateShl(Op1, Res);542// We can only propegate nuw flag.543Shl->setHasNoUnsignedWrap(HasNUW);544return Shl;545}546if (takeLog2(Builder, Op1, /*Depth*/ 0, /*AssumeNonZero*/ false,547/*DoFold*/ false)) {548Value *Res = takeLog2(Builder, Op1, /*Depth*/ 0, /*AssumeNonZero*/ false,549/*DoFold*/ true);550BinaryOperator *Shl = BinaryOperator::CreateShl(Op0, Res);551// We can only propegate nuw flag.552Shl->setHasNoUnsignedWrap(HasNUW);553return Shl;554}555556bool Changed = false;557if (!HasNSW && willNotOverflowSignedMul(Op0, Op1, I)) {558Changed = true;559I.setHasNoSignedWrap(true);560}561562if (!HasNUW && willNotOverflowUnsignedMul(Op0, Op1, I, I.hasNoSignedWrap())) {563Changed = true;564I.setHasNoUnsignedWrap(true);565}566567return Changed ? &I : nullptr;568}569570Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {571BinaryOperator::BinaryOps Opcode = I.getOpcode();572assert((Opcode == Instruction::FMul || Opcode == Instruction::FDiv) &&573"Expected fmul or fdiv");574575Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);576Value *X, *Y;577578// -X * -Y --> X * Y579// -X / -Y --> X / Y580if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))581return BinaryOperator::CreateWithCopiedFlags(Opcode, X, Y, &I);582583// fabs(X) * fabs(X) -> X * X584// fabs(X) / fabs(X) -> X / X585if (Op0 == Op1 && match(Op0, m_FAbs(m_Value(X))))586return BinaryOperator::CreateWithCopiedFlags(Opcode, X, X, &I);587588// fabs(X) * fabs(Y) --> fabs(X * Y)589// fabs(X) / fabs(Y) --> fabs(X / Y)590if (match(Op0, m_FAbs(m_Value(X))) && match(Op1, m_FAbs(m_Value(Y))) &&591(Op0->hasOneUse() || Op1->hasOneUse())) {592IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);593Builder.setFastMathFlags(I.getFastMathFlags());594Value *XY = Builder.CreateBinOp(Opcode, X, Y);595Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, XY);596Fabs->takeName(&I);597return replaceInstUsesWith(I, Fabs);598}599600return nullptr;601}602603Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) {604auto createPowiExpr = [](BinaryOperator &I, InstCombinerImpl &IC, Value *X,605Value *Y, Value *Z) {606InstCombiner::BuilderTy &Builder = IC.Builder;607Value *YZ = Builder.CreateAdd(Y, Z);608Instruction *NewPow = Builder.CreateIntrinsic(609Intrinsic::powi, {X->getType(), YZ->getType()}, {X, YZ}, &I);610611return NewPow;612};613614Value *X, *Y, *Z;615unsigned Opcode = I.getOpcode();616assert((Opcode == Instruction::FMul || Opcode == Instruction::FDiv) &&617"Unexpected opcode");618619// powi(X, Y) * X --> powi(X, Y+1)620// X * powi(X, Y) --> powi(X, Y+1)621if (match(&I, m_c_FMul(m_OneUse(m_AllowReassoc(m_Intrinsic<Intrinsic::powi>(622m_Value(X), m_Value(Y)))),623m_Deferred(X)))) {624Constant *One = ConstantInt::get(Y->getType(), 1);625if (willNotOverflowSignedAdd(Y, One, I)) {626Instruction *NewPow = createPowiExpr(I, *this, X, Y, One);627return replaceInstUsesWith(I, NewPow);628}629}630631// powi(x, y) * powi(x, z) -> powi(x, y + z)632Value *Op0 = I.getOperand(0);633Value *Op1 = I.getOperand(1);634if (Opcode == Instruction::FMul && I.isOnlyUserOfAnyOperand() &&635match(Op0, m_AllowReassoc(636m_Intrinsic<Intrinsic::powi>(m_Value(X), m_Value(Y)))) &&637match(Op1, m_AllowReassoc(m_Intrinsic<Intrinsic::powi>(m_Specific(X),638m_Value(Z)))) &&639Y->getType() == Z->getType()) {640Instruction *NewPow = createPowiExpr(I, *this, X, Y, Z);641return replaceInstUsesWith(I, NewPow);642}643644if (Opcode == Instruction::FDiv && I.hasAllowReassoc() && I.hasNoNaNs()) {645// powi(X, Y) / X --> powi(X, Y-1)646// This is legal when (Y - 1) can't wraparound, in which case reassoc and647// nnan are required.648// TODO: Multi-use may be also better off creating Powi(x,y-1)649if (match(Op0, m_OneUse(m_AllowReassoc(m_Intrinsic<Intrinsic::powi>(650m_Specific(Op1), m_Value(Y))))) &&651willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {652Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType());653Instruction *NewPow = createPowiExpr(I, *this, Op1, Y, NegOne);654return replaceInstUsesWith(I, NewPow);655}656657// powi(X, Y) / (X * Z) --> powi(X, Y-1) / Z658// This is legal when (Y - 1) can't wraparound, in which case reassoc and659// nnan are required.660// TODO: Multi-use may be also better off creating Powi(x,y-1)661if (match(Op0, m_OneUse(m_AllowReassoc(m_Intrinsic<Intrinsic::powi>(662m_Value(X), m_Value(Y))))) &&663match(Op1, m_AllowReassoc(m_c_FMul(m_Specific(X), m_Value(Z)))) &&664willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {665Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType());666auto *NewPow = createPowiExpr(I, *this, X, Y, NegOne);667return BinaryOperator::CreateFDivFMF(NewPow, Z, &I);668}669}670671return nullptr;672}673674Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {675Value *Op0 = I.getOperand(0);676Value *Op1 = I.getOperand(1);677Value *X, *Y;678Constant *C;679BinaryOperator *Op0BinOp;680681// Reassociate constant RHS with another constant to form constant682// expression.683if (match(Op1, m_Constant(C)) && C->isFiniteNonZeroFP() &&684match(Op0, m_AllowReassoc(m_BinOp(Op0BinOp)))) {685// Everything in this scope folds I with Op0, intersecting their FMF.686FastMathFlags FMF = I.getFastMathFlags() & Op0BinOp->getFastMathFlags();687IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);688Builder.setFastMathFlags(FMF);689Constant *C1;690if (match(Op0, m_OneUse(m_FDiv(m_Constant(C1), m_Value(X))))) {691// (C1 / X) * C --> (C * C1) / X692Constant *CC1 =693ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL);694if (CC1 && CC1->isNormalFP())695return BinaryOperator::CreateFDivFMF(CC1, X, FMF);696}697if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) {698// FIXME: This seems like it should also be checking for arcp699// (X / C1) * C --> X * (C / C1)700Constant *CDivC1 =701ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C1, DL);702if (CDivC1 && CDivC1->isNormalFP())703return BinaryOperator::CreateFMulFMF(X, CDivC1, FMF);704705// If the constant was a denormal, try reassociating differently.706// (X / C1) * C --> X / (C1 / C)707Constant *C1DivC =708ConstantFoldBinaryOpOperands(Instruction::FDiv, C1, C, DL);709if (C1DivC && Op0->hasOneUse() && C1DivC->isNormalFP())710return BinaryOperator::CreateFDivFMF(X, C1DivC, FMF);711}712713// We do not need to match 'fadd C, X' and 'fsub X, C' because they are714// canonicalized to 'fadd X, C'. Distributing the multiply may allow715// further folds and (X * C) + C2 is 'fma'.716if (match(Op0, m_OneUse(m_FAdd(m_Value(X), m_Constant(C1))))) {717// (X + C1) * C --> (X * C) + (C * C1)718if (Constant *CC1 =719ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL)) {720Value *XC = Builder.CreateFMul(X, C);721return BinaryOperator::CreateFAddFMF(XC, CC1, FMF);722}723}724if (match(Op0, m_OneUse(m_FSub(m_Constant(C1), m_Value(X))))) {725// (C1 - X) * C --> (C * C1) - (X * C)726if (Constant *CC1 =727ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL)) {728Value *XC = Builder.CreateFMul(X, C);729return BinaryOperator::CreateFSubFMF(CC1, XC, FMF);730}731}732}733734Value *Z;735if (match(&I,736m_c_FMul(m_AllowReassoc(m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))),737m_Value(Z)))) {738BinaryOperator *DivOp = cast<BinaryOperator>(((Z == Op0) ? Op1 : Op0));739FastMathFlags FMF = I.getFastMathFlags() & DivOp->getFastMathFlags();740if (FMF.allowReassoc()) {741// Sink division: (X / Y) * Z --> (X * Z) / Y742IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);743Builder.setFastMathFlags(FMF);744auto *NewFMul = Builder.CreateFMul(X, Z);745return BinaryOperator::CreateFDivFMF(NewFMul, Y, FMF);746}747}748749// sqrt(X) * sqrt(Y) -> sqrt(X * Y)750// nnan disallows the possibility of returning a number if both operands are751// negative (in that case, we should return NaN).752if (I.hasNoNaNs() && match(Op0, m_OneUse(m_Sqrt(m_Value(X)))) &&753match(Op1, m_OneUse(m_Sqrt(m_Value(Y))))) {754Value *XY = Builder.CreateFMulFMF(X, Y, &I);755Value *Sqrt = Builder.CreateUnaryIntrinsic(Intrinsic::sqrt, XY, &I);756return replaceInstUsesWith(I, Sqrt);757}758759// The following transforms are done irrespective of the number of uses760// for the expression "1.0/sqrt(X)".761// 1) 1.0/sqrt(X) * X -> X/sqrt(X)762// 2) X * 1.0/sqrt(X) -> X/sqrt(X)763// We always expect the backend to reduce X/sqrt(X) to sqrt(X), if it764// has the necessary (reassoc) fast-math-flags.765if (I.hasNoSignedZeros() &&766match(Op0, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&767match(Y, m_Sqrt(m_Value(X))) && Op1 == X)768return BinaryOperator::CreateFDivFMF(X, Y, &I);769if (I.hasNoSignedZeros() &&770match(Op1, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&771match(Y, m_Sqrt(m_Value(X))) && Op0 == X)772return BinaryOperator::CreateFDivFMF(X, Y, &I);773774// Like the similar transform in instsimplify, this requires 'nsz' because775// sqrt(-0.0) = -0.0, and -0.0 * -0.0 does not simplify to -0.0.776if (I.hasNoNaNs() && I.hasNoSignedZeros() && Op0 == Op1 && Op0->hasNUses(2)) {777// Peek through fdiv to find squaring of square root:778// (X / sqrt(Y)) * (X / sqrt(Y)) --> (X * X) / Y779if (match(Op0, m_FDiv(m_Value(X), m_Sqrt(m_Value(Y))))) {780Value *XX = Builder.CreateFMulFMF(X, X, &I);781return BinaryOperator::CreateFDivFMF(XX, Y, &I);782}783// (sqrt(Y) / X) * (sqrt(Y) / X) --> Y / (X * X)784if (match(Op0, m_FDiv(m_Sqrt(m_Value(Y)), m_Value(X)))) {785Value *XX = Builder.CreateFMulFMF(X, X, &I);786return BinaryOperator::CreateFDivFMF(Y, XX, &I);787}788}789790// pow(X, Y) * X --> pow(X, Y+1)791// X * pow(X, Y) --> pow(X, Y+1)792if (match(&I, m_c_FMul(m_OneUse(m_Intrinsic<Intrinsic::pow>(m_Value(X),793m_Value(Y))),794m_Deferred(X)))) {795Value *Y1 = Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), 1.0), &I);796Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, Y1, &I);797return replaceInstUsesWith(I, Pow);798}799800if (Instruction *FoldedPowi = foldPowiReassoc(I))801return FoldedPowi;802803if (I.isOnlyUserOfAnyOperand()) {804// pow(X, Y) * pow(X, Z) -> pow(X, Y + Z)805if (match(Op0, m_Intrinsic<Intrinsic::pow>(m_Value(X), m_Value(Y))) &&806match(Op1, m_Intrinsic<Intrinsic::pow>(m_Specific(X), m_Value(Z)))) {807auto *YZ = Builder.CreateFAddFMF(Y, Z, &I);808auto *NewPow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, YZ, &I);809return replaceInstUsesWith(I, NewPow);810}811// pow(X, Y) * pow(Z, Y) -> pow(X * Z, Y)812if (match(Op0, m_Intrinsic<Intrinsic::pow>(m_Value(X), m_Value(Y))) &&813match(Op1, m_Intrinsic<Intrinsic::pow>(m_Value(Z), m_Specific(Y)))) {814auto *XZ = Builder.CreateFMulFMF(X, Z, &I);815auto *NewPow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, XZ, Y, &I);816return replaceInstUsesWith(I, NewPow);817}818819// exp(X) * exp(Y) -> exp(X + Y)820if (match(Op0, m_Intrinsic<Intrinsic::exp>(m_Value(X))) &&821match(Op1, m_Intrinsic<Intrinsic::exp>(m_Value(Y)))) {822Value *XY = Builder.CreateFAddFMF(X, Y, &I);823Value *Exp = Builder.CreateUnaryIntrinsic(Intrinsic::exp, XY, &I);824return replaceInstUsesWith(I, Exp);825}826827// exp2(X) * exp2(Y) -> exp2(X + Y)828if (match(Op0, m_Intrinsic<Intrinsic::exp2>(m_Value(X))) &&829match(Op1, m_Intrinsic<Intrinsic::exp2>(m_Value(Y)))) {830Value *XY = Builder.CreateFAddFMF(X, Y, &I);831Value *Exp2 = Builder.CreateUnaryIntrinsic(Intrinsic::exp2, XY, &I);832return replaceInstUsesWith(I, Exp2);833}834}835836// (X*Y) * X => (X*X) * Y where Y != X837// The purpose is two-fold:838// 1) to form a power expression (of X).839// 2) potentially shorten the critical path: After transformation, the840// latency of the instruction Y is amortized by the expression of X*X,841// and therefore Y is in a "less critical" position compared to what it842// was before the transformation.843if (match(Op0, m_OneUse(m_c_FMul(m_Specific(Op1), m_Value(Y)))) && Op1 != Y) {844Value *XX = Builder.CreateFMulFMF(Op1, Op1, &I);845return BinaryOperator::CreateFMulFMF(XX, Y, &I);846}847if (match(Op1, m_OneUse(m_c_FMul(m_Specific(Op0), m_Value(Y)))) && Op0 != Y) {848Value *XX = Builder.CreateFMulFMF(Op0, Op0, &I);849return BinaryOperator::CreateFMulFMF(XX, Y, &I);850}851852return nullptr;853}854855Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {856if (Value *V = simplifyFMulInst(I.getOperand(0), I.getOperand(1),857I.getFastMathFlags(),858SQ.getWithInstruction(&I)))859return replaceInstUsesWith(I, V);860861if (SimplifyAssociativeOrCommutative(I))862return &I;863864if (Instruction *X = foldVectorBinop(I))865return X;866867if (Instruction *Phi = foldBinopWithPhiOperands(I))868return Phi;869870if (Instruction *FoldedMul = foldBinOpIntoSelectOrPhi(I))871return FoldedMul;872873if (Value *FoldedMul = foldMulSelectToNegate(I, Builder))874return replaceInstUsesWith(I, FoldedMul);875876if (Instruction *R = foldFPSignBitOps(I))877return R;878879if (Instruction *R = foldFBinOpOfIntCasts(I))880return R;881882// X * -1.0 --> -X883Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);884if (match(Op1, m_SpecificFP(-1.0)))885return UnaryOperator::CreateFNegFMF(Op0, &I);886887// With no-nans/no-infs:888// X * 0.0 --> copysign(0.0, X)889// X * -0.0 --> copysign(0.0, -X)890const APFloat *FPC;891if (match(Op1, m_APFloatAllowPoison(FPC)) && FPC->isZero() &&892((I.hasNoInfs() &&893isKnownNeverNaN(Op0, /*Depth=*/0, SQ.getWithInstruction(&I))) ||894isKnownNeverNaN(&I, /*Depth=*/0, SQ.getWithInstruction(&I)))) {895if (FPC->isNegative())896Op0 = Builder.CreateFNegFMF(Op0, &I);897CallInst *CopySign = Builder.CreateIntrinsic(Intrinsic::copysign,898{I.getType()}, {Op1, Op0}, &I);899return replaceInstUsesWith(I, CopySign);900}901902// -X * C --> X * -C903Value *X, *Y;904Constant *C;905if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_Constant(C)))906if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))907return BinaryOperator::CreateFMulFMF(X, NegC, &I);908909if (I.hasNoNaNs() && I.hasNoSignedZeros()) {910// (uitofp bool X) * Y --> X ? Y : 0911// Y * (uitofp bool X) --> X ? Y : 0912// Note INF * 0 is NaN.913if (match(Op0, m_UIToFP(m_Value(X))) &&914X->getType()->isIntOrIntVectorTy(1)) {915auto *SI = SelectInst::Create(X, Op1, ConstantFP::get(I.getType(), 0.0));916SI->copyFastMathFlags(I.getFastMathFlags());917return SI;918}919if (match(Op1, m_UIToFP(m_Value(X))) &&920X->getType()->isIntOrIntVectorTy(1)) {921auto *SI = SelectInst::Create(X, Op0, ConstantFP::get(I.getType(), 0.0));922SI->copyFastMathFlags(I.getFastMathFlags());923return SI;924}925}926927// (select A, B, C) * (select A, D, E) --> select A, (B*D), (C*E)928if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))929return replaceInstUsesWith(I, V);930931if (I.hasAllowReassoc())932if (Instruction *FoldedMul = foldFMulReassoc(I))933return FoldedMul;934935// log2(X * 0.5) * Y = log2(X) * Y - Y936if (I.isFast()) {937IntrinsicInst *Log2 = nullptr;938if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::log2>(939m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {940Log2 = cast<IntrinsicInst>(Op0);941Y = Op1;942}943if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::log2>(944m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {945Log2 = cast<IntrinsicInst>(Op1);946Y = Op0;947}948if (Log2) {949Value *Log2 = Builder.CreateUnaryIntrinsic(Intrinsic::log2, X, &I);950Value *LogXTimesY = Builder.CreateFMulFMF(Log2, Y, &I);951return BinaryOperator::CreateFSubFMF(LogXTimesY, Y, &I);952}953}954955// Simplify FMUL recurrences starting with 0.0 to 0.0 if nnan and nsz are set.956// Given a phi node with entry value as 0 and it used in fmul operation,957// we can replace fmul with 0 safely and eleminate loop operation.958PHINode *PN = nullptr;959Value *Start = nullptr, *Step = nullptr;960if (matchSimpleRecurrence(&I, PN, Start, Step) && I.hasNoNaNs() &&961I.hasNoSignedZeros() && match(Start, m_Zero()))962return replaceInstUsesWith(I, Start);963964// minimum(X, Y) * maximum(X, Y) => X * Y.965if (match(&I,966m_c_FMul(m_Intrinsic<Intrinsic::maximum>(m_Value(X), m_Value(Y)),967m_c_Intrinsic<Intrinsic::minimum>(m_Deferred(X),968m_Deferred(Y))))) {969BinaryOperator *Result = BinaryOperator::CreateFMulFMF(X, Y, &I);970// We cannot preserve ninf if nnan flag is not set.971// If X is NaN and Y is Inf then in original program we had NaN * NaN,972// while in optimized version NaN * Inf and this is a poison with ninf flag.973if (!Result->hasNoNaNs())974Result->setHasNoInfs(false);975return Result;976}977978return nullptr;979}980981/// Fold a divide or remainder with a select instruction divisor when one of the982/// select operands is zero. In that case, we can use the other select operand983/// because div/rem by zero is undefined.984bool InstCombinerImpl::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {985SelectInst *SI = dyn_cast<SelectInst>(I.getOperand(1));986if (!SI)987return false;988989int NonNullOperand;990if (match(SI->getTrueValue(), m_Zero()))991// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y992NonNullOperand = 2;993else if (match(SI->getFalseValue(), m_Zero()))994// div/rem X, (Cond ? Y : 0) -> div/rem X, Y995NonNullOperand = 1;996else997return false;998999// Change the div/rem to use 'Y' instead of the select.1000replaceOperand(I, 1, SI->getOperand(NonNullOperand));10011002// Okay, we know we replace the operand of the div/rem with 'Y' with no1003// problem. However, the select, or the condition of the select may have1004// multiple uses. Based on our knowledge that the operand must be non-zero,1005// propagate the known value for the select into other uses of it, and1006// propagate a known value of the condition into its other users.10071008// If the select and condition only have a single use, don't bother with this,1009// early exit.1010Value *SelectCond = SI->getCondition();1011if (SI->use_empty() && SelectCond->hasOneUse())1012return true;10131014// Scan the current block backward, looking for other uses of SI.1015BasicBlock::iterator BBI = I.getIterator(), BBFront = I.getParent()->begin();1016Type *CondTy = SelectCond->getType();1017while (BBI != BBFront) {1018--BBI;1019// If we found an instruction that we can't assume will return, so1020// information from below it cannot be propagated above it.1021if (!isGuaranteedToTransferExecutionToSuccessor(&*BBI))1022break;10231024// Replace uses of the select or its condition with the known values.1025for (Use &Op : BBI->operands()) {1026if (Op == SI) {1027replaceUse(Op, SI->getOperand(NonNullOperand));1028Worklist.push(&*BBI);1029} else if (Op == SelectCond) {1030replaceUse(Op, NonNullOperand == 1 ? ConstantInt::getTrue(CondTy)1031: ConstantInt::getFalse(CondTy));1032Worklist.push(&*BBI);1033}1034}10351036// If we past the instruction, quit looking for it.1037if (&*BBI == SI)1038SI = nullptr;1039if (&*BBI == SelectCond)1040SelectCond = nullptr;10411042// If we ran out of things to eliminate, break out of the loop.1043if (!SelectCond && !SI)1044break;10451046}1047return true;1048}10491050/// True if the multiply can not be expressed in an int this size.1051static bool multiplyOverflows(const APInt &C1, const APInt &C2, APInt &Product,1052bool IsSigned) {1053bool Overflow;1054Product = IsSigned ? C1.smul_ov(C2, Overflow) : C1.umul_ov(C2, Overflow);1055return Overflow;1056}10571058/// True if C1 is a multiple of C2. Quotient contains C1/C2.1059static bool isMultiple(const APInt &C1, const APInt &C2, APInt &Quotient,1060bool IsSigned) {1061assert(C1.getBitWidth() == C2.getBitWidth() && "Constant widths not equal");10621063// Bail if we will divide by zero.1064if (C2.isZero())1065return false;10661067// Bail if we would divide INT_MIN by -1.1068if (IsSigned && C1.isMinSignedValue() && C2.isAllOnes())1069return false;10701071APInt Remainder(C1.getBitWidth(), /*val=*/0ULL, IsSigned);1072if (IsSigned)1073APInt::sdivrem(C1, C2, Quotient, Remainder);1074else1075APInt::udivrem(C1, C2, Quotient, Remainder);10761077return Remainder.isMinValue();1078}10791080static Value *foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder) {1081assert((I.getOpcode() == Instruction::SDiv ||1082I.getOpcode() == Instruction::UDiv) &&1083"Expected integer divide");10841085bool IsSigned = I.getOpcode() == Instruction::SDiv;1086Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1087Type *Ty = I.getType();10881089Value *X, *Y, *Z;10901091// With appropriate no-wrap constraints, remove a common factor in the1092// dividend and divisor that is disguised as a left-shifted value.1093if (match(Op1, m_Shl(m_Value(X), m_Value(Z))) &&1094match(Op0, m_c_Mul(m_Specific(X), m_Value(Y)))) {1095// Both operands must have the matching no-wrap for this kind of division.1096auto *Mul = cast<OverflowingBinaryOperator>(Op0);1097auto *Shl = cast<OverflowingBinaryOperator>(Op1);1098bool HasNUW = Mul->hasNoUnsignedWrap() && Shl->hasNoUnsignedWrap();1099bool HasNSW = Mul->hasNoSignedWrap() && Shl->hasNoSignedWrap();11001101// (X * Y) u/ (X << Z) --> Y u>> Z1102if (!IsSigned && HasNUW)1103return Builder.CreateLShr(Y, Z, "", I.isExact());11041105// (X * Y) s/ (X << Z) --> Y s/ (1 << Z)1106if (IsSigned && HasNSW && (Op0->hasOneUse() || Op1->hasOneUse())) {1107Value *Shl = Builder.CreateShl(ConstantInt::get(Ty, 1), Z);1108return Builder.CreateSDiv(Y, Shl, "", I.isExact());1109}1110}11111112// With appropriate no-wrap constraints, remove a common factor in the1113// dividend and divisor that is disguised as a left-shift amount.1114if (match(Op0, m_Shl(m_Value(X), m_Value(Z))) &&1115match(Op1, m_Shl(m_Value(Y), m_Specific(Z)))) {1116auto *Shl0 = cast<OverflowingBinaryOperator>(Op0);1117auto *Shl1 = cast<OverflowingBinaryOperator>(Op1);11181119// For unsigned div, we need 'nuw' on both shifts or1120// 'nsw' on both shifts + 'nuw' on the dividend.1121// (X << Z) / (Y << Z) --> X / Y1122if (!IsSigned &&1123((Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap()) ||1124(Shl0->hasNoUnsignedWrap() && Shl0->hasNoSignedWrap() &&1125Shl1->hasNoSignedWrap())))1126return Builder.CreateUDiv(X, Y, "", I.isExact());11271128// For signed div, we need 'nsw' on both shifts + 'nuw' on the divisor.1129// (X << Z) / (Y << Z) --> X / Y1130if (IsSigned && Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap() &&1131Shl1->hasNoUnsignedWrap())1132return Builder.CreateSDiv(X, Y, "", I.isExact());1133}11341135// If X << Y and X << Z does not overflow, then:1136// (X << Y) / (X << Z) -> (1 << Y) / (1 << Z) -> 1 << Y >> Z1137if (match(Op0, m_Shl(m_Value(X), m_Value(Y))) &&1138match(Op1, m_Shl(m_Specific(X), m_Value(Z)))) {1139auto *Shl0 = cast<OverflowingBinaryOperator>(Op0);1140auto *Shl1 = cast<OverflowingBinaryOperator>(Op1);11411142if (IsSigned ? (Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap())1143: (Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap())) {1144Constant *One = ConstantInt::get(X->getType(), 1);1145// Only preserve the nsw flag if dividend has nsw1146// or divisor has nsw and operator is sdiv.1147Value *Dividend = Builder.CreateShl(1148One, Y, "shl.dividend",1149/*HasNUW*/ true,1150/*HasNSW*/1151IsSigned ? (Shl0->hasNoUnsignedWrap() || Shl1->hasNoUnsignedWrap())1152: Shl0->hasNoSignedWrap());1153return Builder.CreateLShr(Dividend, Z, "", I.isExact());1154}1155}11561157return nullptr;1158}11591160/// This function implements the transforms common to both integer division1161/// instructions (udiv and sdiv). It is called by the visitors to those integer1162/// division instructions.1163/// Common integer divide transforms1164Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {1165if (Instruction *Phi = foldBinopWithPhiOperands(I))1166return Phi;11671168Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1169bool IsSigned = I.getOpcode() == Instruction::SDiv;1170Type *Ty = I.getType();11711172// The RHS is known non-zero.1173if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this, I))1174return replaceOperand(I, 1, V);11751176// Handle cases involving: [su]div X, (select Cond, Y, Z)1177// This does not apply for fdiv.1178if (simplifyDivRemOfSelectWithZeroOp(I))1179return &I;11801181// If the divisor is a select-of-constants, try to constant fold all div ops:1182// C / (select Cond, TrueC, FalseC) --> select Cond, (C / TrueC), (C / FalseC)1183// TODO: Adapt simplifyDivRemOfSelectWithZeroOp to allow this and other folds.1184if (match(Op0, m_ImmConstant()) &&1185match(Op1, m_Select(m_Value(), m_ImmConstant(), m_ImmConstant()))) {1186if (Instruction *R = FoldOpIntoSelect(I, cast<SelectInst>(Op1),1187/*FoldWithMultiUse*/ true))1188return R;1189}11901191const APInt *C2;1192if (match(Op1, m_APInt(C2))) {1193Value *X;1194const APInt *C1;11951196// (X / C1) / C2 -> X / (C1*C2)1197if ((IsSigned && match(Op0, m_SDiv(m_Value(X), m_APInt(C1)))) ||1198(!IsSigned && match(Op0, m_UDiv(m_Value(X), m_APInt(C1))))) {1199APInt Product(C1->getBitWidth(), /*val=*/0ULL, IsSigned);1200if (!multiplyOverflows(*C1, *C2, Product, IsSigned))1201return BinaryOperator::Create(I.getOpcode(), X,1202ConstantInt::get(Ty, Product));1203}12041205APInt Quotient(C2->getBitWidth(), /*val=*/0ULL, IsSigned);1206if ((IsSigned && match(Op0, m_NSWMul(m_Value(X), m_APInt(C1)))) ||1207(!IsSigned && match(Op0, m_NUWMul(m_Value(X), m_APInt(C1))))) {12081209// (X * C1) / C2 -> X / (C2 / C1) if C2 is a multiple of C1.1210if (isMultiple(*C2, *C1, Quotient, IsSigned)) {1211auto *NewDiv = BinaryOperator::Create(I.getOpcode(), X,1212ConstantInt::get(Ty, Quotient));1213NewDiv->setIsExact(I.isExact());1214return NewDiv;1215}12161217// (X * C1) / C2 -> X * (C1 / C2) if C1 is a multiple of C2.1218if (isMultiple(*C1, *C2, Quotient, IsSigned)) {1219auto *Mul = BinaryOperator::Create(Instruction::Mul, X,1220ConstantInt::get(Ty, Quotient));1221auto *OBO = cast<OverflowingBinaryOperator>(Op0);1222Mul->setHasNoUnsignedWrap(!IsSigned && OBO->hasNoUnsignedWrap());1223Mul->setHasNoSignedWrap(OBO->hasNoSignedWrap());1224return Mul;1225}1226}12271228if ((IsSigned && match(Op0, m_NSWShl(m_Value(X), m_APInt(C1))) &&1229C1->ult(C1->getBitWidth() - 1)) ||1230(!IsSigned && match(Op0, m_NUWShl(m_Value(X), m_APInt(C1))) &&1231C1->ult(C1->getBitWidth()))) {1232APInt C1Shifted = APInt::getOneBitSet(1233C1->getBitWidth(), static_cast<unsigned>(C1->getZExtValue()));12341235// (X << C1) / C2 -> X / (C2 >> C1) if C2 is a multiple of 1 << C1.1236if (isMultiple(*C2, C1Shifted, Quotient, IsSigned)) {1237auto *BO = BinaryOperator::Create(I.getOpcode(), X,1238ConstantInt::get(Ty, Quotient));1239BO->setIsExact(I.isExact());1240return BO;1241}12421243// (X << C1) / C2 -> X * ((1 << C1) / C2) if 1 << C1 is a multiple of C2.1244if (isMultiple(C1Shifted, *C2, Quotient, IsSigned)) {1245auto *Mul = BinaryOperator::Create(Instruction::Mul, X,1246ConstantInt::get(Ty, Quotient));1247auto *OBO = cast<OverflowingBinaryOperator>(Op0);1248Mul->setHasNoUnsignedWrap(!IsSigned && OBO->hasNoUnsignedWrap());1249Mul->setHasNoSignedWrap(OBO->hasNoSignedWrap());1250return Mul;1251}1252}12531254// Distribute div over add to eliminate a matching div/mul pair:1255// ((X * C2) + C1) / C2 --> X + C1/C21256// We need a multiple of the divisor for a signed add constant, but1257// unsigned is fine with any constant pair.1258if (IsSigned &&1259match(Op0, m_NSWAddLike(m_NSWMul(m_Value(X), m_SpecificInt(*C2)),1260m_APInt(C1))) &&1261isMultiple(*C1, *C2, Quotient, IsSigned)) {1262return BinaryOperator::CreateNSWAdd(X, ConstantInt::get(Ty, Quotient));1263}1264if (!IsSigned &&1265match(Op0, m_NUWAddLike(m_NUWMul(m_Value(X), m_SpecificInt(*C2)),1266m_APInt(C1)))) {1267return BinaryOperator::CreateNUWAdd(X,1268ConstantInt::get(Ty, C1->udiv(*C2)));1269}12701271if (!C2->isZero()) // avoid X udiv 01272if (Instruction *FoldedDiv = foldBinOpIntoSelectOrPhi(I))1273return FoldedDiv;1274}12751276if (match(Op0, m_One())) {1277assert(!Ty->isIntOrIntVectorTy(1) && "i1 divide not removed?");1278if (IsSigned) {1279// 1 / 0 --> undef ; 1 / 1 --> 1 ; 1 / -1 --> -1 ; 1 / anything else --> 01280// (Op1 + 1) u< 3 ? Op1 : 01281// Op1 must be frozen because we are increasing its number of uses.1282Value *F1 = Op1;1283if (!isGuaranteedNotToBeUndef(Op1))1284F1 = Builder.CreateFreeze(Op1, Op1->getName() + ".fr");1285Value *Inc = Builder.CreateAdd(F1, Op0);1286Value *Cmp = Builder.CreateICmpULT(Inc, ConstantInt::get(Ty, 3));1287return SelectInst::Create(Cmp, F1, ConstantInt::get(Ty, 0));1288} else {1289// If Op1 is 0 then it's undefined behaviour. If Op1 is 1 then the1290// result is one, otherwise it's zero.1291return new ZExtInst(Builder.CreateICmpEQ(Op1, Op0), Ty);1292}1293}12941295// See if we can fold away this div instruction.1296if (SimplifyDemandedInstructionBits(I))1297return &I;12981299// (X - (X rem Y)) / Y -> X / Y; usually originates as ((X / Y) * Y) / Y1300Value *X, *Z;1301if (match(Op0, m_Sub(m_Value(X), m_Value(Z)))) // (X - Z) / Y; Y = Op11302if ((IsSigned && match(Z, m_SRem(m_Specific(X), m_Specific(Op1)))) ||1303(!IsSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1)))))1304return BinaryOperator::Create(I.getOpcode(), X, Op1);13051306// (X << Y) / X -> 1 << Y1307Value *Y;1308if (IsSigned && match(Op0, m_NSWShl(m_Specific(Op1), m_Value(Y))))1309return BinaryOperator::CreateNSWShl(ConstantInt::get(Ty, 1), Y);1310if (!IsSigned && match(Op0, m_NUWShl(m_Specific(Op1), m_Value(Y))))1311return BinaryOperator::CreateNUWShl(ConstantInt::get(Ty, 1), Y);13121313// X / (X * Y) -> 1 / Y if the multiplication does not overflow.1314if (match(Op1, m_c_Mul(m_Specific(Op0), m_Value(Y)))) {1315bool HasNSW = cast<OverflowingBinaryOperator>(Op1)->hasNoSignedWrap();1316bool HasNUW = cast<OverflowingBinaryOperator>(Op1)->hasNoUnsignedWrap();1317if ((IsSigned && HasNSW) || (!IsSigned && HasNUW)) {1318replaceOperand(I, 0, ConstantInt::get(Ty, 1));1319replaceOperand(I, 1, Y);1320return &I;1321}1322}13231324// (X << Z) / (X * Y) -> (1 << Z) / Y1325// TODO: Handle sdiv.1326if (!IsSigned && Op1->hasOneUse() &&1327match(Op0, m_NUWShl(m_Value(X), m_Value(Z))) &&1328match(Op1, m_c_Mul(m_Specific(X), m_Value(Y))))1329if (cast<OverflowingBinaryOperator>(Op1)->hasNoUnsignedWrap()) {1330Instruction *NewDiv = BinaryOperator::CreateUDiv(1331Builder.CreateShl(ConstantInt::get(Ty, 1), Z, "", /*NUW*/ true), Y);1332NewDiv->setIsExact(I.isExact());1333return NewDiv;1334}13351336if (Value *R = foldIDivShl(I, Builder))1337return replaceInstUsesWith(I, R);13381339// With the appropriate no-wrap constraint, remove a multiply by the divisor1340// after peeking through another divide:1341// ((Op1 * X) / Y) / Op1 --> X / Y1342if (match(Op0, m_BinOp(I.getOpcode(), m_c_Mul(m_Specific(Op1), m_Value(X)),1343m_Value(Y)))) {1344auto *InnerDiv = cast<PossiblyExactOperator>(Op0);1345auto *Mul = cast<OverflowingBinaryOperator>(InnerDiv->getOperand(0));1346Instruction *NewDiv = nullptr;1347if (!IsSigned && Mul->hasNoUnsignedWrap())1348NewDiv = BinaryOperator::CreateUDiv(X, Y);1349else if (IsSigned && Mul->hasNoSignedWrap())1350NewDiv = BinaryOperator::CreateSDiv(X, Y);13511352// Exact propagates only if both of the original divides are exact.1353if (NewDiv) {1354NewDiv->setIsExact(I.isExact() && InnerDiv->isExact());1355return NewDiv;1356}1357}13581359// (X * Y) / (X * Z) --> Y / Z (and commuted variants)1360if (match(Op0, m_Mul(m_Value(X), m_Value(Y)))) {1361auto OB0HasNSW = cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap();1362auto OB0HasNUW = cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap();13631364auto CreateDivOrNull = [&](Value *A, Value *B) -> Instruction * {1365auto OB1HasNSW = cast<OverflowingBinaryOperator>(Op1)->hasNoSignedWrap();1366auto OB1HasNUW =1367cast<OverflowingBinaryOperator>(Op1)->hasNoUnsignedWrap();1368const APInt *C1, *C2;1369if (IsSigned && OB0HasNSW) {1370if (OB1HasNSW && match(B, m_APInt(C1)) && !C1->isAllOnes())1371return BinaryOperator::CreateSDiv(A, B);1372}1373if (!IsSigned && OB0HasNUW) {1374if (OB1HasNUW)1375return BinaryOperator::CreateUDiv(A, B);1376if (match(A, m_APInt(C1)) && match(B, m_APInt(C2)) && C2->ule(*C1))1377return BinaryOperator::CreateUDiv(A, B);1378}1379return nullptr;1380};13811382if (match(Op1, m_c_Mul(m_Specific(X), m_Value(Z)))) {1383if (auto *Val = CreateDivOrNull(Y, Z))1384return Val;1385}1386if (match(Op1, m_c_Mul(m_Specific(Y), m_Value(Z)))) {1387if (auto *Val = CreateDivOrNull(X, Z))1388return Val;1389}1390}1391return nullptr;1392}13931394static const unsigned MaxDepth = 6;13951396// Take the exact integer log2 of the value. If DoFold is true, create the1397// actual instructions, otherwise return a non-null dummy value. Return nullptr1398// on failure.1399static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,1400bool AssumeNonZero, bool DoFold) {1401auto IfFold = [DoFold](function_ref<Value *()> Fn) {1402if (!DoFold)1403return reinterpret_cast<Value *>(-1);1404return Fn();1405};14061407// FIXME: assert that Op1 isn't/doesn't contain undef.14081409// log2(2^C) -> C1410if (match(Op, m_Power2()))1411return IfFold([&]() {1412Constant *C = ConstantExpr::getExactLogBase2(cast<Constant>(Op));1413if (!C)1414llvm_unreachable("Failed to constant fold udiv -> logbase2");1415return C;1416});14171418// The remaining tests are all recursive, so bail out if we hit the limit.1419if (Depth++ == MaxDepth)1420return nullptr;14211422// log2(zext X) -> zext log2(X)1423// FIXME: Require one use?1424Value *X, *Y;1425if (match(Op, m_ZExt(m_Value(X))))1426if (Value *LogX = takeLog2(Builder, X, Depth, AssumeNonZero, DoFold))1427return IfFold([&]() { return Builder.CreateZExt(LogX, Op->getType()); });14281429// log2(X << Y) -> log2(X) + Y1430// FIXME: Require one use unless X is 1?1431if (match(Op, m_Shl(m_Value(X), m_Value(Y)))) {1432auto *BO = cast<OverflowingBinaryOperator>(Op);1433// nuw will be set if the `shl` is trivially non-zero.1434if (AssumeNonZero || BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap())1435if (Value *LogX = takeLog2(Builder, X, Depth, AssumeNonZero, DoFold))1436return IfFold([&]() { return Builder.CreateAdd(LogX, Y); });1437}14381439// log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)1440// FIXME: Require one use?1441if (SelectInst *SI = dyn_cast<SelectInst>(Op))1442if (Value *LogX = takeLog2(Builder, SI->getOperand(1), Depth,1443AssumeNonZero, DoFold))1444if (Value *LogY = takeLog2(Builder, SI->getOperand(2), Depth,1445AssumeNonZero, DoFold))1446return IfFold([&]() {1447return Builder.CreateSelect(SI->getOperand(0), LogX, LogY);1448});14491450// log2(umin(X, Y)) -> umin(log2(X), log2(Y))1451// log2(umax(X, Y)) -> umax(log2(X), log2(Y))1452auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op);1453if (MinMax && MinMax->hasOneUse() && !MinMax->isSigned()) {1454// Use AssumeNonZero as false here. Otherwise we can hit case where1455// log2(umax(X, Y)) != umax(log2(X), log2(Y)) (because overflow).1456if (Value *LogX = takeLog2(Builder, MinMax->getLHS(), Depth,1457/*AssumeNonZero*/ false, DoFold))1458if (Value *LogY = takeLog2(Builder, MinMax->getRHS(), Depth,1459/*AssumeNonZero*/ false, DoFold))1460return IfFold([&]() {1461return Builder.CreateBinaryIntrinsic(MinMax->getIntrinsicID(), LogX,1462LogY);1463});1464}14651466return nullptr;1467}14681469/// If we have zero-extended operands of an unsigned div or rem, we may be able1470/// to narrow the operation (sink the zext below the math).1471static Instruction *narrowUDivURem(BinaryOperator &I,1472InstCombinerImpl &IC) {1473Instruction::BinaryOps Opcode = I.getOpcode();1474Value *N = I.getOperand(0);1475Value *D = I.getOperand(1);1476Type *Ty = I.getType();1477Value *X, *Y;1478if (match(N, m_ZExt(m_Value(X))) && match(D, m_ZExt(m_Value(Y))) &&1479X->getType() == Y->getType() && (N->hasOneUse() || D->hasOneUse())) {1480// udiv (zext X), (zext Y) --> zext (udiv X, Y)1481// urem (zext X), (zext Y) --> zext (urem X, Y)1482Value *NarrowOp = IC.Builder.CreateBinOp(Opcode, X, Y);1483return new ZExtInst(NarrowOp, Ty);1484}14851486Constant *C;1487if (isa<Instruction>(N) && match(N, m_OneUse(m_ZExt(m_Value(X)))) &&1488match(D, m_Constant(C))) {1489// If the constant is the same in the smaller type, use the narrow version.1490Constant *TruncC = IC.getLosslessUnsignedTrunc(C, X->getType());1491if (!TruncC)1492return nullptr;14931494// udiv (zext X), C --> zext (udiv X, C')1495// urem (zext X), C --> zext (urem X, C')1496return new ZExtInst(IC.Builder.CreateBinOp(Opcode, X, TruncC), Ty);1497}1498if (isa<Instruction>(D) && match(D, m_OneUse(m_ZExt(m_Value(X)))) &&1499match(N, m_Constant(C))) {1500// If the constant is the same in the smaller type, use the narrow version.1501Constant *TruncC = IC.getLosslessUnsignedTrunc(C, X->getType());1502if (!TruncC)1503return nullptr;15041505// udiv C, (zext X) --> zext (udiv C', X)1506// urem C, (zext X) --> zext (urem C', X)1507return new ZExtInst(IC.Builder.CreateBinOp(Opcode, TruncC, X), Ty);1508}15091510return nullptr;1511}15121513Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {1514if (Value *V = simplifyUDivInst(I.getOperand(0), I.getOperand(1), I.isExact(),1515SQ.getWithInstruction(&I)))1516return replaceInstUsesWith(I, V);15171518if (Instruction *X = foldVectorBinop(I))1519return X;15201521// Handle the integer div common cases1522if (Instruction *Common = commonIDivTransforms(I))1523return Common;15241525Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1526Value *X;1527const APInt *C1, *C2;1528if (match(Op0, m_LShr(m_Value(X), m_APInt(C1))) && match(Op1, m_APInt(C2))) {1529// (X lshr C1) udiv C2 --> X udiv (C2 << C1)1530bool Overflow;1531APInt C2ShlC1 = C2->ushl_ov(*C1, Overflow);1532if (!Overflow) {1533bool IsExact = I.isExact() && match(Op0, m_Exact(m_Value()));1534BinaryOperator *BO = BinaryOperator::CreateUDiv(1535X, ConstantInt::get(X->getType(), C2ShlC1));1536if (IsExact)1537BO->setIsExact();1538return BO;1539}1540}15411542// Op0 / C where C is large (negative) --> zext (Op0 >= C)1543// TODO: Could use isKnownNegative() to handle non-constant values.1544Type *Ty = I.getType();1545if (match(Op1, m_Negative())) {1546Value *Cmp = Builder.CreateICmpUGE(Op0, Op1);1547return CastInst::CreateZExtOrBitCast(Cmp, Ty);1548}1549// Op0 / (sext i1 X) --> zext (Op0 == -1) (if X is 0, the div is undefined)1550if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {1551Value *Cmp = Builder.CreateICmpEQ(Op0, ConstantInt::getAllOnesValue(Ty));1552return CastInst::CreateZExtOrBitCast(Cmp, Ty);1553}15541555if (Instruction *NarrowDiv = narrowUDivURem(I, *this))1556return NarrowDiv;15571558Value *A, *B;15591560// Look through a right-shift to find the common factor:1561// ((Op1 *nuw A) >> B) / Op1 --> A >> B1562if (match(Op0, m_LShr(m_NUWMul(m_Specific(Op1), m_Value(A)), m_Value(B))) ||1563match(Op0, m_LShr(m_NUWMul(m_Value(A), m_Specific(Op1)), m_Value(B)))) {1564Instruction *Lshr = BinaryOperator::CreateLShr(A, B);1565if (I.isExact() && cast<PossiblyExactOperator>(Op0)->isExact())1566Lshr->setIsExact();1567return Lshr;1568}15691570// Op1 udiv Op2 -> Op1 lshr log2(Op2), if log2() folds away.1571if (takeLog2(Builder, Op1, /*Depth*/ 0, /*AssumeNonZero*/ true,1572/*DoFold*/ false)) {1573Value *Res = takeLog2(Builder, Op1, /*Depth*/ 0,1574/*AssumeNonZero*/ true, /*DoFold*/ true);1575return replaceInstUsesWith(1576I, Builder.CreateLShr(Op0, Res, I.getName(), I.isExact()));1577}15781579return nullptr;1580}15811582Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {1583if (Value *V = simplifySDivInst(I.getOperand(0), I.getOperand(1), I.isExact(),1584SQ.getWithInstruction(&I)))1585return replaceInstUsesWith(I, V);15861587if (Instruction *X = foldVectorBinop(I))1588return X;15891590// Handle the integer div common cases1591if (Instruction *Common = commonIDivTransforms(I))1592return Common;15931594Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1595Type *Ty = I.getType();1596Value *X;1597// sdiv Op0, -1 --> -Op01598// sdiv Op0, (sext i1 X) --> -Op0 (because if X is 0, the op is undefined)1599if (match(Op1, m_AllOnes()) ||1600(match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)))1601return BinaryOperator::CreateNSWNeg(Op0);16021603// X / INT_MIN --> X == INT_MIN1604if (match(Op1, m_SignMask()))1605return new ZExtInst(Builder.CreateICmpEQ(Op0, Op1), Ty);16061607if (I.isExact()) {1608// sdiv exact X, 1<<C --> ashr exact X, C iff 1<<C is non-negative1609if (match(Op1, m_Power2()) && match(Op1, m_NonNegative())) {1610Constant *C = ConstantExpr::getExactLogBase2(cast<Constant>(Op1));1611return BinaryOperator::CreateExactAShr(Op0, C);1612}16131614// sdiv exact X, (1<<ShAmt) --> ashr exact X, ShAmt (if shl is non-negative)1615Value *ShAmt;1616if (match(Op1, m_NSWShl(m_One(), m_Value(ShAmt))))1617return BinaryOperator::CreateExactAShr(Op0, ShAmt);16181619// sdiv exact X, -1<<C --> -(ashr exact X, C)1620if (match(Op1, m_NegatedPower2())) {1621Constant *NegPow2C = ConstantExpr::getNeg(cast<Constant>(Op1));1622Constant *C = ConstantExpr::getExactLogBase2(NegPow2C);1623Value *Ashr = Builder.CreateAShr(Op0, C, I.getName() + ".neg", true);1624return BinaryOperator::CreateNSWNeg(Ashr);1625}1626}16271628const APInt *Op1C;1629if (match(Op1, m_APInt(Op1C))) {1630// If the dividend is sign-extended and the constant divisor is small enough1631// to fit in the source type, shrink the division to the narrower type:1632// (sext X) sdiv C --> sext (X sdiv C)1633Value *Op0Src;1634if (match(Op0, m_OneUse(m_SExt(m_Value(Op0Src)))) &&1635Op0Src->getType()->getScalarSizeInBits() >=1636Op1C->getSignificantBits()) {16371638// In the general case, we need to make sure that the dividend is not the1639// minimum signed value because dividing that by -1 is UB. But here, we1640// know that the -1 divisor case is already handled above.16411642Constant *NarrowDivisor =1643ConstantExpr::getTrunc(cast<Constant>(Op1), Op0Src->getType());1644Value *NarrowOp = Builder.CreateSDiv(Op0Src, NarrowDivisor);1645return new SExtInst(NarrowOp, Ty);1646}16471648// -X / C --> X / -C (if the negation doesn't overflow).1649// TODO: This could be enhanced to handle arbitrary vector constants by1650// checking if all elements are not the min-signed-val.1651if (!Op1C->isMinSignedValue() && match(Op0, m_NSWNeg(m_Value(X)))) {1652Constant *NegC = ConstantInt::get(Ty, -(*Op1C));1653Instruction *BO = BinaryOperator::CreateSDiv(X, NegC);1654BO->setIsExact(I.isExact());1655return BO;1656}1657}16581659// -X / Y --> -(X / Y)1660Value *Y;1661if (match(&I, m_SDiv(m_OneUse(m_NSWNeg(m_Value(X))), m_Value(Y))))1662return BinaryOperator::CreateNSWNeg(1663Builder.CreateSDiv(X, Y, I.getName(), I.isExact()));16641665// abs(X) / X --> X > -1 ? 1 : -11666// X / abs(X) --> X > -1 ? 1 : -11667if (match(&I, m_c_BinOp(1668m_OneUse(m_Intrinsic<Intrinsic::abs>(m_Value(X), m_One())),1669m_Deferred(X)))) {1670Value *Cond = Builder.CreateIsNotNeg(X);1671return SelectInst::Create(Cond, ConstantInt::get(Ty, 1),1672ConstantInt::getAllOnesValue(Ty));1673}16741675KnownBits KnownDividend = computeKnownBits(Op0, 0, &I);1676if (!I.isExact() &&1677(match(Op1, m_Power2(Op1C)) || match(Op1, m_NegatedPower2(Op1C))) &&1678KnownDividend.countMinTrailingZeros() >= Op1C->countr_zero()) {1679I.setIsExact();1680return &I;1681}16821683if (KnownDividend.isNonNegative()) {1684// If both operands are unsigned, turn this into a udiv.1685if (isKnownNonNegative(Op1, SQ.getWithInstruction(&I))) {1686auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName());1687BO->setIsExact(I.isExact());1688return BO;1689}16901691if (match(Op1, m_NegatedPower2())) {1692// X sdiv (-(1 << C)) -> -(X sdiv (1 << C)) ->1693// -> -(X udiv (1 << C)) -> -(X u>> C)1694Constant *CNegLog2 = ConstantExpr::getExactLogBase2(1695ConstantExpr::getNeg(cast<Constant>(Op1)));1696Value *Shr = Builder.CreateLShr(Op0, CNegLog2, I.getName(), I.isExact());1697return BinaryOperator::CreateNeg(Shr);1698}16991700if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, 0, &I)) {1701// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)1702// Safe because the only negative value (1 << Y) can take on is1703// INT_MIN, and X sdiv INT_MIN == X udiv INT_MIN == 0 if X doesn't have1704// the sign bit set.1705auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName());1706BO->setIsExact(I.isExact());1707return BO;1708}1709}17101711// -X / X --> X == INT_MIN ? 1 : -11712if (isKnownNegation(Op0, Op1)) {1713APInt MinVal = APInt::getSignedMinValue(Ty->getScalarSizeInBits());1714Value *Cond = Builder.CreateICmpEQ(Op0, ConstantInt::get(Ty, MinVal));1715return SelectInst::Create(Cond, ConstantInt::get(Ty, 1),1716ConstantInt::getAllOnesValue(Ty));1717}1718return nullptr;1719}17201721/// Remove negation and try to convert division into multiplication.1722Instruction *InstCombinerImpl::foldFDivConstantDivisor(BinaryOperator &I) {1723Constant *C;1724if (!match(I.getOperand(1), m_Constant(C)))1725return nullptr;17261727// -X / C --> X / -C1728Value *X;1729const DataLayout &DL = I.getDataLayout();1730if (match(I.getOperand(0), m_FNeg(m_Value(X))))1731if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))1732return BinaryOperator::CreateFDivFMF(X, NegC, &I);17331734// nnan X / +0.0 -> copysign(inf, X)1735// nnan nsz X / -0.0 -> copysign(inf, X)1736if (I.hasNoNaNs() &&1737(match(I.getOperand(1), m_PosZeroFP()) ||1738(I.hasNoSignedZeros() && match(I.getOperand(1), m_AnyZeroFP())))) {1739IRBuilder<> B(&I);1740CallInst *CopySign = B.CreateIntrinsic(1741Intrinsic::copysign, {C->getType()},1742{ConstantFP::getInfinity(I.getType()), I.getOperand(0)}, &I);1743CopySign->takeName(&I);1744return replaceInstUsesWith(I, CopySign);1745}17461747// If the constant divisor has an exact inverse, this is always safe. If not,1748// then we can still create a reciprocal if fast-math-flags allow it and the1749// constant is a regular number (not zero, infinite, or denormal).1750if (!(C->hasExactInverseFP() || (I.hasAllowReciprocal() && C->isNormalFP())))1751return nullptr;17521753// Disallow denormal constants because we don't know what would happen1754// on all targets.1755// TODO: Use Intrinsic::canonicalize or let function attributes tell us that1756// denorms are flushed?1757auto *RecipC = ConstantFoldBinaryOpOperands(1758Instruction::FDiv, ConstantFP::get(I.getType(), 1.0), C, DL);1759if (!RecipC || !RecipC->isNormalFP())1760return nullptr;17611762// X / C --> X * (1 / C)1763return BinaryOperator::CreateFMulFMF(I.getOperand(0), RecipC, &I);1764}17651766/// Remove negation and try to reassociate constant math.1767static Instruction *foldFDivConstantDividend(BinaryOperator &I) {1768Constant *C;1769if (!match(I.getOperand(0), m_Constant(C)))1770return nullptr;17711772// C / -X --> -C / X1773Value *X;1774const DataLayout &DL = I.getDataLayout();1775if (match(I.getOperand(1), m_FNeg(m_Value(X))))1776if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))1777return BinaryOperator::CreateFDivFMF(NegC, X, &I);17781779if (!I.hasAllowReassoc() || !I.hasAllowReciprocal())1780return nullptr;17811782// Try to reassociate C / X expressions where X includes another constant.1783Constant *C2, *NewC = nullptr;1784if (match(I.getOperand(1), m_FMul(m_Value(X), m_Constant(C2)))) {1785// C / (X * C2) --> (C / C2) / X1786NewC = ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C2, DL);1787} else if (match(I.getOperand(1), m_FDiv(m_Value(X), m_Constant(C2)))) {1788// C / (X / C2) --> (C * C2) / X1789NewC = ConstantFoldBinaryOpOperands(Instruction::FMul, C, C2, DL);1790}1791// Disallow denormal constants because we don't know what would happen1792// on all targets.1793// TODO: Use Intrinsic::canonicalize or let function attributes tell us that1794// denorms are flushed?1795if (!NewC || !NewC->isNormalFP())1796return nullptr;17971798return BinaryOperator::CreateFDivFMF(NewC, X, &I);1799}18001801/// Negate the exponent of pow/exp to fold division-by-pow() into multiply.1802static Instruction *foldFDivPowDivisor(BinaryOperator &I,1803InstCombiner::BuilderTy &Builder) {1804Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1805auto *II = dyn_cast<IntrinsicInst>(Op1);1806if (!II || !II->hasOneUse() || !I.hasAllowReassoc() ||1807!I.hasAllowReciprocal())1808return nullptr;18091810// Z / pow(X, Y) --> Z * pow(X, -Y)1811// Z / exp{2}(Y) --> Z * exp{2}(-Y)1812// In the general case, this creates an extra instruction, but fmul allows1813// for better canonicalization and optimization than fdiv.1814Intrinsic::ID IID = II->getIntrinsicID();1815SmallVector<Value *> Args;1816switch (IID) {1817case Intrinsic::pow:1818Args.push_back(II->getArgOperand(0));1819Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(1), &I));1820break;1821case Intrinsic::powi: {1822// Require 'ninf' assuming that makes powi(X, -INT_MIN) acceptable.1823// That is, X ** (huge negative number) is 0.0, ~1.0, or INF and so1824// dividing by that is INF, ~1.0, or 0.0. Code that uses powi allows1825// non-standard results, so this corner case should be acceptable if the1826// code rules out INF values.1827if (!I.hasNoInfs())1828return nullptr;1829Args.push_back(II->getArgOperand(0));1830Args.push_back(Builder.CreateNeg(II->getArgOperand(1)));1831Type *Tys[] = {I.getType(), II->getArgOperand(1)->getType()};1832Value *Pow = Builder.CreateIntrinsic(IID, Tys, Args, &I);1833return BinaryOperator::CreateFMulFMF(Op0, Pow, &I);1834}1835case Intrinsic::exp:1836case Intrinsic::exp2:1837Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(0), &I));1838break;1839default:1840return nullptr;1841}1842Value *Pow = Builder.CreateIntrinsic(IID, I.getType(), Args, &I);1843return BinaryOperator::CreateFMulFMF(Op0, Pow, &I);1844}18451846/// Convert div to mul if we have an sqrt divisor iff sqrt's operand is a fdiv1847/// instruction.1848static Instruction *foldFDivSqrtDivisor(BinaryOperator &I,1849InstCombiner::BuilderTy &Builder) {1850// X / sqrt(Y / Z) --> X * sqrt(Z / Y)1851if (!I.hasAllowReassoc() || !I.hasAllowReciprocal())1852return nullptr;1853Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1854auto *II = dyn_cast<IntrinsicInst>(Op1);1855if (!II || II->getIntrinsicID() != Intrinsic::sqrt || !II->hasOneUse() ||1856!II->hasAllowReassoc() || !II->hasAllowReciprocal())1857return nullptr;18581859Value *Y, *Z;1860auto *DivOp = dyn_cast<Instruction>(II->getOperand(0));1861if (!DivOp)1862return nullptr;1863if (!match(DivOp, m_FDiv(m_Value(Y), m_Value(Z))))1864return nullptr;1865if (!DivOp->hasAllowReassoc() || !I.hasAllowReciprocal() ||1866!DivOp->hasOneUse())1867return nullptr;1868Value *SwapDiv = Builder.CreateFDivFMF(Z, Y, DivOp);1869Value *NewSqrt =1870Builder.CreateUnaryIntrinsic(II->getIntrinsicID(), SwapDiv, II);1871return BinaryOperator::CreateFMulFMF(Op0, NewSqrt, &I);1872}18731874Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {1875Module *M = I.getModule();18761877if (Value *V = simplifyFDivInst(I.getOperand(0), I.getOperand(1),1878I.getFastMathFlags(),1879SQ.getWithInstruction(&I)))1880return replaceInstUsesWith(I, V);18811882if (Instruction *X = foldVectorBinop(I))1883return X;18841885if (Instruction *Phi = foldBinopWithPhiOperands(I))1886return Phi;18871888if (Instruction *R = foldFDivConstantDivisor(I))1889return R;18901891if (Instruction *R = foldFDivConstantDividend(I))1892return R;18931894if (Instruction *R = foldFPSignBitOps(I))1895return R;18961897Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);1898if (isa<Constant>(Op0))1899if (SelectInst *SI = dyn_cast<SelectInst>(Op1))1900if (Instruction *R = FoldOpIntoSelect(I, SI))1901return R;19021903if (isa<Constant>(Op1))1904if (SelectInst *SI = dyn_cast<SelectInst>(Op0))1905if (Instruction *R = FoldOpIntoSelect(I, SI))1906return R;19071908if (I.hasAllowReassoc() && I.hasAllowReciprocal()) {1909Value *X, *Y;1910if (match(Op0, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&1911(!isa<Constant>(Y) || !isa<Constant>(Op1))) {1912// (X / Y) / Z => X / (Y * Z)1913Value *YZ = Builder.CreateFMulFMF(Y, Op1, &I);1914return BinaryOperator::CreateFDivFMF(X, YZ, &I);1915}1916if (match(Op1, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&1917(!isa<Constant>(Y) || !isa<Constant>(Op0))) {1918// Z / (X / Y) => (Y * Z) / X1919Value *YZ = Builder.CreateFMulFMF(Y, Op0, &I);1920return BinaryOperator::CreateFDivFMF(YZ, X, &I);1921}1922// Z / (1.0 / Y) => (Y * Z)1923//1924// This is a special case of Z / (X / Y) => (Y * Z) / X, with X = 1.0. The1925// m_OneUse check is avoided because even in the case of the multiple uses1926// for 1.0/Y, the number of instructions remain the same and a division is1927// replaced by a multiplication.1928if (match(Op1, m_FDiv(m_SpecificFP(1.0), m_Value(Y))))1929return BinaryOperator::CreateFMulFMF(Y, Op0, &I);1930}19311932if (I.hasAllowReassoc() && Op0->hasOneUse() && Op1->hasOneUse()) {1933// sin(X) / cos(X) -> tan(X)1934// cos(X) / sin(X) -> 1/tan(X) (cotangent)1935Value *X;1936bool IsTan = match(Op0, m_Intrinsic<Intrinsic::sin>(m_Value(X))) &&1937match(Op1, m_Intrinsic<Intrinsic::cos>(m_Specific(X)));1938bool IsCot =1939!IsTan && match(Op0, m_Intrinsic<Intrinsic::cos>(m_Value(X))) &&1940match(Op1, m_Intrinsic<Intrinsic::sin>(m_Specific(X)));19411942if ((IsTan || IsCot) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tan,1943LibFunc_tanf, LibFunc_tanl)) {1944IRBuilder<> B(&I);1945IRBuilder<>::FastMathFlagGuard FMFGuard(B);1946B.setFastMathFlags(I.getFastMathFlags());1947AttributeList Attrs =1948cast<CallBase>(Op0)->getCalledFunction()->getAttributes();1949Value *Res = emitUnaryFloatFnCall(X, &TLI, LibFunc_tan, LibFunc_tanf,1950LibFunc_tanl, B, Attrs);1951if (IsCot)1952Res = B.CreateFDiv(ConstantFP::get(I.getType(), 1.0), Res);1953return replaceInstUsesWith(I, Res);1954}1955}19561957// X / (X * Y) --> 1.0 / Y1958// Reassociate to (X / X -> 1.0) is legal when NaNs are not allowed.1959// We can ignore the possibility that X is infinity because INF/INF is NaN.1960Value *X, *Y;1961if (I.hasNoNaNs() && I.hasAllowReassoc() &&1962match(Op1, m_c_FMul(m_Specific(Op0), m_Value(Y)))) {1963replaceOperand(I, 0, ConstantFP::get(I.getType(), 1.0));1964replaceOperand(I, 1, Y);1965return &I;1966}19671968// X / fabs(X) -> copysign(1.0, X)1969// fabs(X) / X -> copysign(1.0, X)1970if (I.hasNoNaNs() && I.hasNoInfs() &&1971(match(&I, m_FDiv(m_Value(X), m_FAbs(m_Deferred(X)))) ||1972match(&I, m_FDiv(m_FAbs(m_Value(X)), m_Deferred(X))))) {1973Value *V = Builder.CreateBinaryIntrinsic(1974Intrinsic::copysign, ConstantFP::get(I.getType(), 1.0), X, &I);1975return replaceInstUsesWith(I, V);1976}19771978if (Instruction *Mul = foldFDivPowDivisor(I, Builder))1979return Mul;19801981if (Instruction *Mul = foldFDivSqrtDivisor(I, Builder))1982return Mul;19831984// pow(X, Y) / X --> pow(X, Y-1)1985if (I.hasAllowReassoc() &&1986match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(m_Specific(Op1),1987m_Value(Y))))) {1988Value *Y1 =1989Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), -1.0), &I);1990Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, Op1, Y1, &I);1991return replaceInstUsesWith(I, Pow);1992}19931994if (Instruction *FoldedPowi = foldPowiReassoc(I))1995return FoldedPowi;19961997return nullptr;1998}19992000// Variety of transform for:2001// (urem/srem (mul X, Y), (mul X, Z))2002// (urem/srem (shl X, Y), (shl X, Z))2003// (urem/srem (shl Y, X), (shl Z, X))2004// NB: The shift cases are really just extensions of the mul case. We treat2005// shift as Val * (1 << Amt).2006static Instruction *simplifyIRemMulShl(BinaryOperator &I,2007InstCombinerImpl &IC) {2008Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *X = nullptr;2009APInt Y, Z;2010bool ShiftByX = false;20112012// If V is not nullptr, it will be matched using m_Specific.2013auto MatchShiftOrMulXC = [](Value *Op, Value *&V, APInt &C) -> bool {2014const APInt *Tmp = nullptr;2015if ((!V && match(Op, m_Mul(m_Value(V), m_APInt(Tmp)))) ||2016(V && match(Op, m_Mul(m_Specific(V), m_APInt(Tmp)))))2017C = *Tmp;2018else if ((!V && match(Op, m_Shl(m_Value(V), m_APInt(Tmp)))) ||2019(V && match(Op, m_Shl(m_Specific(V), m_APInt(Tmp)))))2020C = APInt(Tmp->getBitWidth(), 1) << *Tmp;2021if (Tmp != nullptr)2022return true;20232024// Reset `V` so we don't start with specific value on next match attempt.2025V = nullptr;2026return false;2027};20282029auto MatchShiftCX = [](Value *Op, APInt &C, Value *&V) -> bool {2030const APInt *Tmp = nullptr;2031if ((!V && match(Op, m_Shl(m_APInt(Tmp), m_Value(V)))) ||2032(V && match(Op, m_Shl(m_APInt(Tmp), m_Specific(V))))) {2033C = *Tmp;2034return true;2035}20362037// Reset `V` so we don't start with specific value on next match attempt.2038V = nullptr;2039return false;2040};20412042if (MatchShiftOrMulXC(Op0, X, Y) && MatchShiftOrMulXC(Op1, X, Z)) {2043// pass2044} else if (MatchShiftCX(Op0, Y, X) && MatchShiftCX(Op1, Z, X)) {2045ShiftByX = true;2046} else {2047return nullptr;2048}20492050bool IsSRem = I.getOpcode() == Instruction::SRem;20512052OverflowingBinaryOperator *BO0 = cast<OverflowingBinaryOperator>(Op0);2053// TODO: We may be able to deduce more about nsw/nuw of BO0/BO1 based on Y >=2054// Z or Z >= Y.2055bool BO0HasNSW = BO0->hasNoSignedWrap();2056bool BO0HasNUW = BO0->hasNoUnsignedWrap();2057bool BO0NoWrap = IsSRem ? BO0HasNSW : BO0HasNUW;20582059APInt RemYZ = IsSRem ? Y.srem(Z) : Y.urem(Z);2060// (rem (mul nuw/nsw X, Y), (mul X, Z))2061// if (rem Y, Z) == 02062// -> 02063if (RemYZ.isZero() && BO0NoWrap)2064return IC.replaceInstUsesWith(I, ConstantInt::getNullValue(I.getType()));20652066// Helper function to emit either (RemSimplificationC << X) or2067// (RemSimplificationC * X) depending on whether we matched Op0/Op1 as2068// (shl V, X) or (mul V, X) respectively.2069auto CreateMulOrShift =2070[&](const APInt &RemSimplificationC) -> BinaryOperator * {2071Value *RemSimplification =2072ConstantInt::get(I.getType(), RemSimplificationC);2073return ShiftByX ? BinaryOperator::CreateShl(RemSimplification, X)2074: BinaryOperator::CreateMul(X, RemSimplification);2075};20762077OverflowingBinaryOperator *BO1 = cast<OverflowingBinaryOperator>(Op1);2078bool BO1HasNSW = BO1->hasNoSignedWrap();2079bool BO1HasNUW = BO1->hasNoUnsignedWrap();2080bool BO1NoWrap = IsSRem ? BO1HasNSW : BO1HasNUW;2081// (rem (mul X, Y), (mul nuw/nsw X, Z))2082// if (rem Y, Z) == Y2083// -> (mul nuw/nsw X, Y)2084if (RemYZ == Y && BO1NoWrap) {2085BinaryOperator *BO = CreateMulOrShift(Y);2086// Copy any overflow flags from Op0.2087BO->setHasNoSignedWrap(IsSRem || BO0HasNSW);2088BO->setHasNoUnsignedWrap(!IsSRem || BO0HasNUW);2089return BO;2090}20912092// (rem (mul nuw/nsw X, Y), (mul {nsw} X, Z))2093// if Y >= Z2094// -> (mul {nuw} nsw X, (rem Y, Z))2095if (Y.uge(Z) && (IsSRem ? (BO0HasNSW && BO1HasNSW) : BO0HasNUW)) {2096BinaryOperator *BO = CreateMulOrShift(RemYZ);2097BO->setHasNoSignedWrap();2098BO->setHasNoUnsignedWrap(BO0HasNUW);2099return BO;2100}21012102return nullptr;2103}21042105/// This function implements the transforms common to both integer remainder2106/// instructions (urem and srem). It is called by the visitors to those integer2107/// remainder instructions.2108/// Common integer remainder transforms2109Instruction *InstCombinerImpl::commonIRemTransforms(BinaryOperator &I) {2110if (Instruction *Phi = foldBinopWithPhiOperands(I))2111return Phi;21122113Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);21142115// The RHS is known non-zero.2116if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this, I))2117return replaceOperand(I, 1, V);21182119// Handle cases involving: rem X, (select Cond, Y, Z)2120if (simplifyDivRemOfSelectWithZeroOp(I))2121return &I;21222123// If the divisor is a select-of-constants, try to constant fold all rem ops:2124// C % (select Cond, TrueC, FalseC) --> select Cond, (C % TrueC), (C % FalseC)2125// TODO: Adapt simplifyDivRemOfSelectWithZeroOp to allow this and other folds.2126if (match(Op0, m_ImmConstant()) &&2127match(Op1, m_Select(m_Value(), m_ImmConstant(), m_ImmConstant()))) {2128if (Instruction *R = FoldOpIntoSelect(I, cast<SelectInst>(Op1),2129/*FoldWithMultiUse*/ true))2130return R;2131}21322133if (isa<Constant>(Op1)) {2134if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {2135if (SelectInst *SI = dyn_cast<SelectInst>(Op0I)) {2136if (Instruction *R = FoldOpIntoSelect(I, SI))2137return R;2138} else if (auto *PN = dyn_cast<PHINode>(Op0I)) {2139const APInt *Op1Int;2140if (match(Op1, m_APInt(Op1Int)) && !Op1Int->isMinValue() &&2141(I.getOpcode() == Instruction::URem ||2142!Op1Int->isMinSignedValue())) {2143// foldOpIntoPhi will speculate instructions to the end of the PHI's2144// predecessor blocks, so do this only if we know the srem or urem2145// will not fault.2146if (Instruction *NV = foldOpIntoPhi(I, PN))2147return NV;2148}2149}21502151// See if we can fold away this rem instruction.2152if (SimplifyDemandedInstructionBits(I))2153return &I;2154}2155}21562157if (Instruction *R = simplifyIRemMulShl(I, *this))2158return R;21592160return nullptr;2161}21622163Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {2164if (Value *V = simplifyURemInst(I.getOperand(0), I.getOperand(1),2165SQ.getWithInstruction(&I)))2166return replaceInstUsesWith(I, V);21672168if (Instruction *X = foldVectorBinop(I))2169return X;21702171if (Instruction *common = commonIRemTransforms(I))2172return common;21732174if (Instruction *NarrowRem = narrowUDivURem(I, *this))2175return NarrowRem;21762177// X urem Y -> X and Y-1, where Y is a power of 2,2178Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);2179Type *Ty = I.getType();2180if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, 0, &I)) {2181// This may increase instruction count, we don't enforce that Y is a2182// constant.2183Constant *N1 = Constant::getAllOnesValue(Ty);2184Value *Add = Builder.CreateAdd(Op1, N1);2185return BinaryOperator::CreateAnd(Op0, Add);2186}21872188// 1 urem X -> zext(X != 1)2189if (match(Op0, m_One())) {2190Value *Cmp = Builder.CreateICmpNE(Op1, ConstantInt::get(Ty, 1));2191return CastInst::CreateZExtOrBitCast(Cmp, Ty);2192}21932194// Op0 urem C -> Op0 < C ? Op0 : Op0 - C, where C >= signbit.2195// Op0 must be frozen because we are increasing its number of uses.2196if (match(Op1, m_Negative())) {2197Value *F0 = Op0;2198if (!isGuaranteedNotToBeUndef(Op0))2199F0 = Builder.CreateFreeze(Op0, Op0->getName() + ".fr");2200Value *Cmp = Builder.CreateICmpULT(F0, Op1);2201Value *Sub = Builder.CreateSub(F0, Op1);2202return SelectInst::Create(Cmp, F0, Sub);2203}22042205// If the divisor is a sext of a boolean, then the divisor must be max2206// unsigned value (-1). Therefore, the remainder is Op0 unless Op0 is also2207// max unsigned value. In that case, the remainder is 0:2208// urem Op0, (sext i1 X) --> (Op0 == -1) ? 0 : Op02209Value *X;2210if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {2211Value *FrozenOp0 = Op0;2212if (!isGuaranteedNotToBeUndef(Op0))2213FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");2214Value *Cmp =2215Builder.CreateICmpEQ(FrozenOp0, ConstantInt::getAllOnesValue(Ty));2216return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), FrozenOp0);2217}22182219// For "(X + 1) % Op1" and if (X u< Op1) => (X + 1) == Op1 ? 0 : X + 1 .2220if (match(Op0, m_Add(m_Value(X), m_One()))) {2221Value *Val =2222simplifyICmpInst(ICmpInst::ICMP_ULT, X, Op1, SQ.getWithInstruction(&I));2223if (Val && match(Val, m_One())) {2224Value *FrozenOp0 = Op0;2225if (!isGuaranteedNotToBeUndef(Op0))2226FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");2227Value *Cmp = Builder.CreateICmpEQ(FrozenOp0, Op1);2228return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), FrozenOp0);2229}2230}22312232return nullptr;2233}22342235Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {2236if (Value *V = simplifySRemInst(I.getOperand(0), I.getOperand(1),2237SQ.getWithInstruction(&I)))2238return replaceInstUsesWith(I, V);22392240if (Instruction *X = foldVectorBinop(I))2241return X;22422243// Handle the integer rem common cases2244if (Instruction *Common = commonIRemTransforms(I))2245return Common;22462247Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);2248{2249const APInt *Y;2250// X % -Y -> X % Y2251if (match(Op1, m_Negative(Y)) && !Y->isMinSignedValue())2252return replaceOperand(I, 1, ConstantInt::get(I.getType(), -*Y));2253}22542255// -X srem Y --> -(X srem Y)2256Value *X, *Y;2257if (match(&I, m_SRem(m_OneUse(m_NSWNeg(m_Value(X))), m_Value(Y))))2258return BinaryOperator::CreateNSWNeg(Builder.CreateSRem(X, Y));22592260// If the sign bits of both operands are zero (i.e. we can prove they are2261// unsigned inputs), turn this into a urem.2262APInt Mask(APInt::getSignMask(I.getType()->getScalarSizeInBits()));2263if (MaskedValueIsZero(Op1, Mask, 0, &I) &&2264MaskedValueIsZero(Op0, Mask, 0, &I)) {2265// X srem Y -> X urem Y, iff X and Y don't have sign bit set2266return BinaryOperator::CreateURem(Op0, Op1, I.getName());2267}22682269// If it's a constant vector, flip any negative values positive.2270if (isa<ConstantVector>(Op1) || isa<ConstantDataVector>(Op1)) {2271Constant *C = cast<Constant>(Op1);2272unsigned VWidth = cast<FixedVectorType>(C->getType())->getNumElements();22732274bool hasNegative = false;2275bool hasMissing = false;2276for (unsigned i = 0; i != VWidth; ++i) {2277Constant *Elt = C->getAggregateElement(i);2278if (!Elt) {2279hasMissing = true;2280break;2281}22822283if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elt))2284if (RHS->isNegative())2285hasNegative = true;2286}22872288if (hasNegative && !hasMissing) {2289SmallVector<Constant *, 16> Elts(VWidth);2290for (unsigned i = 0; i != VWidth; ++i) {2291Elts[i] = C->getAggregateElement(i); // Handle undef, etc.2292if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elts[i])) {2293if (RHS->isNegative())2294Elts[i] = cast<ConstantInt>(ConstantExpr::getNeg(RHS));2295}2296}22972298Constant *NewRHSV = ConstantVector::get(Elts);2299if (NewRHSV != C) // Don't loop on -MININT2300return replaceOperand(I, 1, NewRHSV);2301}2302}23032304return nullptr;2305}23062307Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {2308if (Value *V = simplifyFRemInst(I.getOperand(0), I.getOperand(1),2309I.getFastMathFlags(),2310SQ.getWithInstruction(&I)))2311return replaceInstUsesWith(I, V);23122313if (Instruction *X = foldVectorBinop(I))2314return X;23152316if (Instruction *Phi = foldBinopWithPhiOperands(I))2317return Phi;23182319return nullptr;2320}232123222323