@@ -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,18 +528,18 @@ 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 ,
531+ if (takeLog2 (Op0, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
535532 /* DoFold*/ false )) {
536- Value *Res = takeLog2 (Builder, Op0, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
533+ Value *Res = takeLog2 (Op0, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
537534 /* DoFold*/ true );
538535 BinaryOperator *Shl = BinaryOperator::CreateShl (Op1, Res);
539536 // We can only propegate nuw flag.
540537 Shl->setHasNoUnsignedWrap (HasNUW);
541538 return Shl;
542539 }
543- if (takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
540+ if (takeLog2 (Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
544541 /* DoFold*/ false )) {
545- Value *Res = takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
542+ Value *Res = takeLog2 (Op1, /* Depth*/ 0 , /* AssumeNonZero*/ false ,
546543 /* DoFold*/ true );
547544 BinaryOperator *Shl = BinaryOperator::CreateShl (Op0, Res);
548545 // We can only propegate nuw flag.
@@ -1407,111 +1404,6 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
14071404 return nullptr ;
14081405}
14091406
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) {
1417- auto IfFold = [DoFold](function_ref<Value *()> Fn) {
1418- if (!DoFold)
1419- return reinterpret_cast <Value *>(-1 );
1420- return Fn ();
1421- };
1422-
1423- // FIXME: assert that Op1 isn't/doesn't contain undef.
1424-
1425- // log2(2^C) -> C
1426- if (match (Op, m_Power2 ()))
1427- return IfFold ([&]() {
1428- Constant *C = ConstantExpr::getExactLogBase2 (cast<Constant>(Op));
1429- if (!C)
1430- llvm_unreachable (" Failed to constant fold udiv -> logbase2" );
1431- return C;
1432- });
1433-
1434- // The remaining tests are all recursive, so bail out if we hit the limit.
1435- if (Depth++ == MaxDepth)
1436- return nullptr ;
1437-
1438- // log2(zext X) -> zext log2(X)
1439- // FIXME: Require one use?
1440- Value *X, *Y;
1441- if (match (Op, m_ZExt (m_Value (X))))
1442- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1443- return IfFold ([&]() { return Builder.CreateZExt (LogX, Op->getType ()); });
1444-
1445- // log2(trunc x) -> trunc log2(X)
1446- // FIXME: Require one use?
1447- if (match (Op, m_Trunc (m_Value (X)))) {
1448- auto *TI = cast<TruncInst>(Op);
1449- if (AssumeNonZero || TI->hasNoUnsignedWrap ())
1450- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1451- return IfFold ([&]() {
1452- return Builder.CreateTrunc (LogX, Op->getType (), " " ,
1453- /* IsNUW=*/ TI->hasNoUnsignedWrap ());
1454- });
1455- }
1456-
1457- // log2(X << Y) -> log2(X) + Y
1458- // FIXME: Require one use unless X is 1?
1459- if (match (Op, m_Shl (m_Value (X), m_Value (Y)))) {
1460- auto *BO = cast<OverflowingBinaryOperator>(Op);
1461- // nuw will be set if the `shl` is trivially non-zero.
1462- if (AssumeNonZero || BO->hasNoUnsignedWrap () || BO->hasNoSignedWrap ())
1463- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1464- return IfFold ([&]() { return Builder.CreateAdd (LogX, Y); });
1465- }
1466-
1467- // log2(X >>u Y) -> log2(X) - Y
1468- // FIXME: Require one use?
1469- if (match (Op, m_LShr (m_Value (X), m_Value (Y)))) {
1470- auto *PEO = cast<PossiblyExactOperator>(Op);
1471- if (AssumeNonZero || PEO->isExact ())
1472- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1473- return IfFold ([&]() { return Builder.CreateSub (LogX, Y); });
1474- }
1475-
1476- // log2(X & Y) -> either log2(X) or log2(Y)
1477- // This requires `AssumeNonZero` as `X & Y` may be zero when X != Y.
1478- if (AssumeNonZero && match (Op, m_And (m_Value (X), m_Value (Y)))) {
1479- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1480- return IfFold ([&]() { return LogX; });
1481- if (Value *LogY = takeLog2 (Builder, Y, Depth, AssumeNonZero, DoFold))
1482- return IfFold ([&]() { return LogY; });
1483- }
1484-
1485- // log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
1486- // FIXME: Require one use?
1487- 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))
1492- return IfFold ([&]() {
1493- return Builder.CreateSelect (SI->getOperand (0 ), LogX, LogY);
1494- });
1495-
1496- // log2(umin(X, Y)) -> umin(log2(X), log2(Y))
1497- // log2(umax(X, Y)) -> umax(log2(X), log2(Y))
1498- auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op);
1499- if (MinMax && MinMax->hasOneUse () && !MinMax->isSigned ()) {
1500- // Use AssumeNonZero as false here. Otherwise we can hit case where
1501- // log2(umax(X, Y)) != umax(log2(X), log2(Y)) (because overflow).
1502- if (Value *LogX = takeLog2 (Builder, MinMax->getLHS (), Depth,
1503- /* AssumeNonZero*/ false , DoFold))
1504- if (Value *LogY = takeLog2 (Builder, MinMax->getRHS (), Depth,
1505- /* AssumeNonZero*/ false , DoFold))
1506- return IfFold ([&]() {
1507- return Builder.CreateBinaryIntrinsic (MinMax->getIntrinsicID (), LogX,
1508- LogY);
1509- });
1510- }
1511-
1512- return nullptr ;
1513- }
1514-
15151407// / If we have zero-extended operands of an unsigned div or rem, we may be able
15161408// / to narrow the operation (sink the zext below the math).
15171409static Instruction *narrowUDivURem (BinaryOperator &I,
@@ -1614,9 +1506,9 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
16141506 }
16151507
16161508 // Op1 udiv Op2 -> Op1 lshr log2(Op2), if log2() folds away.
1617- if (takeLog2 (Builder, Op1, /* Depth*/ 0 , /* AssumeNonZero*/ true ,
1509+ if (takeLog2 (Op1, /* Depth*/ 0 , /* AssumeNonZero*/ true ,
16181510 /* DoFold*/ false )) {
1619- Value *Res = takeLog2 (Builder, Op1, /* Depth*/ 0 ,
1511+ Value *Res = takeLog2 (Op1, /* Depth*/ 0 ,
16201512 /* AssumeNonZero*/ true , /* DoFold*/ true );
16211513 return replaceInstUsesWith (
16221514 I, Builder.CreateLShr (Op0, Res, I.getName (), I.isExact ()));
0 commit comments