[llvm] 89f0314 - Revert "InstSimplify: Use correct interested FP classes when simplifying fcmp"
Zequan Wu via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 1 11:54:34 PDT 2023
Author: Zequan Wu
Date: 2023-09-01T14:54:27-04:00
New Revision: 89f0314ee14a4d7f5a92fd63574ba545863df016
URL: https://github.com/llvm/llvm-project/commit/89f0314ee14a4d7f5a92fd63574ba545863df016
DIFF: https://github.com/llvm/llvm-project/commit/89f0314ee14a4d7f5a92fd63574ba545863df016.diff
LOG: Revert "InstSimplify: Use correct interested FP classes when simplifying fcmp"
Revert "InstSimplify: Add baseline tests for reported regression"
Revert "InstSimplify: Start cleaning up simplifyFCmpInst"
This reverts commit 0637b00041c7d6a191d51d9966c4f5f41fb97ab5.
This reverts commit 239fb206de35935416e652b89725d5f3193f78f5.
This reverts commit ddb3f12c428bc4bd5a98913d74dfd7f2402bdfd8.
These commits causes crashes when compiling chromium code, attached reduced ir at: https://reviews.llvm.org/D151887#4634914
Added:
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/Attributor/nofpclass.ll
llvm/test/Transforms/InstCombine/fcmp.ll
llvm/test/Transforms/InstCombine/is_fpclass.ll
llvm/test/Transforms/InstSimplify/floating-point-compare.ll
llvm/test/Transforms/InstSimplify/known-never-infinity.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 695f2fecae885b..3521fa8be3b691 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -18,7 +18,6 @@
#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 <cassert>
@@ -230,10 +229,6 @@ std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
const Function &F, Value *LHS,
Value *RHS,
bool LookThroughSrc = true);
-std::pair<Value *, FPClassTest> 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.
@@ -476,28 +471,6 @@ KnownFPClass computeKnownFPClass(
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.
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 040c2e55d87ced..600418a5b7debf 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4060,6 +4060,19 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
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<PoisonValue>(LHS) || isa<PoisonValue>(RHS))
@@ -4081,86 +4094,80 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return getFalse(RetTy);
}
- // 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);
- }
-
- const APFloat *C = nullptr;
- match(RHS, m_APFloatAllowUndef(C));
- std::optional<KnownFPClass> 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);
- };
+ // 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;
+ }
+ }
- 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)
+ // 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))
return getFalse(RetTy);
- if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone)
+ // LHS != Inf && LHS != NaN
+ if (Pred == FCmpInst::FCMP_ONE &&
+ isKnownNeverInfOrNaN(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
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 = KnownFPClass::OrderedLessThanZeroMask;
-
- // 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: {
- KnownFPClass KnownClass = computeLHSClass(Interested);
-
+ case FCmpInst::FCMP_UNE:
// (X >= 0) implies (X > C) when (C < 0)
- if (KnownClass.cannotBeOrderedLessThanZero())
+ if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0,
+ Q.AC, Q.CxtI, Q.DT))
return getTrue(RetTy);
break;
- }
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_OLT: {
- KnownFPClass KnownClass = computeLHSClass(Interested);
-
+ case FCmpInst::FCMP_OLT:
// (X >= 0) implies !(X < C) when (C < 0)
- if (KnownClass.cannotBeOrderedLessThanZero())
+ if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI,
+ Q.DT))
return getFalse(RetTy);
break;
- }
default:
break;
}
}
+
// Check comparison of [minnum/maxnum with constant] with other constant.
const APFloat *C2;
if ((match(LHS, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_APFloat(C2))) &&
@@ -4207,17 +4214,13 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
}
- // 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())) {
switch (Pred) {
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_ULT: {
- FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
- if (!FMF.noNaNs())
- Interested |= fcNan;
-
- KnownFPClass Known = computeLHSClass(Interested);
+ FPClassTest Interested = FMF.noNaNs() ? fcNegative : fcNegative | fcNan;
+ KnownFPClass Known = computeKnownFPClass(LHS, Q.DL, Interested, 0,
+ Q.TLI, Q.AC, Q.CxtI, Q.DT);
// Positive or zero X >= 0.0 --> true
// Positive or zero X < 0.0 --> false
@@ -4227,16 +4230,12 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
break;
}
case FCmpInst::FCMP_UGE:
- case FCmpInst::FCMP_OLT: {
- FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
- KnownFPClass Known = computeLHSClass(Interested);
-
+ case FCmpInst::FCMP_OLT:
// Positive or zero or nan X >= 0.0 --> true
// Positive or zero or nan X < 0.0 --> false
- if (Known.cannotBeOrderedLessThanZero())
+ if (cannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI, 0, Q.AC, Q.CxtI, Q.DT))
return Pred == FCmpInst::FCMP_UGE ? getTrue(RetTy) : getFalse(RetTy);
break;
- }
default:
break;
}
@@ -6817,9 +6816,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
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()) {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 801814e0c18a83..0c31dc22b871ef 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4007,15 +4007,9 @@ std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred,
Value *LHS, Value *RHS,
bool LookThroughSrc) {
const APFloat *ConstRHS;
- if (!match(RHS, m_APFloatAllowUndef(ConstRHS)))
+ if (!match(RHS, m_APFloat(ConstRHS)))
return {nullptr, fcNone};
- return fcmpToClassTest(Pred, F, LHS, ConstRHS, LookThroughSrc);
-}
-
-std::pair<Value *, FPClassTest>
-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};
diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index 051ae8b8fe3d5a..2690bba123a345 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -600,7 +600,8 @@ define half @assume_fcmp_fabs_with_other_fabs_assume_fallback(half %arg) {
; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]]
; CHECK-NEXT: [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR16]]
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]]
+; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
+; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR16]]
; 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]]
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 159c84d0dd8aa9..5c4380b14397dc 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -718,7 +718,9 @@ define i1 @is_signbit_clear_nonzero(double %x) {
define i1 @is_signbit_set_simplify_zero(double %x) {
; CHECK-LABEL: @is_signbit_set_simplify_zero(
-; CHECK-NEXT: ret i1 false
+; 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]]
;
%s = call double @llvm.copysign.f64(double 0.0, double %x)
%r = fcmp ogt double %s, 0.0
@@ -729,7 +731,9 @@ define i1 @is_signbit_set_simplify_zero(double %x) {
define i1 @is_signbit_set_simplify_nan(double %x) {
; CHECK-LABEL: @is_signbit_set_simplify_nan(
-; CHECK-NEXT: ret i1 false
+; 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]]
;
%s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
%r = fcmp ogt double %s, 0.0
diff --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll
index ad0bcd1b0c437c..2f399e7e23a637 100644
--- a/llvm/test/Transforms/InstCombine/is_fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll
@@ -2444,7 +2444,8 @@ define <2 x i1> @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan_
define i1 @test_class_is_zero_nozero_src(float nofpclass(zero) %arg) {
; CHECK-LABEL: @test_class_is_zero_nozero_src(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96)
ret i1 %class
@@ -2577,7 +2578,8 @@ define i1 @test_class_is_neginf_or_nopinf_src(float nofpclass(pinf) %arg) {
define i1 @test_class_is_neginf_noninf_src(float nofpclass(ninf) %arg) {
; CHECK-LABEL: @test_class_is_neginf_noninf_src(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0xFFF0000000000000
+; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4)
ret i1 %class
@@ -2602,7 +2604,8 @@ define i1 @test_class_is_posinf_noninf_src(float nofpclass(ninf) %arg) {
define i1 @test_class_is_posinf_nopinf_src(float nofpclass(pinf) %arg) {
; CHECK-LABEL: @test_class_is_posinf_nopinf_src(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0x7FF0000000000000
+; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512)
ret i1 %class
@@ -2730,7 +2733,8 @@ define i1 @test_class_is_nan_assume_uno(float %x) {
; 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: ret i1 true
+; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CLASS]]
;
%ord = fcmp uno float %x, 0.0
call void @llvm.assume(i1 %ord)
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
index 62dd37d9b74e62..a88057e4d4d93e 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -656,7 +656,8 @@ define i1 @assume_nan_ord(float %x) {
; 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: ret i1 false
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X]], 1.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
;
%uno = fcmp uno float %x, 0.0
call void @llvm.assume(i1 %uno)
@@ -680,7 +681,8 @@ define i1 @assume_nan_uno(float %x) {
; 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: ret i1 true
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X]], 1.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
;
%uno = fcmp uno float %x, 0.0
call void @llvm.assume(i1 %uno)
@@ -1523,7 +1525,10 @@ define i1 @fcmp_olt_0_assumed_oge_zero(float %x) {
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: ret i1 true
+; 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]]
;
entry:
%select = select i1 %cond, float -1.0, float 0x7FF0000000000000
@@ -1535,7 +1540,10 @@ entry:
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: ret i1 true
+; 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]]
;
entry:
%select = select i1 %cond, float 1.0, float 0xFFF0000000000000
@@ -1544,114 +1552,6 @@ entry:
ret i1 %one
}
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_ieee(float %arg, float %arg1) {
-; CHECK-LABEL: @fast_square_must_be_positive_ieee(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp olt float %i3, 0.000000e+00
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_ieee_nnan(float %arg, float %arg1) {
-; CHECK-LABEL: @fast_square_must_be_positive_ieee_nnan(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp nnan olt float %i3, 0.000000e+00
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_daz(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @fast_square_must_be_positive_daz(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp olt float %i3, 0.000000e+00
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
-; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
-define float @fast_square_must_be_positive_daz_nnan(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @fast_square_must_be_positive_daz_nnan(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp nnan olt float %i3, 0.000000e+00
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
-; Make the compare to negative constant is folded out
-define float @must_be_olt_negative_constant_daz(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @must_be_olt_negative_constant_daz(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp olt float %i3, -1.0
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
-; Make the compare to negative constant is folded out
-define float @must_be_olt_negative_constant_daz_nnan(float %arg, float %arg1) #0 {
-; CHECK-LABEL: @must_be_olt_negative_constant_daz_nnan(
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
-; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
-; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]]
-; CHECK-NEXT: ret float [[I3]]
-;
-bb:
- %i = fmul float %arg, %arg
- %i2 = fmul float %arg1, %arg1
- %i3 = fadd float %i2, %i
- %i4 = fcmp nnan olt float %i3, -1.0
- %i5 = select i1 %i4, float 0.000000e+00, float %i3
- ret float %i5
-}
-
declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)
@@ -1671,5 +1571,3 @@ declare double @llvm.sqrt.f64(double)
declare double @llvm.copysign.f64(double, double)
declare half @llvm.fabs.f16(half)
declare void @llvm.assume(i1 noundef)
-
-attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
index efa19aa0999a7a..a7b7e0b4b1fa6c 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
@@ -753,7 +753,11 @@ define i1 @isKnownNeverInfinity_cos(double %x) {
define i1 @isKnownNeverInfinity_log(double %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_log
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
%a = fadd ninf double %x.clamp.zero, 1.0
@@ -765,7 +769,10 @@ define i1 @isKnownNeverInfinity_log(double %x) {
define i1 @isNotKnownNeverInfinity_log_maybe_negative(double %x) {
; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log_maybe_negative
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.not.inf = fadd ninf double %x, 1.0
@@ -805,7 +812,11 @@ define i1 @isKnownNeverNegInfinity_log_maybe_0(double %x) {
define i1 @isKnownNeverInfinity_log10(double %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_log10
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
%a = fadd ninf double %x.clamp.zero, 1.0
@@ -817,7 +828,10 @@ define i1 @isKnownNeverInfinity_log10(double %x) {
define i1 @isNotKnownNeverInfinity_log10_maybe_negative(double %x) {
; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log10_maybe_negative
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.not.inf = fadd ninf double %x, 1.0
@@ -857,7 +871,11 @@ define i1 @isKnownNeverNegInfinity_log10_maybe_0(double %x) {
define i1 @isKnownNeverInfinity_log2(double %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_log2
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.clamp.zero = call double @llvm.maxnum.f64(double %x, double 0.0)
%a = fadd ninf double %x.clamp.zero, 1.0
@@ -869,7 +887,10 @@ define i1 @isKnownNeverInfinity_log2(double %x) {
define i1 @isNotKnownNeverInfinity_log2_maybe_negative(double %x) {
; CHECK-LABEL: define i1 @isNotKnownNeverInfinity_log2_maybe_negative
; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT: ret i1 true
+; 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]]
;
%x.not.inf = fadd ninf double %x, 1.0
@@ -1036,7 +1057,10 @@ define i1 @not_ninf_fabs_select_nzero_or_pinf(i1 %cond) {
; CHECK-LABEL: define i1 @not_ninf_fabs_select_nzero_or_pinf
; CHECK-SAME: (i1 [[COND:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i1 true
+; 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]]
;
entry:
%select = select i1 %cond, float -0.000000e+00, float 0x7FF0000000000000
More information about the llvm-commits
mailing list