@@ -185,9 +185,6 @@ static Value *foldMulShl1(BinaryOperator &Mul, bool CommuteOperands,
185185 return nullptr ;
186186}
187187
188- static Value *takeLog2 (IRBuilderBase &Builder, Value *Op, unsigned Depth,
189- bool AssumeNonZero, bool DoFold);
190-
191188Instruction *InstCombinerImpl::visitMul (BinaryOperator &I) {
192189 Value *Op0 = I.getOperand (0 ), *Op1 = I.getOperand (1 );
193190 if (Value *V =
@@ -531,19 +528,13 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
531528 // (shl Op1, Log2(Op0))
532529 // if Log2(Op1) folds away ->
533530 // (shl Op0, Log2(Op1))
534- if (takeLog2 (Builder, Op0, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
535- /* DoFold*/ false )) {
536- Value *Res = takeLog2 (Builder, Op0, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
537- /* DoFold*/ true );
531+ if (Value *Res = tryGetLog2 (Op0, /* AssumeNonZero=*/ false )) {
538532 BinaryOperator *Shl = BinaryOperator::CreateShl (Op1, Res);
539533 // We can only propegate nuw flag.
540534 Shl->setHasNoUnsignedWrap (HasNUW);
541535 return Shl;
542536 }
543- if (takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
544- /* DoFold*/ false )) {
545- Value *Res = takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
546- /* DoFold*/ true );
537+ if (Value *Res = tryGetLog2 (Op1, /* AssumeNonZero=*/ false )) {
547538 BinaryOperator *Shl = BinaryOperator::CreateShl (Op0, Res);
548539 // We can only propegate nuw flag.
549540 Shl->setHasNoUnsignedWrap (HasNUW);
@@ -1407,13 +1398,8 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
14071398 return nullptr ;
14081399}
14091400
1410- static const unsigned MaxDepth = 6 ;
1411-
1412- // Take the exact integer log2 of the value. If DoFold is true, create the
1413- // actual instructions, otherwise return a non-null dummy value. Return nullptr
1414- // on failure.
1415- static Value *takeLog2 (IRBuilderBase &Builder, Value *Op, unsigned Depth,
1416- bool AssumeNonZero, bool DoFold) {
1401+ Value *InstCombinerImpl::takeLog2 (Value *Op, unsigned Depth, bool AssumeNonZero,
1402+ bool DoFold) {
14171403 auto IfFold = [DoFold](function_ref<Value *()> Fn) {
14181404 if (!DoFold)
14191405 return reinterpret_cast <Value *>(-1 );
@@ -1432,22 +1418,22 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
14321418 });
14331419
14341420 // The remaining tests are all recursive, so bail out if we hit the limit.
1435- if (Depth++ == MaxDepth )
1421+ if (Depth++ == MaxAnalysisRecursionDepth )
14361422 return nullptr ;
14371423
14381424 // log2(zext X) -> zext log2(X)
14391425 // FIXME: Require one use?
14401426 Value *X, *Y;
14411427 if (match (Op, m_ZExt (m_Value (X))))
1442- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1428+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
14431429 return IfFold ([&]() { return Builder.CreateZExt (LogX, Op->getType ()); });
14441430
14451431 // log2(trunc x) -> trunc log2(X)
14461432 // FIXME: Require one use?
14471433 if (match (Op, m_Trunc (m_Value (X)))) {
14481434 auto *TI = cast<TruncInst>(Op);
14491435 if (AssumeNonZero || TI->hasNoUnsignedWrap ())
1450- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1436+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
14511437 return IfFold ([&]() {
14521438 return Builder.CreateTrunc (LogX, Op->getType (), " " ,
14531439 /* IsNUW=*/ TI->hasNoUnsignedWrap ());
@@ -1460,7 +1446,7 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
14601446 auto *BO = cast<OverflowingBinaryOperator>(Op);
14611447 // nuw will be set if the `shl` is trivially non-zero.
14621448 if (AssumeNonZero || BO->hasNoUnsignedWrap () || BO->hasNoSignedWrap ())
1463- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1449+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
14641450 return IfFold ([&]() { return Builder.CreateAdd (LogX, Y); });
14651451 }
14661452
@@ -1469,26 +1455,25 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
14691455 if (match (Op, m_LShr (m_Value (X), m_Value (Y)))) {
14701456 auto *PEO = cast<PossiblyExactOperator>(Op);
14711457 if (AssumeNonZero || PEO->isExact ())
1472- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1458+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
14731459 return IfFold ([&]() { return Builder.CreateSub (LogX, Y); });
14741460 }
14751461
14761462 // log2(X & Y) -> either log2(X) or log2(Y)
14771463 // This requires `AssumeNonZero` as `X & Y` may be zero when X != Y.
14781464 if (AssumeNonZero && match (Op, m_And (m_Value (X), m_Value (Y)))) {
1479- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1465+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
14801466 return IfFold ([&]() { return LogX; });
1481- if (Value *LogY = takeLog2 (Builder, Y, Depth, AssumeNonZero, DoFold))
1467+ if (Value *LogY = takeLog2 (Y, Depth, AssumeNonZero, DoFold))
14821468 return IfFold ([&]() { return LogY; });
14831469 }
14841470
14851471 // log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
14861472 // FIXME: Require one use?
14871473 if (SelectInst *SI = dyn_cast<SelectInst>(Op))
1488- if (Value *LogX = takeLog2 (Builder, SI->getOperand (1 ), Depth,
1489- AssumeNonZero, DoFold))
1490- if (Value *LogY = takeLog2 (Builder, SI->getOperand (2 ), Depth,
1491- AssumeNonZero, DoFold))
1474+ if (Value *LogX = takeLog2 (SI->getOperand (1 ), Depth, AssumeNonZero, DoFold))
1475+ if (Value *LogY =
1476+ takeLog2 (SI->getOperand (2 ), Depth, AssumeNonZero, DoFold))
14921477 return IfFold ([&]() {
14931478 return Builder.CreateSelect (SI->getOperand (0 ), LogX, LogY);
14941479 });
@@ -1499,9 +1484,9 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
14991484 if (MinMax && MinMax->hasOneUse () && !MinMax->isSigned ()) {
15001485 // Use AssumeNonZero as false here. Otherwise we can hit case where
15011486 // log2(umax(X, Y)) != umax(log2(X), log2(Y)) (because overflow).
1502- if (Value *LogX = takeLog2 (Builder, MinMax->getLHS (), Depth,
1487+ if (Value *LogX = takeLog2 (MinMax->getLHS (), Depth,
15031488 /* AssumeNonZero*/ false , DoFold))
1504- if (Value *LogY = takeLog2 (Builder, MinMax->getRHS (), Depth,
1489+ if (Value *LogY = takeLog2 (MinMax->getRHS (), Depth,
15051490 /* AssumeNonZero*/ false , DoFold))
15061491 return IfFold ([&]() {
15071492 return Builder.CreateBinaryIntrinsic (MinMax->getIntrinsicID (), LogX,
@@ -1614,13 +1599,9 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
16141599 }
16151600
16161601 // Op1 udiv Op2 -> Op1 lshr log2(Op2), if log2() folds away.
1617- if (takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ true ,
1618- /* DoFold*/ false )) {
1619- Value *Res = takeLog2 (Builder, Op1, /* Depth*/ 0 ,
1620- /* AssumeNonZero*/ true , /* DoFold*/ true );
1602+ if (Value *Res = tryGetLog2 (Op1, /* AssumeNonZero=*/ true ))
16211603 return replaceInstUsesWith (
16221604 I, Builder.CreateLShr (Op0, Res, I.getName (), I.isExact ()));
1623- }
16241605
16251606 return nullptr ;
16261607}
0 commit comments