aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2023-11-10 14:40:44 +0100
committerHans Wennborg <hans@chromium.org>2023-11-10 14:45:52 +0100
commit96a0d714d58e48c363ee6abbbcdfd7a6ce646ac1 (patch)
treeed74a941f3bc4c38db03693b49f1fe743ba0565f /llvm/lib/Analysis/ValueTracking.cpp
parent10ce319320adba3a6a5e11407af03b44d3622c71 (diff)
downloadllvm-96a0d714d58e48c363ee6abbbcdfd7a6ce646ac1.zip
llvm-96a0d714d58e48c363ee6abbbcdfd7a6ce646ac1.tar.gz
llvm-96a0d714d58e48c363ee6abbbcdfd7a6ce646ac1.tar.bz2
Revert "ValueTracking: Identify implied fp classes by general fcmp (#66505)"
This causes asserts to fire: llvm/lib/Analysis/ValueTracking.cpp:4262: std::tuple<Value *, FPClassTest, FPClassTest> llvm::fcmpImpliesClass(CmpInst::Predicate, const Function &, Value *, const APFloat *, bool): Assertion `(RHSClass == fcPosNormal || RHSClass == fcNegNormal || RHSClass == fcPosSubnormal || RHSClass == fcNegSubnormal) && "should have been recognized as an exact class test"' failed. See comments on the PR. > Previously we could recognize exact class tests performed by > an fcmp with special values (0s, infs and smallest normal). > Expand this to recognize the implied classes by a compare with a general > constant. e.g. fcmp ogt x, 1 implies positive and non-0. > > The API should be better merged with fcmpToClassTest but that > made the diff way bigger, will try to do that in a future > patch. This reverts commit dc3faf0ed0e3f1ea9e435a006167d9649f865da1.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp177
1 files changed, 19 insertions, 158 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 05eaaed..923ff04 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4248,139 +4248,6 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
return {Src, Mask};
}
-std::tuple<Value *, FPClassTest, FPClassTest>
-llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
- const APFloat *ConstRHS, bool LookThroughSrc) {
- auto [Val, ClassMask] =
- fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc);
- if (Val)
- return {Val, ClassMask, ~ClassMask};
-
- FPClassTest RHSClass = ConstRHS->classify();
- assert((RHSClass == fcPosNormal || RHSClass == fcNegNormal ||
- RHSClass == fcPosSubnormal || RHSClass == fcNegSubnormal) &&
- "should have been recognized as an exact class test");
-
- const bool IsNegativeRHS = (RHSClass & fcNegative) == RHSClass;
- const bool IsPositiveRHS = (RHSClass & fcPositive) == RHSClass;
-
- assert(IsNegativeRHS == ConstRHS->isNegative());
- assert(IsPositiveRHS == !ConstRHS->isNegative());
-
- Value *Src = LHS;
- const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src)));
-
- if (IsFabs)
- RHSClass = llvm::inverse_fabs(RHSClass);
-
- if (Pred == FCmpInst::FCMP_OEQ)
- return {Src, RHSClass, fcAllFlags};
-
- if (Pred == FCmpInst::FCMP_UEQ) {
- FPClassTest Class = RHSClass | fcNan;
- return {Src, Class, ~fcNan};
- }
-
- if (Pred == FCmpInst::FCMP_ONE)
- return {Src, ~fcNan, RHSClass};
-
- if (Pred == FCmpInst::FCMP_UNE)
- return {Src, fcAllFlags, RHSClass};
-
- if (IsNegativeRHS) {
- // TODO: Handle fneg(fabs)
- if (IsFabs) {
- // fabs(x) o> -k -> fcmp ord x, x
- // fabs(x) u> -k -> true
- // fabs(x) o< -k -> false
- // fabs(x) u< -k -> fcmp uno x, x
- switch (Pred) {
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_OGE:
- return {Src, ~fcNan, fcNan};
- case FCmpInst::FCMP_UGT:
- case FCmpInst::FCMP_UGE:
- return {Src, fcAllFlags, fcNone};
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_OLE:
- return {Src, fcNone, fcAllFlags};
- case FCmpInst::FCMP_ULT:
- case FCmpInst::FCMP_ULE:
- return {Src, fcNan, ~fcNan};
- default:
- break;
- }
-
- return {nullptr, fcAllFlags, fcAllFlags};
- }
-
- FPClassTest ClassesLE = fcNegInf | fcNegNormal;
- FPClassTest ClassesGE = fcPositive | fcNegZero | fcNegSubnormal;
-
- if (ConstRHS->isDenormal())
- ClassesLE |= fcNegSubnormal;
- else
- ClassesGE |= fcNegNormal;
-
- switch (Pred) {
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_OGE:
- return {Src, ClassesGE, ~ClassesGE | RHSClass};
- case FCmpInst::FCMP_UGT:
- case FCmpInst::FCMP_UGE:
- return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_OLE:
- return {Src, ClassesLE, ~ClassesLE | RHSClass};
- case FCmpInst::FCMP_ULT:
- case FCmpInst::FCMP_ULE:
- return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
- default:
- break;
- }
- } else if (IsPositiveRHS) {
- FPClassTest ClassesGE = fcPosNormal | fcPosInf;
- FPClassTest ClassesLE = fcNegative | fcPosZero | fcPosNormal;
- if (ConstRHS->isDenormal())
- ClassesGE |= fcPosNormal;
- else
- ClassesLE |= fcPosSubnormal;
-
- if (IsFabs) {
- ClassesGE = llvm::inverse_fabs(ClassesGE);
- ClassesLE = llvm::inverse_fabs(ClassesLE);
- }
-
- switch (Pred) {
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_OGE:
- return {Src, ClassesGE, ~ClassesGE | RHSClass};
- case FCmpInst::FCMP_UGT:
- case FCmpInst::FCMP_UGE:
- return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_OLE:
- return {Src, ClassesLE, ~ClassesLE | RHSClass};
- case FCmpInst::FCMP_ULT:
- case FCmpInst::FCMP_ULE:
- return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
- default:
- break;
- }
- }
-
- return {nullptr, fcAllFlags, fcAllFlags};
-}
-
-std::tuple<Value *, FPClassTest, FPClassTest>
-llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
- Value *RHS, bool LookThroughSrc) {
- const APFloat *ConstRHS;
- if (!match(RHS, m_APFloatAllowUndef(ConstRHS)))
- return {nullptr, fcAllFlags, fcNone};
- return fcmpImpliesClass(Pred, F, LHS, ConstRHS, LookThroughSrc);
-}
-
static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
const SimplifyQuery &Q) {
FPClassTest KnownFromAssume = fcAllFlags;
@@ -4405,21 +4272,18 @@ static FPClassTest computeKnownFPClassFromAssumes(const Value *V,
Value *LHS, *RHS;
uint64_t ClassVal = 0;
if (match(I->getArgOperand(0), m_FCmp(Pred, m_Value(LHS), m_Value(RHS)))) {
- const APFloat *CRHS;
- if (match(RHS, m_APFloat(CRHS))) {
- // First see if we can fold in fabs/fneg into the test.
- auto [CmpVal, MaskIfTrue, MaskIfFalse] =
- fcmpImpliesClass(Pred, *F, LHS, CRHS, true);
- if (CmpVal == V)
- KnownFromAssume &= MaskIfTrue;
- else {
- // Try again without the lookthrough if we found a different source
- // value.
- auto [CmpVal, MaskIfTrue, MaskIfFalse] =
- fcmpImpliesClass(Pred, *F, LHS, CRHS, false);
- if (CmpVal == V)
- KnownFromAssume &= MaskIfTrue;
- }
+ auto [TestedValue, TestedMask] =
+ fcmpToClassTest(Pred, *F, LHS, RHS, true);
+ // First see if we can fold in fabs/fneg into the test.
+ if (TestedValue == V)
+ KnownFromAssume &= TestedMask;
+ else {
+ // Try again without the lookthrough if we found a different source
+ // value.
+ auto [TestedValue, TestedMask] =
+ fcmpToClassTest(Pred, *F, LHS, RHS, false);
+ if (TestedValue == V)
+ KnownFromAssume &= TestedMask;
}
} else if (match(I->getArgOperand(0),
m_Intrinsic<Intrinsic::is_fpclass>(
@@ -4567,8 +4431,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
FPClassTest FilterRHS = fcAllFlags;
Value *TestedValue = nullptr;
- FPClassTest MaskIfTrue = fcAllFlags;
- FPClassTest MaskIfFalse = fcAllFlags;
+ FPClassTest TestedMask = fcNone;
uint64_t ClassVal = 0;
const Function *F = cast<Instruction>(Op)->getFunction();
CmpInst::Predicate Pred;
@@ -4580,22 +4443,20 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// TODO: In some degenerate cases we can infer something if we try again
// without looking through sign operations.
bool LookThroughFAbsFNeg = CmpLHS != LHS && CmpLHS != RHS;
- std::tie(TestedValue, MaskIfTrue, MaskIfFalse) =
- fcmpImpliesClass(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg);
+ std::tie(TestedValue, TestedMask) =
+ fcmpToClassTest(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg);
} else if (match(Cond,
m_Intrinsic<Intrinsic::is_fpclass>(
m_Value(TestedValue), m_ConstantInt(ClassVal)))) {
- FPClassTest TestedMask = static_cast<FPClassTest>(ClassVal);
- MaskIfTrue = TestedMask;
- MaskIfFalse = ~TestedMask;
+ TestedMask = static_cast<FPClassTest>(ClassVal);
}
if (TestedValue == LHS) {
// match !isnan(x) ? x : y
- FilterLHS = MaskIfTrue;
- } else if (TestedValue == RHS) { // && IsExactClass
+ FilterLHS = TestedMask;
+ } else if (TestedValue == RHS) {
// match !isnan(x) ? y : x
- FilterRHS = MaskIfFalse;
+ FilterRHS = ~TestedMask;
}
KnownFPClass Known2;