[llvm] InstSimplify: support floating-point equivalences (PR #115152)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 11 06:22:30 PST 2024
================
@@ -4761,27 +4763,51 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
/// Try to simplify a select instruction when its condition operand is a
/// floating-point comparison.
static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
- const SimplifyQuery &Q) {
+ const SimplifyQuery &Q,
+ unsigned MaxRecurse) {
FCmpInst::Predicate Pred;
- if (!match(Cond, m_FCmp(Pred, m_Specific(T), m_Specific(F))) &&
- !match(Cond, m_FCmp(Pred, m_Specific(F), m_Specific(T))))
+ Value *CmpLHS, *CmpRHS;
+ if (!match(Cond, m_FCmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
+ return nullptr;
+ FCmpInst *I = cast<FCmpInst>(Cond);
+
+ bool IsEquiv = I->isEquivalence(),
+ IsInverseEquiv = I->isEquivalence(/*Invert=*/true);
+
+ if (IsInverseEquiv)
+ std::swap(T, F);
+
+ // Canonicalize CmpLHS to be T, and CmpRHS to be F, if they're swapped.
+ if (CmpLHS == F && CmpRHS == T)
+ std::swap(CmpLHS, CmpRHS);
+
+ // This transforms is safe if at least one operand is known to not be zero.
+ // Otherwise, the select can change the sign of a zero operand.
+ if (IsEquiv || IsInverseEquiv) {
+ if (Value *V =
+ simplifySelectWithEquivalence(CmpLHS, CmpRHS, T, F, Q, MaxRecurse))
+ return V;
+ if (Value *V =
+ simplifySelectWithEquivalence(CmpRHS, CmpLHS, T, F, Q, MaxRecurse))
+ return V;
+
+ // (T == F) ? T : F --> F
+ // (T != F) ? F : T --> F
+ return CmpLHS == T && CmpRHS == F ? F : nullptr;
----------------
nikic wrote:
But shouldn't this case at least be covered by the preceding simplify code?
https://github.com/llvm/llvm-project/pull/115152
More information about the llvm-commits
mailing list