Skip to content

Commit fd6a4f9

Browse files
committed
Leave in orig spot
1 parent 305c6c8 commit fd6a4f9

File tree

4 files changed

+111
-111
lines changed

4 files changed

+111
-111
lines changed

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,6 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
195195
PatternMatch::m_Value()));
196196
}
197197

198-
// Take the exact integer log2 of the value. If DoFold is true, create the
199-
// actual instructions, otherwise return a non-null dummy value. Return
200-
// nullptr on failure. Note, if DoFold is true the caller must ensure that
201-
// takeLog2 will succeed, otherwise it may create stray instructions.
202-
Value *takeLog2(Value *Op, unsigned Depth, bool AssumeNonZero, bool DoFold);
203-
204-
Value *tryGetLog2(Value *Op, bool AssumeNonZero) {
205-
if (takeLog2(Op, /*Depth=*/0, AssumeNonZero, /*DoFold=*/false))
206-
return takeLog2(Op, /*Depth=*/0, AssumeNonZero, /*DoFold=*/true);
207-
return nullptr;
208-
}
209-
210198
/// Return nonnull value if V is free to invert under the condition of
211199
/// WillInvertAllUses.
212200
/// If Builder is nonnull, it will return a simplified ~V.

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,18 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
785785
void handlePotentiallyDeadBlocks(SmallVectorImpl<BasicBlock *> &Worklist);
786786
void handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc);
787787
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser = nullptr);
788+
789+
// Take the exact integer log2 of the value. If DoFold is true, create the
790+
// actual instructions, otherwise return a non-null dummy value. Return
791+
// nullptr on failure. Note, if DoFold is true the caller must ensure that
792+
// takeLog2 will succeed, otherwise it may create stray instructions.
793+
Value *takeLog2(Value *Op, unsigned Depth, bool AssumeNonZero, bool DoFold);
794+
795+
Value *tryGetLog2(Value *Op, bool AssumeNonZero) {
796+
if (takeLog2(Op, /*Depth=*/0, AssumeNonZero, /*DoFold=*/false))
797+
return takeLog2(Op, /*Depth=*/0, AssumeNonZero, /*DoFold=*/true);
798+
return nullptr;
799+
}
788800
};
789801

790802
class Negator final {

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,105 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
13981398
return nullptr;
13991399
}
14001400

1401+
Value *InstCombinerImpl::takeLog2(Value *Op, unsigned Depth, bool AssumeNonZero,
1402+
bool DoFold) {
1403+
auto IfFold = [DoFold](function_ref<Value *()> Fn) {
1404+
if (!DoFold)
1405+
return reinterpret_cast<Value *>(-1);
1406+
return Fn();
1407+
};
1408+
1409+
// FIXME: assert that Op1 isn't/doesn't contain undef.
1410+
1411+
// log2(2^C) -> C
1412+
if (match(Op, m_Power2()))
1413+
return IfFold([&]() {
1414+
Constant *C = ConstantExpr::getExactLogBase2(cast<Constant>(Op));
1415+
if (!C)
1416+
llvm_unreachable("Failed to constant fold udiv -> logbase2");
1417+
return C;
1418+
});
1419+
1420+
// The remaining tests are all recursive, so bail out if we hit the limit.
1421+
if (Depth++ == MaxAnalysisRecursionDepth)
1422+
return nullptr;
1423+
1424+
// log2(zext X) -> zext log2(X)
1425+
// FIXME: Require one use?
1426+
Value *X, *Y;
1427+
if (match(Op, m_ZExt(m_Value(X))))
1428+
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
1429+
return IfFold([&]() { return Builder.CreateZExt(LogX, Op->getType()); });
1430+
1431+
// log2(trunc x) -> trunc log2(X)
1432+
// FIXME: Require one use?
1433+
if (match(Op, m_Trunc(m_Value(X)))) {
1434+
auto *TI = cast<TruncInst>(Op);
1435+
if (AssumeNonZero || TI->hasNoUnsignedWrap())
1436+
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
1437+
return IfFold([&]() {
1438+
return Builder.CreateTrunc(LogX, Op->getType(), "",
1439+
/*IsNUW=*/TI->hasNoUnsignedWrap());
1440+
});
1441+
}
1442+
1443+
// log2(X << Y) -> log2(X) + Y
1444+
// FIXME: Require one use unless X is 1?
1445+
if (match(Op, m_Shl(m_Value(X), m_Value(Y)))) {
1446+
auto *BO = cast<OverflowingBinaryOperator>(Op);
1447+
// nuw will be set if the `shl` is trivially non-zero.
1448+
if (AssumeNonZero || BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap())
1449+
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
1450+
return IfFold([&]() { return Builder.CreateAdd(LogX, Y); });
1451+
}
1452+
1453+
// log2(X >>u Y) -> log2(X) - Y
1454+
// FIXME: Require one use?
1455+
if (match(Op, m_LShr(m_Value(X), m_Value(Y)))) {
1456+
auto *PEO = cast<PossiblyExactOperator>(Op);
1457+
if (AssumeNonZero || PEO->isExact())
1458+
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
1459+
return IfFold([&]() { return Builder.CreateSub(LogX, Y); });
1460+
}
1461+
1462+
// log2(X & Y) -> either log2(X) or log2(Y)
1463+
// This requires `AssumeNonZero` as `X & Y` may be zero when X != Y.
1464+
if (AssumeNonZero && match(Op, m_And(m_Value(X), m_Value(Y)))) {
1465+
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
1466+
return IfFold([&]() { return LogX; });
1467+
if (Value *LogY = takeLog2(Y, Depth, AssumeNonZero, DoFold))
1468+
return IfFold([&]() { return LogY; });
1469+
}
1470+
1471+
// log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
1472+
// FIXME: Require one use?
1473+
if (SelectInst *SI = dyn_cast<SelectInst>(Op))
1474+
if (Value *LogX = takeLog2(SI->getOperand(1), Depth, AssumeNonZero, DoFold))
1475+
if (Value *LogY =
1476+
takeLog2(SI->getOperand(2), Depth, AssumeNonZero, DoFold))
1477+
return IfFold([&]() {
1478+
return Builder.CreateSelect(SI->getOperand(0), LogX, LogY);
1479+
});
1480+
1481+
// log2(umin(X, Y)) -> umin(log2(X), log2(Y))
1482+
// log2(umax(X, Y)) -> umax(log2(X), log2(Y))
1483+
auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op);
1484+
if (MinMax && MinMax->hasOneUse() && !MinMax->isSigned()) {
1485+
// Use AssumeNonZero as false here. Otherwise we can hit case where
1486+
// log2(umax(X, Y)) != umax(log2(X), log2(Y)) (because overflow).
1487+
if (Value *LogX = takeLog2(MinMax->getLHS(), Depth,
1488+
/*AssumeNonZero*/ false, DoFold))
1489+
if (Value *LogY = takeLog2(MinMax->getRHS(), Depth,
1490+
/*AssumeNonZero*/ false, DoFold))
1491+
return IfFold([&]() {
1492+
return Builder.CreateBinaryIntrinsic(MinMax->getIntrinsicID(), LogX,
1493+
LogY);
1494+
});
1495+
}
1496+
1497+
return nullptr;
1498+
}
1499+
14011500
/// If we have zero-extended operands of an unsigned div or rem, we may be able
14021501
/// to narrow the operation (sink the zext below the math).
14031502
static Instruction *narrowUDivURem(BinaryOperator &I,

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 0 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,105 +2565,6 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
25652565
return nullptr;
25662566
}
25672567

2568-
Value *InstCombiner::takeLog2(Value *Op, unsigned Depth, bool AssumeNonZero,
2569-
bool DoFold) {
2570-
auto IfFold = [DoFold](function_ref<Value *()> Fn) {
2571-
if (!DoFold)
2572-
return reinterpret_cast<Value *>(-1);
2573-
return Fn();
2574-
};
2575-
2576-
// FIXME: assert that Op1 isn't/doesn't contain undef.
2577-
2578-
// log2(2^C) -> C
2579-
if (match(Op, m_Power2()))
2580-
return IfFold([&]() {
2581-
Constant *C = ConstantExpr::getExactLogBase2(cast<Constant>(Op));
2582-
if (!C)
2583-
llvm_unreachable("Failed to constant fold udiv -> logbase2");
2584-
return C;
2585-
});
2586-
2587-
// The remaining tests are all recursive, so bail out if we hit the limit.
2588-
if (Depth++ == MaxAnalysisRecursionDepth)
2589-
return nullptr;
2590-
2591-
// log2(zext X) -> zext log2(X)
2592-
// FIXME: Require one use?
2593-
Value *X, *Y;
2594-
if (match(Op, m_ZExt(m_Value(X))))
2595-
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
2596-
return IfFold([&]() { return Builder.CreateZExt(LogX, Op->getType()); });
2597-
2598-
// log2(trunc x) -> trunc log2(X)
2599-
// FIXME: Require one use?
2600-
if (match(Op, m_Trunc(m_Value(X)))) {
2601-
auto *TI = cast<TruncInst>(Op);
2602-
if (AssumeNonZero || TI->hasNoUnsignedWrap())
2603-
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
2604-
return IfFold([&]() {
2605-
return Builder.CreateTrunc(LogX, Op->getType(), "",
2606-
/*IsNUW=*/TI->hasNoUnsignedWrap());
2607-
});
2608-
}
2609-
2610-
// log2(X << Y) -> log2(X) + Y
2611-
// FIXME: Require one use unless X is 1?
2612-
if (match(Op, m_Shl(m_Value(X), m_Value(Y)))) {
2613-
auto *BO = cast<OverflowingBinaryOperator>(Op);
2614-
// nuw will be set if the `shl` is trivially non-zero.
2615-
if (AssumeNonZero || BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap())
2616-
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
2617-
return IfFold([&]() { return Builder.CreateAdd(LogX, Y); });
2618-
}
2619-
2620-
// log2(X >>u Y) -> log2(X) - Y
2621-
// FIXME: Require one use?
2622-
if (match(Op, m_LShr(m_Value(X), m_Value(Y)))) {
2623-
auto *PEO = cast<PossiblyExactOperator>(Op);
2624-
if (AssumeNonZero || PEO->isExact())
2625-
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
2626-
return IfFold([&]() { return Builder.CreateSub(LogX, Y); });
2627-
}
2628-
2629-
// log2(X & Y) -> either log2(X) or log2(Y)
2630-
// This requires `AssumeNonZero` as `X & Y` may be zero when X != Y.
2631-
if (AssumeNonZero && match(Op, m_And(m_Value(X), m_Value(Y)))) {
2632-
if (Value *LogX = takeLog2(X, Depth, AssumeNonZero, DoFold))
2633-
return IfFold([&]() { return LogX; });
2634-
if (Value *LogY = takeLog2(Y, Depth, AssumeNonZero, DoFold))
2635-
return IfFold([&]() { return LogY; });
2636-
}
2637-
2638-
// log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
2639-
// FIXME: Require one use?
2640-
if (SelectInst *SI = dyn_cast<SelectInst>(Op))
2641-
if (Value *LogX = takeLog2(SI->getOperand(1), Depth, AssumeNonZero, DoFold))
2642-
if (Value *LogY =
2643-
takeLog2(SI->getOperand(2), Depth, AssumeNonZero, DoFold))
2644-
return IfFold([&]() {
2645-
return Builder.CreateSelect(SI->getOperand(0), LogX, LogY);
2646-
});
2647-
2648-
// log2(umin(X, Y)) -> umin(log2(X), log2(Y))
2649-
// log2(umax(X, Y)) -> umax(log2(X), log2(Y))
2650-
auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op);
2651-
if (MinMax && MinMax->hasOneUse() && !MinMax->isSigned()) {
2652-
// Use AssumeNonZero as false here. Otherwise we can hit case where
2653-
// log2(umax(X, Y)) != umax(log2(X), log2(Y)) (because overflow).
2654-
if (Value *LogX = takeLog2(MinMax->getLHS(), Depth,
2655-
/*AssumeNonZero*/ false, DoFold))
2656-
if (Value *LogY = takeLog2(MinMax->getRHS(), Depth,
2657-
/*AssumeNonZero*/ false, DoFold))
2658-
return IfFold([&]() {
2659-
return Builder.CreateBinaryIntrinsic(MinMax->getIntrinsicID(), LogX,
2660-
LogY);
2661-
});
2662-
}
2663-
2664-
return nullptr;
2665-
}
2666-
26672568
Value *InstCombiner::getFreelyInvertedImpl(Value *V, bool WillInvertAllUses,
26682569
BuilderTy *Builder,
26692570
bool &DoesConsume, unsigned Depth) {

0 commit comments

Comments
 (0)