Index: llvm/include/llvm/Analysis/ValueTracking.h =================================================================== --- llvm/include/llvm/Analysis/ValueTracking.h +++ llvm/include/llvm/Analysis/ValueTracking.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/FMF.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Intrinsics.h" #include @@ -229,6 +230,10 @@ const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc = true); +std::pair fcmpToClassTest(CmpInst::Predicate Pred, + const Function &F, Value *LHS, + const APFloat *ConstRHS, + bool LookThroughSrc = true); struct KnownFPClass { /// Floating-point classes the value could be one of. @@ -471,6 +476,28 @@ const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr, bool UseInstrInfo = true); +/// Wrapper to account for known fast math flags at the use instruction. +inline KnownFPClass computeKnownFPClass( + const Value *V, FastMathFlags FMF, const DataLayout &DL, + FPClassTest InterestedClasses = fcAllFlags, unsigned Depth = 0, + const TargetLibraryInfo *TLI = nullptr, AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr, + bool UseInstrInfo = true) { + if (FMF.noNaNs()) + InterestedClasses &= ~fcNan; + if (FMF.noInfs()) + InterestedClasses &= ~fcInf; + + KnownFPClass Result = computeKnownFPClass(V, DL, InterestedClasses, Depth, + TLI, AC, CxtI, DT, UseInstrInfo); + + if (FMF.noNaNs()) + Result.KnownFPClasses &= ~fcNan; + if (FMF.noInfs()) + Result.KnownFPClasses &= ~fcInf; + return Result; +} + /// Return true if we can prove that the specified FP value is never equal to /// -0.0. Users should use caution when considering PreserveSign /// denormal-fp-math. Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4060,19 +4060,6 @@ if (Pred == FCmpInst::FCMP_TRUE) return getTrue(RetTy); - // Fold (un)ordered comparison if we can determine there are no NaNs. - if (Pred == FCmpInst::FCMP_UNO || Pred == FCmpInst::FCMP_ORD) - if (FMF.noNaNs() || - (isKnownNeverNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT) && - isKnownNeverNaN(RHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))) - return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD); - - // NaN is unordered; NaN is not ordered. - assert((FCmpInst::isOrdered(Pred) || FCmpInst::isUnordered(Pred)) && - "Comparison must be either ordered or unordered"); - if (match(RHS, m_NaN())) - return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred)); - // fcmp pred x, poison and fcmp pred poison, x // fold to poison if (isa(LHS) || isa(RHS)) @@ -4094,80 +4081,86 @@ return getFalse(RetTy); } - // Handle fcmp with constant RHS. - // TODO: Use match with a specific FP value, so these work with vectors with - // undef lanes. - const APFloat *C; - if (match(RHS, m_APFloat(C))) { - // Check whether the constant is an infinity. - if (C->isInfinity()) { - if (C->isNegative()) { - switch (Pred) { - case FCmpInst::FCMP_OLT: - // No value is ordered and less than negative infinity. - return getFalse(RetTy); - case FCmpInst::FCMP_UGE: - // All values are unordered with or at least negative infinity. - return getTrue(RetTy); - default: - break; - } - } else { - switch (Pred) { - case FCmpInst::FCMP_OGT: - // No value is ordered and greater than infinity. - return getFalse(RetTy); - case FCmpInst::FCMP_ULE: - // All values are unordered with and at most infinity. - return getTrue(RetTy); - default: - break; - } - } + // Fold (un)ordered comparison if we can determine there are no NaNs. + // + // This catches the 2 variable input case, constants are handled below as a + // class-like compare. + if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) { + if (FMF.noNaNs() || + (isKnownNeverNaN(RHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT) && + isKnownNeverNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))) + return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD); + } - // LHS == Inf - if (Pred == FCmpInst::FCMP_OEQ && - isKnownNeverInfinity(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)) - return getFalse(RetTy); - // LHS != Inf - if (Pred == FCmpInst::FCMP_UNE && - isKnownNeverInfinity(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)) - return getTrue(RetTy); - // LHS == Inf || LHS == NaN - if (Pred == FCmpInst::FCMP_UEQ && - isKnownNeverInfOrNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)) + const APFloat *C = nullptr; + match(RHS, m_APFloatAllowUndef(C)); + std::optional FullKnownClassLHS; + + // Lazily compute the possible classes for LHS. Avoid computing it twice if + // RHS is a 0. + auto computeLHSClass = [=, &FullKnownClassLHS](FPClassTest InterestedFlags = + fcAllFlags) { + if (FullKnownClassLHS) + return *FullKnownClassLHS; + return computeKnownFPClass(LHS, FMF, Q.DL, InterestedFlags, 0, Q.TLI, Q.AC, + Q.CxtI, Q.DT, Q.IIQ.UseInstrInfo); + }; + + if (C && Q.CxtI) { + // Fold out compares that express a class test. + // + // FIXME: Should be able to perform folds without context + // instruction. Always pass in the context function? + + const Function *ParentF = Q.CxtI->getFunction(); + auto [ClassVal, ClassTest] = fcmpToClassTest(Pred, *ParentF, LHS, C); + if (ClassVal) { + FullKnownClassLHS = computeLHSClass(); + if ((FullKnownClassLHS->KnownFPClasses & ClassTest) == fcNone) return getFalse(RetTy); - // LHS != Inf && LHS != NaN - if (Pred == FCmpInst::FCMP_ONE && - isKnownNeverInfOrNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)) + if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone) return getTrue(RetTy); } + } + + // Handle fcmp with constant RHS. + if (C) { + // TODO: Need version fcmpToClassTest which returns implied class when the + // compare isn't a complete class test. e.g. > 1.0 implies fcPositive, but + // isn't implementable as a class call. if (C->isNegative() && !C->isNegZero()) { + FPClassTest Interested = fcPositive | fcNan; + + // FIXME: This assert won't always hold if we depend on the context + // instruction above assert(!C->isNaN() && "Unexpected NaN constant!"); // TODO: We can catch more cases by using a range check rather than // relying on CannotBeOrderedLessThanZero. switch (Pred) { case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_UGT: - case FCmpInst::FCMP_UNE: + case FCmpInst::FCMP_UNE: { + KnownFPClass KnownClass = computeLHSClass(Interested); + // (X >= 0) implies (X > C) when (C < 0) - if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, - Q.AC, Q.CxtI, Q.DT)) + if (KnownClass.cannotBeOrderedLessThanZero()) return getTrue(RetTy); break; + } case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_OLE: - case FCmpInst::FCMP_OLT: + case FCmpInst::FCMP_OLT: { + KnownFPClass KnownClass = computeLHSClass(Interested); + // (X >= 0) implies !(X < C) when (C < 0) - if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, - Q.DT)) + if (KnownClass.cannotBeOrderedLessThanZero()) return getFalse(RetTy); break; + } default: break; } } - // Check comparison of [minnum/maxnum with constant] with other constant. const APFloat *C2; if ((match(LHS, m_Intrinsic(m_Value(), m_APFloat(C2))) && @@ -4214,13 +4207,15 @@ } } + // TODO: Could fold this with above if there were a matcher which returned all + // classes in a non-splat vector. if (match(RHS, m_AnyZeroFP())) { + FPClassTest Interested = FMF.noNaNs() ? fcPositive : fcPositive | fcNan; + switch (Pred) { case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_ULT: { - FPClassTest Interested = FMF.noNaNs() ? fcNegative : fcNegative | fcNan; - KnownFPClass Known = computeKnownFPClass(LHS, Q.DL, Interested, 0, - Q.TLI, Q.AC, Q.CxtI, Q.DT); + KnownFPClass Known = computeLHSClass(Interested); // Positive or zero X >= 0.0 --> true // Positive or zero X < 0.0 --> false @@ -4230,12 +4225,15 @@ break; } case FCmpInst::FCMP_UGE: - case FCmpInst::FCMP_OLT: + case FCmpInst::FCMP_OLT: { + KnownFPClass Known = computeLHSClass(Interested); + // Positive or zero or nan X >= 0.0 --> true // Positive or zero or nan X < 0.0 --> false - if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT)) + if (Known.cannotBeOrderedLessThanZero()) return Pred == FCmpInst::FCMP_UGE ? getTrue(RetTy) : getFalse(RetTy); break; + } default: break; } @@ -6816,6 +6814,9 @@ const SimplifyQuery &SQ, unsigned MaxRecurse) { assert(I->getFunction() && "instruction should be inserted in a function"); + assert((!SQ.CxtI || SQ.CxtI->getFunction() == I->getFunction()) && + "context instruction should be in the same function"); + const SimplifyQuery Q = SQ.CxtI ? SQ : SQ.getWithInstruction(I); switch (I->getOpcode()) { Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -3978,9 +3978,15 @@ Value *LHS, Value *RHS, bool LookThroughSrc) { const APFloat *ConstRHS; - if (!match(RHS, m_APFloat(ConstRHS))) + if (!match(RHS, m_APFloatAllowUndef(ConstRHS))) return {nullptr, fcNone}; + return fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc); +} + +std::pair +llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, + const APFloat *ConstRHS, bool LookThroughSrc) { // fcmp ord x, zero|normal|subnormal|inf -> ~fcNan if (Pred == FCmpInst::FCMP_ORD && !ConstRHS->isNaN()) return {LHS, ~fcNan}; Index: llvm/test/Transforms/Attributor/nofpclass.ll =================================================================== --- llvm/test/Transforms/Attributor/nofpclass.ll +++ llvm/test/Transforms/Attributor/nofpclass.ll @@ -598,8 +598,7 @@ ; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] ; CHECK-NEXT: [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR14]] -; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR14]] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] ; CHECK-NEXT: call void @extern.use.f16(half nofpclass(nan inf norm) [[ARG]]) ; CHECK-NEXT: call void @extern.use.f16(half nofpclass(nan inf nzero sub norm) [[FABS]]) ; CHECK-NEXT: ret half [[ARG]] Index: llvm/test/Transforms/InstCombine/fcmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/fcmp.ll +++ llvm/test/Transforms/InstCombine/fcmp.ll @@ -718,9 +718,7 @@ define i1 @is_signbit_set_simplify_zero(double %x) { ; CHECK-LABEL: @is_signbit_set_simplify_zero( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 0.000000e+00, double [[X:%.*]]) -; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %s = call double @llvm.copysign.f64(double 0.0, double %x) %r = fcmp ogt double %s, 0.0 @@ -731,9 +729,7 @@ define i1 @is_signbit_set_simplify_nan(double %x) { ; CHECK-LABEL: @is_signbit_set_simplify_nan( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 0xFFFFFFFFFFFFFFFF, double [[X:%.*]]) -; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x) %r = fcmp ogt double %s, 0.0 Index: llvm/test/Transforms/InstCombine/is_fpclass.ll =================================================================== --- llvm/test/Transforms/InstCombine/is_fpclass.ll +++ llvm/test/Transforms/InstCombine/is_fpclass.ll @@ -2438,8 +2438,7 @@ define i1 @test_class_is_zero_nozero_src(float nofpclass(zero) %arg) { ; CHECK-LABEL: @test_class_is_zero_nozero_src( -; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[CLASS]] +; CHECK-NEXT: ret i1 false ; %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96) ret i1 %class @@ -2569,8 +2568,7 @@ define i1 @test_class_is_neginf_noninf_src(float nofpclass(ninf) %arg) { ; CHECK-LABEL: @test_class_is_neginf_noninf_src( -; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0xFFF0000000000000 -; CHECK-NEXT: ret i1 [[CLASS]] +; CHECK-NEXT: ret i1 false ; %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4) ret i1 %class @@ -2595,8 +2593,7 @@ define i1 @test_class_is_posinf_nopinf_src(float nofpclass(pinf) %arg) { ; CHECK-LABEL: @test_class_is_posinf_nopinf_src( -; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[CLASS]] +; CHECK-NEXT: ret i1 false ; %class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512) ret i1 %class @@ -2724,8 +2721,7 @@ ; CHECK-LABEL: @test_class_is_nan_assume_uno( ; CHECK-NEXT: [[ORD:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 ; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]]) -; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[CLASS]] +; CHECK-NEXT: ret i1 true ; %ord = fcmp uno float %x, 0.0 call void @llvm.assume(i1 %ord) Index: llvm/test/Transforms/InstSimplify/floating-point-compare.ll =================================================================== --- llvm/test/Transforms/InstSimplify/floating-point-compare.ll +++ llvm/test/Transforms/InstSimplify/floating-point-compare.ll @@ -692,8 +692,7 @@ ; CHECK-LABEL: @assume_nan_ord( ; CHECK-NEXT: [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 ; CHECK-NEXT: call void @llvm.assume(i1 [[UNO]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X]], 1.000000e+00 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %uno = fcmp uno float %x, 0.0 call void @llvm.assume(i1 %uno) @@ -717,8 +716,7 @@ ; CHECK-LABEL: @assume_nan_uno( ; CHECK-NEXT: [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 ; CHECK-NEXT: call void @llvm.assume(i1 [[UNO]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X]], 1.000000e+00 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %uno = fcmp uno float %x, 0.0 call void @llvm.assume(i1 %uno) @@ -1561,10 +1559,7 @@ define i1 @ogt_zero_fabs_select_negone_or_pinf(i1 %cond) { ; CHECK-LABEL: @ogt_zero_fabs_select_negone_or_pinf( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float -1.000000e+00, float 0x7FF0000000000000 -; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]]) -; CHECK-NEXT: [[ONE:%.*]] = fcmp ogt float [[FABS]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[ONE]] +; CHECK-NEXT: ret i1 true ; entry: %select = select i1 %cond, float -1.0, float 0x7FF0000000000000 @@ -1576,10 +1571,7 @@ define i1 @ogt_zero_fabs_select_one_or_ninf(i1 %cond) { ; CHECK-LABEL: @ogt_zero_fabs_select_one_or_ninf( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float 0xFFF0000000000000 -; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]]) -; CHECK-NEXT: [[ONE:%.*]] = fcmp ogt float [[FABS]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[ONE]] +; CHECK-NEXT: ret i1 true ; entry: %select = select i1 %cond, float 1.0, float 0xFFF0000000000000 Index: llvm/test/Transforms/InstSimplify/known-never-infinity.ll =================================================================== --- llvm/test/Transforms/InstSimplify/known-never-infinity.ll +++ llvm/test/Transforms/InstSimplify/known-never-infinity.ll @@ -753,11 +753,7 @@ define i1 @isKnownNeverInfinity_log(double %x) { ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00) -; CHECK-NEXT: [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log.f64(double [[A]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0) %a = fadd ninf double %x.clamp.zero, 1.0 @@ -769,10 +765,7 @@ define i1 @isNotKnownNeverInfinity_log_maybe_negative(double %x) { ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log_maybe_negative ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log.f64(double [[X_NOT_INF]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.not.inf = fadd ninf double %x, 1.0 @@ -812,11 +805,7 @@ define i1 @isKnownNeverInfinity_log10(double %x) { ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log10 ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00) -; CHECK-NEXT: [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log10.f64(double [[A]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0) %a = fadd ninf double %x.clamp.zero, 1.0 @@ -828,10 +817,7 @@ define i1 @isNotKnownNeverInfinity_log10_maybe_negative(double %x) { ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log10_maybe_negative ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log10.f64(double [[X_NOT_INF]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.not.inf = fadd ninf double %x, 1.0 @@ -871,11 +857,7 @@ define i1 @isKnownNeverInfinity_log2(double %x) { ; CHECK-LABEL: define i1 @isKnownNeverInfinity_log2 ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_CLAMP_ZERO:%.*]] = call double @llvm.maxnum.f64(double [[X]], double 0.000000e+00) -; CHECK-NEXT: [[A:%.*]] = fadd ninf double [[X_CLAMP_ZERO]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log2.f64(double [[A]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0) %a = fadd ninf double %x.clamp.zero, 1.0 @@ -887,10 +869,7 @@ define i1 @isNotKnownNeverInfinity_log2_maybe_negative(double %x) { ; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log2_maybe_negative ; CHECK-SAME: (double [[X:%.*]]) { -; CHECK-NEXT: [[X_NOT_INF:%.*]] = fadd ninf double [[X]], 1.000000e+00 -; CHECK-NEXT: [[E:%.*]] = call double @llvm.log2.f64(double [[X_NOT_INF]]) -; CHECK-NEXT: [[R:%.*]] = fcmp une double [[E]], 0x7FF0000000000000 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %x.not.inf = fadd ninf double %x, 1.0 @@ -1057,10 +1036,7 @@ ; CHECK-LABEL: define i1 @not_ninf_fabs_select_nzero_or_pinf ; CHECK-SAME: (i1 [[COND:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float -0.000000e+00, float 0x7FF0000000000000 -; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]]) -; CHECK-NEXT: [[ONE:%.*]] = fcmp one float [[FABS]], 0xFFF0000000000000 -; CHECK-NEXT: ret i1 [[ONE]] +; CHECK-NEXT: ret i1 true ; entry: %select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000