ValueTracking: Recognize fcmp ole/ugt with inf as a class test (#79095)

These were missed and hopefully avoids assertions when
dc3faf0ed0 is recommitted.
This commit is contained in:
Matt Arsenault 2024-01-23 20:20:40 +07:00 committed by GitHub
parent d2398cca6f
commit 55f12299d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 24 deletions

View File

@ -4065,7 +4065,7 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
case FCmpInst::FCMP_ULE: // isnan(x) || x <= 0
return {LHS, fcNegative | fcPosZero | fcNan};
default:
break;
llvm_unreachable("all compare types are handled");
}
return {nullptr, fcAllFlags};
@ -4184,8 +4184,22 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
Mask = fcNone;
break;
}
case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_UGT: {
if (ConstRHS->isNegative()) {
Mask = IsFabs ? fcNone : fcNegInf;
break;
}
// fcmp ole x, +inf -> fcmp ord x, x
// fcmp ole fabs(x), +inf -> fcmp ord x, x
// fcmp ole x, -inf -> fcmp oeq x, -inf
// fcmp ole fabs(x), -inf -> false
Mask = ~fcNan;
break;
}
default:
return {nullptr, fcAllFlags};
llvm_unreachable("all compare types are handled");
}
} else if (ConstRHS->isSmallestNormalized() && !ConstRHS->isNegative()) {
// Match pattern that's used in __builtin_isnormal.

View File

@ -2400,8 +2400,8 @@ define float @assume_oeq_smallest_normal_known_pos(float nofpclass(ninf nsub nno
;---------------------------------------------------------------------
define float @assume_ole_pinf(float %arg) {
; CHECK-LABEL: define float @assume_ole_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(nan) float @assume_ole_pinf(
; CHECK-SAME: float returned nofpclass(nan) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ole float [[ARG]], 0x7FF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
@ -2412,8 +2412,8 @@ define float @assume_ole_pinf(float %arg) {
}
define float @assume_ole_ninf(float %arg) {
; CHECK-LABEL: define float @assume_ole_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float @assume_ole_ninf(
; CHECK-SAME: float returned nofpclass(nan pinf zero sub norm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ole float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
@ -2424,8 +2424,8 @@ define float @assume_ole_ninf(float %arg) {
}
define float @assume_ugt_pinf(float %arg) {
; CHECK-LABEL: define float @assume_ugt_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @assume_ugt_pinf(
; CHECK-SAME: float returned nofpclass(inf zero sub norm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ugt float [[ARG]], 0x7FF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
@ -2436,8 +2436,8 @@ define float @assume_ugt_pinf(float %arg) {
}
define float @assume_ugt_ninf(float %arg) {
; CHECK-LABEL: define float @assume_ugt_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(ninf) float @assume_ugt_ninf(
; CHECK-SAME: float returned nofpclass(ninf) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ugt float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
@ -2448,8 +2448,8 @@ define float @assume_ugt_ninf(float %arg) {
}
define float @assume_fabs_ole_pinf(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @assume_fabs_ole_pinf(
; CHECK-SAME: float returned nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @assume_fabs_ole_pinf(
; CHECK-SAME: float returned nofpclass(nan ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ole float [[FABS]], 0x7FF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
@ -2462,8 +2462,8 @@ define float @assume_fabs_ole_pinf(float %arg) {
}
define float @assume_fabs_ole_ninf(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @assume_fabs_ole_ninf(
; CHECK-SAME: float returned nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(all) float @assume_fabs_ole_ninf(
; CHECK-SAME: float returned nofpclass(all) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
@ -2474,8 +2474,8 @@ define float @assume_fabs_ole_ninf(float %arg) {
}
define float @assume_fabs_ugt_pinf(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @assume_fabs_ugt_pinf(
; CHECK-SAME: float returned nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @assume_fabs_ugt_pinf(
; CHECK-SAME: float returned nofpclass(inf zero sub norm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[FCMP:%.*]] = fcmp ugt float [[FABS]], 0x7FF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]

View File

@ -4820,10 +4820,7 @@ define i1 @clang_builtin_isnormal_inf_check_olt(half %x) {
define i1 @clang_builtin_isnormal_inf_check_ole(half %x) {
; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ole(
; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
; CHECK-NEXT: [[CMP:%.*]] = fcmp ole half [[FABS_X]], 0xH7C00
; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
; CHECK-NEXT: [[AND:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs.x = call half @llvm.fabs.f16(half %x)

View File

@ -1945,14 +1945,14 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_PInf) {
auto [OleVal, OleClass] =
fcmpToClassTest(CmpInst::FCMP_OLE, *A3->getFunction(), A3->getOperand(0),
A3->getOperand(1));
EXPECT_EQ(nullptr, OleVal);
EXPECT_EQ(fcAllFlags, OleClass);
EXPECT_EQ(A->getOperand(0), OleVal);
EXPECT_EQ(~fcNan, OleClass);
auto [UgtVal, UgtClass] =
fcmpToClassTest(CmpInst::FCMP_UGT, *A4->getFunction(), A4->getOperand(0),
A4->getOperand(1));
EXPECT_EQ(nullptr, UgtVal);
EXPECT_EQ(fcAllFlags, UgtClass);
EXPECT_EQ(A4->getOperand(0), UgtVal);
EXPECT_EQ(fcNan, UgtClass);
}
TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) {