mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
[InstCombine] Extract "freely invert" related helpers (NFC)
This commit is contained in:
@@ -3994,6 +3994,29 @@ static Instruction *canonicalizeAbs(BinaryOperator &Xor,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool canFreelyInvert(InstCombiner &IC, Value *Op,
|
||||
Instruction *IgnoredUser) {
|
||||
if (!IC.isFreeToInvert(Op, /*WillInvertAllUses=*/true))
|
||||
return false;
|
||||
return match(Op, m_ImmConstant()) ||
|
||||
(isa<Instruction>(Op) && InstCombiner::canFreelyInvertAllUsersOf(
|
||||
cast<Instruction>(Op), IgnoredUser));
|
||||
}
|
||||
|
||||
static Value *freelyInvert(InstCombinerImpl &IC, Value *Op,
|
||||
Instruction *IgnoredUser) {
|
||||
if (auto *C = dyn_cast<Constant>(Op))
|
||||
return ConstantExpr::getNot(C);
|
||||
|
||||
IC.Builder.SetInsertPoint(
|
||||
&*cast<Instruction>(Op)->getInsertionPointAfterDef());
|
||||
Value *NotOp = IC.Builder.CreateNot(Op, Op->getName() + ".not");
|
||||
Op->replaceUsesWithIf(NotOp,
|
||||
[NotOp](Use &U) { return U.getUser() != NotOp; });
|
||||
IC.freelyInvertAllUsersOf(NotOp, IgnoredUser);
|
||||
return NotOp;
|
||||
}
|
||||
|
||||
// Transform
|
||||
// z = ~(x &/| y)
|
||||
// into:
|
||||
@@ -4018,28 +4041,11 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
|
||||
return false;
|
||||
|
||||
// And can the operands be adapted?
|
||||
for (Value *Op : {Op0, Op1})
|
||||
if (!(InstCombiner::isFreeToInvert(Op, /*WillInvertAllUses=*/true) &&
|
||||
(match(Op, m_ImmConstant()) ||
|
||||
(isa<Instruction>(Op) &&
|
||||
InstCombiner::canFreelyInvertAllUsersOf(cast<Instruction>(Op),
|
||||
/*IgnoredUser=*/&I)))))
|
||||
return false;
|
||||
if (!canFreelyInvert(*this, Op0, &I) || !canFreelyInvert(*this, Op1, &I))
|
||||
return false;
|
||||
|
||||
for (Value **Op : {&Op0, &Op1}) {
|
||||
Value *NotOp;
|
||||
if (auto *C = dyn_cast<Constant>(*Op)) {
|
||||
NotOp = ConstantExpr::getNot(C);
|
||||
} else {
|
||||
Builder.SetInsertPoint(
|
||||
&*cast<Instruction>(*Op)->getInsertionPointAfterDef());
|
||||
NotOp = Builder.CreateNot(*Op, (*Op)->getName() + ".not");
|
||||
(*Op)->replaceUsesWithIf(
|
||||
NotOp, [NotOp](Use &U) { return U.getUser() != NotOp; });
|
||||
freelyInvertAllUsersOf(NotOp, /*IgnoredUser=*/&I);
|
||||
}
|
||||
*Op = NotOp;
|
||||
}
|
||||
Op0 = freelyInvert(*this, Op0, &I);
|
||||
Op1 = freelyInvert(*this, Op1, &I);
|
||||
|
||||
Builder.SetInsertPoint(I.getInsertionPointAfterDef());
|
||||
Value *NewLogicOp;
|
||||
@@ -4073,20 +4079,11 @@ bool InstCombinerImpl::sinkNotIntoOtherHandOfLogicalOp(Instruction &I) {
|
||||
Value *NotOp0 = nullptr;
|
||||
Value *NotOp1 = nullptr;
|
||||
Value **OpToInvert = nullptr;
|
||||
if (match(Op0, m_Not(m_Value(NotOp0))) &&
|
||||
InstCombiner::isFreeToInvert(Op1, /*WillInvertAllUses=*/true) &&
|
||||
(match(Op1, m_ImmConstant()) ||
|
||||
(isa<Instruction>(Op1) &&
|
||||
InstCombiner::canFreelyInvertAllUsersOf(cast<Instruction>(Op1),
|
||||
/*IgnoredUser=*/&I)))) {
|
||||
if (match(Op0, m_Not(m_Value(NotOp0))) && canFreelyInvert(*this, Op1, &I)) {
|
||||
Op0 = NotOp0;
|
||||
OpToInvert = &Op1;
|
||||
} else if (match(Op1, m_Not(m_Value(NotOp1))) &&
|
||||
InstCombiner::isFreeToInvert(Op0, /*WillInvertAllUses=*/true) &&
|
||||
(match(Op0, m_ImmConstant()) ||
|
||||
(isa<Instruction>(Op0) &&
|
||||
InstCombiner::canFreelyInvertAllUsersOf(cast<Instruction>(Op0),
|
||||
/*IgnoredUser=*/&I)))) {
|
||||
canFreelyInvert(*this, Op0, &I)) {
|
||||
Op1 = NotOp1;
|
||||
OpToInvert = &Op0;
|
||||
} else
|
||||
@@ -4096,19 +4093,7 @@ bool InstCombinerImpl::sinkNotIntoOtherHandOfLogicalOp(Instruction &I) {
|
||||
if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
|
||||
return false;
|
||||
|
||||
if (auto *C = dyn_cast<Constant>(*OpToInvert)) {
|
||||
*OpToInvert = ConstantExpr::getNot(C);
|
||||
} else {
|
||||
Builder.SetInsertPoint(
|
||||
&*cast<Instruction>(*OpToInvert)->getInsertionPointAfterDef());
|
||||
Value *NotOpToInvert =
|
||||
Builder.CreateNot(*OpToInvert, (*OpToInvert)->getName() + ".not");
|
||||
(*OpToInvert)->replaceUsesWithIf(NotOpToInvert, [NotOpToInvert](Use &U) {
|
||||
return U.getUser() != NotOpToInvert;
|
||||
});
|
||||
freelyInvertAllUsersOf(NotOpToInvert, /*IgnoredUser=*/&I);
|
||||
*OpToInvert = NotOpToInvert;
|
||||
}
|
||||
*OpToInvert = freelyInvert(*this, *OpToInvert, &I);
|
||||
|
||||
Builder.SetInsertPoint(&*I.getInsertionPointAfterDef());
|
||||
Value *NewBinOp;
|
||||
|
||||
@@ -331,8 +331,6 @@ private:
|
||||
Instruction *foldNot(BinaryOperator &I);
|
||||
Instruction *foldBinOpOfDisplacedShifts(BinaryOperator &I);
|
||||
|
||||
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser = nullptr);
|
||||
|
||||
/// Determine if a pair of casts can be replaced by a single cast.
|
||||
///
|
||||
/// \param CI1 The first of a pair of casts.
|
||||
@@ -665,6 +663,7 @@ public:
|
||||
bool removeInstructionsBeforeUnreachable(Instruction &I);
|
||||
bool handleUnreachableFrom(Instruction *I);
|
||||
bool handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc);
|
||||
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser = nullptr);
|
||||
};
|
||||
|
||||
class Negator final {
|
||||
|
||||
Reference in New Issue
Block a user