- Notifications
You must be signed in to change notification settings - Fork 15.3k
ValueTracking: Merge fcmpImpliesClass and fcmpToClassTest #66522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Member
| @llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-analysis ChangesRushing this one out before vacation starts. Refactoring on top of #66505Patch is 128.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66522.diff 6 Files Affected:
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 695f2fecae885b7..8fafdec200fed2c 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -235,6 +235,33 @@ std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred, const APFloat *ConstRHS, bool LookThroughSrc = true); +/// Compute the possible floating-point classes that \p LHS could be based on +/// fcmp \Pred \p LHS, \p RHS. +/// +/// Returns { TestedValue, ClassesIfTrue, ClassesIfFalse } +/// +/// If the compare returns an exact class test, ClassesIfTrue == ~ClassesIfFalse +/// +/// This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will +/// only succeed for a test of x > 0 implies positive, but not x > 1). +/// +/// If \p LookThroughSrc is true, consider the input value when computing the +/// mask. This may look through sign bit operations. +/// +/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair +/// element will always be LHS. +/// +std::tuple<Value *, FPClassTest, FPClassTest> +fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, + Value *RHS, bool LookThroughSrc = true); +std::tuple<Value *, FPClassTest, FPClassTest> +fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, + FPClassTest RHS, bool LookThroughSrc = true); +std::tuple<Value *, FPClassTest, FPClassTest> +fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, + const APFloat &RHS, bool LookThroughSrc = true); + + struct KnownFPClass { /// Floating-point classes the value could be one of. FPClassTest KnownFPClasses = fcAllFlags; diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..ef895bff22e7cb3 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4008,7 +4008,7 @@ std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred, bool LookThroughSrc) { const APFloat *ConstRHS; if (!match(RHS, m_APFloatAllowUndef(ConstRHS))) - return {nullptr, fcNone}; + return {nullptr, fcAllFlags}; return fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc); } @@ -4016,67 +4016,104 @@ std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred, std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, const APFloat *ConstRHS, bool LookThroughSrc) { + + auto [Src, ClassIfTrue, ClassIfFalse] = + fcmpImpliesClass(Pred, F, LHS, *ConstRHS, LookThroughSrc); + if (Src && ClassIfTrue == ~ClassIfFalse) + return {Src, ClassIfTrue}; + return {nullptr, fcAllFlags}; +} + +/// Return the return value for fcmpImpliesClass for a compare that produces an +/// exact class test. +static std::tuple<Value *, FPClassTest, FPClassTest> exactClass(Value *V, + FPClassTest M) { + return {V, M, ~M}; +} + +std::tuple<Value *, FPClassTest, FPClassTest> +llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, + FPClassTest RHSClass, bool LookThroughSrc) { + assert(RHSClass != fcNone); + + const FPClassTest OrigClass = RHSClass; + + Value *Src = LHS; + const bool IsNegativeRHS = (RHSClass & fcNegative) == RHSClass; + const bool IsPositiveRHS = (RHSClass & fcPositive) == RHSClass; + const bool IsNaN = (RHSClass & ~fcNan) == fcNone; + + if (IsNaN) { + // fcmp o__ x, nan -> false + // fcmp u__ x, nan -> true + return exactClass(Src, CmpInst::isOrdered(Pred) ? fcNone : fcAllFlags); + } + // fcmp ord x, zero|normal|subnormal|inf -> ~fcNan - if (Pred == FCmpInst::FCMP_ORD && !ConstRHS->isNaN()) - return {LHS, ~fcNan}; + if (Pred == FCmpInst::FCMP_ORD) + return {Src, ~fcNan, fcNan}; // fcmp uno x, zero|normal|subnormal|inf -> fcNan - if (Pred == FCmpInst::FCMP_UNO && !ConstRHS->isNaN()) - return {LHS, fcNan}; + if (Pred == FCmpInst::FCMP_UNO) + return {Src, fcNan, ~fcNan}; - if (ConstRHS->isZero()) { + const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src))); + if (IsFabs) + RHSClass = llvm::inverse_fabs(RHSClass); + + const bool IsZero = (OrigClass & fcZero) == OrigClass; + if (IsZero) { // Compares with fcNone are only exactly equal to fcZero if input denormals // are not flushed. // TODO: Handle DAZ by expanding masks to cover subnormal cases. if (Pred != FCmpInst::FCMP_ORD && Pred != FCmpInst::FCMP_UNO && !inputDenormalIsIEEE(F, LHS->getType())) - return {nullptr, fcNone}; + return {nullptr, fcAllFlags, fcAllFlags}; switch (Pred) { case FCmpInst::FCMP_OEQ: // Match x == 0.0 - return {LHS, fcZero}; + return exactClass(Src, fcZero); case FCmpInst::FCMP_UEQ: // Match isnan(x) || (x == 0.0) - return {LHS, fcZero | fcNan}; + return exactClass(Src, fcZero | fcNan); case FCmpInst::FCMP_UNE: // Match (x != 0.0) - return {LHS, ~fcZero}; + return exactClass(Src, ~fcZero); case FCmpInst::FCMP_ONE: // Match !isnan(x) && x != 0.0 - return {LHS, ~fcNan & ~fcZero}; + return exactClass(Src, ~fcNan & ~fcZero); case FCmpInst::FCMP_ORD: // Canonical form of ord/uno is with a zero. We could also handle // non-canonical other non-NaN constants or LHS == RHS. - return {LHS, ~fcNan}; + return exactClass(Src, ~fcNan); case FCmpInst::FCMP_UNO: - return {LHS, fcNan}; + return exactClass(Src, fcNan); case FCmpInst::FCMP_OGT: // x > 0 - return {LHS, fcPosSubnormal | fcPosNormal | fcPosInf}; + return exactClass(Src, fcPosSubnormal | fcPosNormal | fcPosInf); case FCmpInst::FCMP_UGT: // isnan(x) || x > 0 - return {LHS, fcPosSubnormal | fcPosNormal | fcPosInf | fcNan}; + return exactClass(Src, fcPosSubnormal | fcPosNormal | fcPosInf | fcNan); case FCmpInst::FCMP_OGE: // x >= 0 - return {LHS, fcPositive | fcNegZero}; + return exactClass(Src, fcPositive | fcNegZero); case FCmpInst::FCMP_UGE: // isnan(x) || x >= 0 - return {LHS, fcPositive | fcNegZero | fcNan}; + return exactClass(Src, fcPositive | fcNegZero | fcNan); case FCmpInst::FCMP_OLT: // x < 0 - return {LHS, fcNegSubnormal | fcNegNormal | fcNegInf}; + return exactClass(Src, fcNegSubnormal | fcNegNormal | fcNegInf); case FCmpInst::FCMP_ULT: // isnan(x) || x < 0 - return {LHS, fcNegSubnormal | fcNegNormal | fcNegInf | fcNan}; + return exactClass(Src, fcNegSubnormal | fcNegNormal | fcNegInf | fcNan); case FCmpInst::FCMP_OLE: // x <= 0 - return {LHS, fcNegative | fcPosZero}; + return exactClass(Src, fcNegative | fcPosZero); case FCmpInst::FCMP_ULE: // isnan(x) || x <= 0 - return {LHS, fcNegative | fcPosZero | fcNan}; + return exactClass(Src, fcNegative | fcPosZero | fcNan); default: break; } - return {nullptr, fcNone}; + return {nullptr, fcAllFlags, fcAllFlags}; } - Value *Src = LHS; - const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src))); + const bool IsDenormalRHS = (OrigClass & fcSubnormal) == OrigClass; - // Compute the test mask that would return true for the ordered comparisons. - FPClassTest Mask; + const bool IsInf = (OrigClass & fcInf) == OrigClass; + if (IsInf) { + FPClassTest Mask = fcAllFlags; - if (ConstRHS->isInfinity()) { switch (Pred) { case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_UNE: { @@ -4091,8 +4128,7 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, // fcmp une fabs(x), +inf -> is_fpclass x, ~fcInf // fcmp une x, -inf -> is_fpclass x, ~fcNegInf // fcmp une fabs(x), -inf -> is_fpclass x, fcAllFlags -> true - - if (ConstRHS->isNegative()) { + if (IsNegativeRHS) { Mask = fcNegInf; if (IsFabs) Mask = fcNone; @@ -4101,7 +4137,6 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, if (IsFabs) Mask |= fcNegInf; } - break; } case FCmpInst::FCMP_ONE: @@ -4116,7 +4151,7 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, // fcmp ueq (fabs x), +inf -> is_fpclass x, fcInf|fcNan // fcmp ueq x, -inf -> is_fpclass x, fcNegInf|fcNan // fcmp ueq fabs(x), -inf -> is_fpclass x, fcNan - if (ConstRHS->isNegative()) { + if (IsNegativeRHS) { Mask = ~fcNegInf & ~fcNan; if (IsFabs) Mask = ~fcNan; @@ -4130,7 +4165,7 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, } case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_UGE: { - if (ConstRHS->isNegative()) { + if (IsNegativeRHS) { // No value is ordered and less than negative infinity. // All values are unordered with or at least negative infinity. // fcmp olt x, -inf -> false @@ -4150,8 +4185,8 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, } case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_ULT: { - if (ConstRHS->isNegative()) // TODO - return {nullptr, fcNone}; + if (IsNegativeRHS) // TODO + return {nullptr, fcAllFlags, fcAllFlags}; // fcmp oge fabs(x), +inf -> fcInf // fcmp oge x, +inf -> fcPosInf @@ -4164,17 +4199,140 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, } case FCmpInst::FCMP_OGT: case FCmpInst::FCMP_ULE: { - if (ConstRHS->isNegative()) - return {nullptr, fcNone}; + if (IsNegativeRHS) + return {nullptr, fcAllFlags, fcAllFlags}; // No value is ordered and greater than infinity. Mask = fcNone; break; } default: - return {nullptr, fcNone}; + return {nullptr, fcAllFlags, fcAllFlags}; + } + + // Invert the comparison for the unordered cases. + if (FCmpInst::isUnordered(Pred)) + Mask = ~Mask; + + return exactClass(Src, Mask); + } + + 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}; + + assert((RHSClass == fcNone || RHSClass == fcPosNormal || + RHSClass == fcNegNormal || RHSClass == fcNormal || + RHSClass == fcPosSubnormal || RHSClass == fcNegSubnormal || + RHSClass == fcSubnormal) && + "should have been recognized as an exact class test"); + + 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}; } - } else if (ConstRHS->isSmallestNormalized() && !ConstRHS->isNegative()) { + + FPClassTest ClassesLE = fcNegInf | fcNegNormal; + FPClassTest ClassesGE = fcPositive | fcNegZero | fcNegSubnormal; + + if (IsDenormalRHS) + 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 (IsDenormalRHS) + ClassesGE |= fcPosNormal; + else + ClassesLE |= fcPosSubnormal; + + FPClassTest FalseClasses = RHSClass; + 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 | FalseClasses}; + case FCmpInst::FCMP_UGT: + case FCmpInst::FCMP_UGE: + return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | FalseClasses}; + case FCmpInst::FCMP_OLT: + case FCmpInst::FCMP_OLE: + return {Src, ClassesLE, ~ClassesLE | FalseClasses}; + case FCmpInst::FCMP_ULT: + case FCmpInst::FCMP_ULE: + return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | FalseClasses}; + default: + break; + } + } + + return {nullptr, fcAllFlags, fcAllFlags}; +} + +std::tuple<Value *, FPClassTest, FPClassTest> +llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, + const APFloat &ConstRHS, bool LookThroughSrc) { + // We can refine checks against smallest normal / largest denormal to an + // exact class test. + if (!ConstRHS.isNegative() && ConstRHS.isSmallestNormalized()) { + Value *Src = LHS; + const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src))); + + FPClassTest Mask; // Match pattern that's used in __builtin_isnormal. switch (Pred) { case FCmpInst::FCMP_OLT: @@ -4201,20 +4359,29 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, break; } default: - return {nullptr, fcNone}; + return fcmpImpliesClass(Pred, F, LHS, ConstRHS.classify(), + LookThroughSrc); } - } else if (ConstRHS->isNaN()) { - // fcmp o__ x, nan -> false - // fcmp u__ x, nan -> true - Mask = fcNone; - } else - return {nullptr, fcNone}; - // Invert the comparison for the unordered cases. - if (FCmpInst::isUnordered(Pred)) - Mask = ~Mask; + // Invert the comparison for the unordered cases. + if (FCmpInst::isUnordered(Pred)) + Mask = ~Mask; - return {Src, Mask}; + return exactClass(Src, Mask); + } + + return fcmpImpliesClass(Pred, F, LHS, ConstRHS.classify(), LookThroughSrc); +} + +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}; + + // TODO: Just call computeKnownFPClass for RHS to handle non-constants. + return fcmpImpliesClass(Pred, F, LHS, *ConstRHS, LookThroughSrc); } static FPClassTest computeKnownFPClassFromAssumes(const Value *V, @@ -4241,18 +4408,22 @@ 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)))) { - 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; + 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; + } } } else if (match(I->getArgOperand(0), m_Intrinsic<Intrinsic::is_fpclass>( @@ -4400,7 +4571,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest FilterRHS = fcAllFlags; Value *TestedValue = nullptr; - FPClassTest TestedMask = fcNone; + FPClassTest MaskIfTrue = fcAllFlags; + FPClassTest MaskIfFalse = fcAllFlags; uint64_t ClassVal = 0; const Function *F = cast<Instruction>(Op)->getFunction(); CmpInst::Predicate Pred; @@ -4412,20 +4584,22 @@ 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, TestedMask) = - fcmpToClassTest(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg); + std::tie(TestedValue, MaskIfTrue, MaskIfFalse) = + fcmpImpliesClass(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg); } else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>( m_Value(TestedValue), m_ConstantInt(ClassVal)))) { - TestedMask = static_cast<FPClassTest>(ClassVal); + FPClassTest TestedMask = static_cast<FPClassTest>(ClassVal); + MaskIfTrue = TestedMask; + MaskIfFalse = ~TestedMask; } if (TestedValue == LHS) { // match !isnan(x) ? x : y - FilterLHS = TestedMask; - } else if (TestedValue == RHS) { + FilterLHS = MaskIfTrue; + } else if (TestedValue == RHS) { // && IsExactClass // match !isnan(x) ? y : x - FilterRHS = ~TestedMask; + FilterRHS = MaskIfFalse; } KnownFPClass Known2; diff --git a/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll index 396b8c84fc898c9..212a8eb2f2451f7 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll @@ -11,7 +11,7 @@ declare void @llvm.assume(i1 noundef) ; can't be +inf define float @clamp_is_ogt_1_to_1(float %arg) { -; CHECK-LABEL: define float @clamp_is_ogt_1_to_1( +; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_ogt_1_to_1( ; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[IS_OGT_1:%.*]] = fcmp ogt float [[ARG]], 1.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_OGT_1]], float 1.000000e+00, float [[ARG]] @@ -23,7 +23,7 @@ define float @clamp_is_ogt_1_to_1(float %arg) { } define float @clamp_is_ogt_1_to_1_commute(float %arg) { -; CHECK-LABEL: define float @clamp_is_ogt_1_to_1_commute( +; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_ogt_1_to_1_commute( ; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[IS_ULE_1:%.*]] = fcmp ule float [[ARG]], 1.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_ULE_1]], float [[ARG]], float 1.000000e+00 @@ -36,7 +36,7 @@ define float @clamp_is_ogt_1_to_1_commute(float %arg) { ; can't be +inf or nan define float @clamp_is_ugt_1_to_1(float %arg) { -; CHECK-LABEL: define float @clamp_is_ugt_1_to_1( +; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_ugt_1_to_1( ; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[IS_UGT_1:%.*]] = fcmp ugt float [[ARG]], 1.000000e+00 ; CHECK-NEXT... [truncated] |
9cb03d4 to 26ba021 Compare | ✅ With the latest revision this PR passed the C/C++ code formatter. |
26ba021 to 0183305 Compare 0183305 to 076ab23 Compare Member
| Is there any progress? |
dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Dec 25, 2023
spavloff approved these changes Dec 27, 2023
Collaborator
spavloff left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
arsenm commented Jan 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
floating-point Floating-point math llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Rushing this one out before vacation starts. Refactoring on top of #66505