@@ -185,9 +185,6 @@ static Value *foldMulShl1(BinaryOperator &Mul, bool CommuteOperands,
185
185
return nullptr ;
186
186
}
187
187
188
- static Value *takeLog2 (IRBuilderBase &Builder, Value *Op, unsigned Depth,
189
- bool AssumeNonZero, bool DoFold);
190
-
191
188
Instruction *InstCombinerImpl::visitMul (BinaryOperator &I) {
192
189
Value *Op0 = I.getOperand (0 ), *Op1 = I.getOperand (1 );
193
190
if (Value *V =
@@ -531,19 +528,13 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
531
528
// (shl Op1, Log2(Op0))
532
529
// if Log2(Op1) folds away ->
533
530
// (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 )) {
538
532
BinaryOperator *Shl = BinaryOperator::CreateShl (Op1, Res);
539
533
// We can only propegate nuw flag.
540
534
Shl->setHasNoUnsignedWrap (HasNUW);
541
535
return Shl;
542
536
}
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 )) {
547
538
BinaryOperator *Shl = BinaryOperator::CreateShl (Op0, Res);
548
539
// We can only propegate nuw flag.
549
540
Shl->setHasNoUnsignedWrap (HasNUW);
@@ -1407,13 +1398,8 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
1407
1398
return nullptr ;
1408
1399
}
1409
1400
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) {
1417
1403
auto IfFold = [DoFold](function_ref<Value *()> Fn) {
1418
1404
if (!DoFold)
1419
1405
return reinterpret_cast <Value *>(-1 );
@@ -1432,22 +1418,22 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
1432
1418
});
1433
1419
1434
1420
// The remaining tests are all recursive, so bail out if we hit the limit.
1435
- if (Depth++ == MaxDepth )
1421
+ if (Depth++ == MaxAnalysisRecursionDepth )
1436
1422
return nullptr ;
1437
1423
1438
1424
// log2(zext X) -> zext log2(X)
1439
1425
// FIXME: Require one use?
1440
1426
Value *X, *Y;
1441
1427
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))
1443
1429
return IfFold ([&]() { return Builder.CreateZExt (LogX, Op->getType ()); });
1444
1430
1445
1431
// log2(trunc x) -> trunc log2(X)
1446
1432
// FIXME: Require one use?
1447
1433
if (match (Op, m_Trunc (m_Value (X)))) {
1448
1434
auto *TI = cast<TruncInst>(Op);
1449
1435
if (AssumeNonZero || TI->hasNoUnsignedWrap ())
1450
- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1436
+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
1451
1437
return IfFold ([&]() {
1452
1438
return Builder.CreateTrunc (LogX, Op->getType (), " " ,
1453
1439
/* IsNUW=*/ TI->hasNoUnsignedWrap ());
@@ -1460,7 +1446,7 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
1460
1446
auto *BO = cast<OverflowingBinaryOperator>(Op);
1461
1447
// nuw will be set if the `shl` is trivially non-zero.
1462
1448
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))
1464
1450
return IfFold ([&]() { return Builder.CreateAdd (LogX, Y); });
1465
1451
}
1466
1452
@@ -1469,26 +1455,25 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
1469
1455
if (match (Op, m_LShr (m_Value (X), m_Value (Y)))) {
1470
1456
auto *PEO = cast<PossiblyExactOperator>(Op);
1471
1457
if (AssumeNonZero || PEO->isExact ())
1472
- if (Value *LogX = takeLog2 (Builder, X, Depth, AssumeNonZero, DoFold))
1458
+ if (Value *LogX = takeLog2 (X, Depth, AssumeNonZero, DoFold))
1473
1459
return IfFold ([&]() { return Builder.CreateSub (LogX, Y); });
1474
1460
}
1475
1461
1476
1462
// log2(X & Y) -> either log2(X) or log2(Y)
1477
1463
// This requires `AssumeNonZero` as `X & Y` may be zero when X != Y.
1478
1464
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))
1480
1466
return IfFold ([&]() { return LogX; });
1481
- if (Value *LogY = takeLog2 (Builder, Y, Depth, AssumeNonZero, DoFold))
1467
+ if (Value *LogY = takeLog2 (Y, Depth, AssumeNonZero, DoFold))
1482
1468
return IfFold ([&]() { return LogY; });
1483
1469
}
1484
1470
1485
1471
// log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
1486
1472
// FIXME: Require one use?
1487
1473
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))
1492
1477
return IfFold ([&]() {
1493
1478
return Builder.CreateSelect (SI->getOperand (0 ), LogX, LogY);
1494
1479
});
@@ -1499,9 +1484,9 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
1499
1484
if (MinMax && MinMax->hasOneUse () && !MinMax->isSigned ()) {
1500
1485
// Use AssumeNonZero as false here. Otherwise we can hit case where
1501
1486
// 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,
1503
1488
/* AssumeNonZero*/ false , DoFold))
1504
- if (Value *LogY = takeLog2 (Builder, MinMax->getRHS (), Depth,
1489
+ if (Value *LogY = takeLog2 (MinMax->getRHS (), Depth,
1505
1490
/* AssumeNonZero*/ false , DoFold))
1506
1491
return IfFold ([&]() {
1507
1492
return Builder.CreateBinaryIntrinsic (MinMax->getIntrinsicID (), LogX,
@@ -1614,13 +1599,9 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
1614
1599
}
1615
1600
1616
1601
// 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 ))
1621
1603
return replaceInstUsesWith (
1622
1604
I, Builder.CreateLShr (Op0, Res, I.getName (), I.isExact ()));
1623
- }
1624
1605
1625
1606
return nullptr ;
1626
1607
}
0 commit comments