Skip to content

Commit

Permalink
[ValueTracking][NFC] move isKnownInversion to ValueTracking (#95321)
Browse files Browse the repository at this point in the history
I am using `isKnownInversion` in the following pr 
#94915

it is useful to have the method in a shared class so I can reuse it. I am not sure if `ValueTracking` is the correct place but it looks like most of the methods with the pattern `isKnownX` belong there.
  • Loading branch information
zjaffal authored Jun 13, 2024
1 parent 3bcd80a commit 22ff7c5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 27 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Analysis/ValueTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth = 0);
bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW = false,
bool AllowPoison = true);

/// Return true iff:
/// 1. X is poison implies Y is poison.
/// 2. X is true implies Y is false.
/// 3. X is false implies Y is true.
/// Otherwise, return false.
bool isKnownInversion(const Value *X, const Value *Y);

/// Returns true if the give value is known to be non-negative.
bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ,
unsigned Depth = 0);
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8176,6 +8176,28 @@ bool llvm::isKnownNegation(const Value *X, const Value *Y, bool NeedNSW,
match(Y, m_NSWSub(m_Specific(B), m_Specific(A)))));
}

bool llvm::isKnownInversion(const Value *X, const Value *Y) {
// Handle X = icmp pred A, B, Y = icmp pred A, C.
Value *A, *B, *C;
ICmpInst::Predicate Pred1, Pred2;
if (!match(X, m_ICmp(Pred1, m_Value(A), m_Value(B))) ||
!match(Y, m_c_ICmp(Pred2, m_Specific(A), m_Value(C))))
return false;

if (B == C)
return Pred1 == ICmpInst::getInversePredicate(Pred2);

// Try to infer the relationship from constant ranges.
const APInt *RHSC1, *RHSC2;
if (!match(B, m_APInt(RHSC1)) || !match(C, m_APInt(RHSC2)))
return false;

const auto CR1 = ConstantRange::makeExactICmpRegion(Pred1, *RHSC1);
const auto CR2 = ConstantRange::makeExactICmpRegion(Pred2, *RHSC2);

return CR1.inverse() == CR2;
}

static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
FastMathFlags FMF,
Value *CmpLHS, Value *CmpRHS,
Expand Down
27 changes: 0 additions & 27 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3520,33 +3520,6 @@ static bool matchFMulByZeroIfResultEqZero(InstCombinerImpl &IC, Value *Cmp0,
return false;
}

/// Return true iff:
/// 1. X is poison implies Y is poison.
/// 2. X is true implies Y is false.
/// 3. X is false implies Y is true.
/// Otherwise, return false.
static bool isKnownInversion(Value *X, Value *Y) {
// Handle X = icmp pred A, B, Y = icmp pred A, C.
Value *A, *B, *C;
ICmpInst::Predicate Pred1, Pred2;
if (!match(X, m_ICmp(Pred1, m_Value(A), m_Value(B))) ||
!match(Y, m_c_ICmp(Pred2, m_Specific(A), m_Value(C))))
return false;

if (B == C)
return Pred1 == ICmpInst::getInversePredicate(Pred2);

// Try to infer the relationship from constant ranges.
const APInt *RHSC1, *RHSC2;
if (!match(B, m_APInt(RHSC1)) || !match(C, m_APInt(RHSC2)))
return false;

const auto CR1 = ConstantRange::makeExactICmpRegion(Pred1, *RHSC1);
const auto CR2 = ConstantRange::makeExactICmpRegion(Pred2, *RHSC2);

return CR1.inverse() == CR2;
}

Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Value *CondVal = SI.getCondition();
Value *TrueVal = SI.getTrueValue();
Expand Down

0 comments on commit 22ff7c5

Please sign in to comment.