-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Revert "InstCombine: Fold is.fpclass(x, fcInf) to fabs+fcmp" #76338
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
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesThis reverts commit 2b58244. I found that this patch caused regressions when I tried to canonicalize the idiom See also D159084. (This link seems broken) Patch is 23.12 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76338.diff 5 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 3b7fe7fa226607..54d9886c5681b9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -931,24 +931,6 @@ Instruction *InstCombinerImpl::foldIntrinsicIsFPClass(IntrinsicInst &II) {
return replaceOperand(II, 0, FAbsSrc);
}
- if ((OrderedMask == fcInf || OrderedInvertedMask == fcInf) &&
- (IsOrdered || IsUnordered) && !IsStrict) {
- // is.fpclass(x, fcInf) -> fcmp oeq fabs(x), +inf
- // is.fpclass(x, ~fcInf) -> fcmp one fabs(x), +inf
- // is.fpclass(x, fcInf|fcNan) -> fcmp ueq fabs(x), +inf
- // is.fpclass(x, ~(fcInf|fcNan)) -> fcmp une fabs(x), +inf
- Constant *Inf = ConstantFP::getInfinity(Src0->getType());
- FCmpInst::Predicate Pred =
- IsUnordered ? FCmpInst::FCMP_UEQ : FCmpInst::FCMP_OEQ;
- if (OrderedInvertedMask == fcInf)
- Pred = IsUnordered ? FCmpInst::FCMP_UNE : FCmpInst::FCMP_ONE;
-
- Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Src0);
- Value *CmpInf = Builder.CreateFCmp(Pred, Fabs, Inf);
- CmpInf->takeName(&II);
- return replaceInstUsesWith(II, CmpInf);
- }
-
if ((OrderedMask == fcPosInf || OrderedMask == fcNegInf) &&
(IsOrdered || IsUnordered) && !IsStrict) {
// is.fpclass(x, fcPosInf) -> fcmp oeq x, +inf
diff --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index 90d34171385c45..bffa4c2ae0fbd0 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -4794,8 +4794,7 @@ define i1 @clang_builtin_isnormal_inf_check_ord(half %x) {
define i1 @clang_builtin_isnormal_inf_check_oge(half %x) {
; CHECK-LABEL: @clang_builtin_isnormal_inf_check_oge(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs.x = call half @llvm.fabs.f16(half %x)
@@ -4807,8 +4806,7 @@ define i1 @clang_builtin_isnormal_inf_check_oge(half %x) {
define i1 @clang_builtin_isnormal_inf_check_olt(half %x) {
; CHECK-LABEL: @clang_builtin_isnormal_inf_check_olt(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp one half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 504)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs.x = call half @llvm.fabs.f16(half %x)
@@ -4835,8 +4833,7 @@ define i1 @clang_builtin_isnormal_inf_check_ole(half %x) {
define i1 @clang_builtin_isnormal_inf_check_oeq(half %x) {
; CHECK-LABEL: @clang_builtin_isnormal_inf_check_oeq(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs.x = call half @llvm.fabs.f16(half %x)
diff --git a/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
index ed8bfd5d669d9e..66ee31f57f961b 100644
--- a/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
@@ -135,8 +135,7 @@ define i1 @fcmp_isfinite_and_class_subnormal(half %x) {
define i1 @fcmp_isfinite_or_class_subnormal(half %x) {
; CHECK-LABEL: @fcmp_isfinite_or_class_subnormal(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = fcmp one half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 504)
; CHECK-NEXT: ret i1 [[SUBNORMAL_CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -149,9 +148,8 @@ define i1 @fcmp_isfinite_or_class_subnormal(half %x) {
; -> isfinite
define i1 @fcmp_issubnormal_or_class_finite(half %x) {
; CHECK-LABEL: @fcmp_issubnormal_or_class_finite(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 504)
+; CHECK-NEXT: ret i1 [[IS_FINITE_CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
%is.subnormal = fcmp olt half %fabs, 0xH0400
@@ -163,9 +161,8 @@ define i1 @fcmp_issubnormal_or_class_finite(half %x) {
; -> isfinite
define i1 @class_finite_or_fcmp_issubnormal(half %x) {
; CHECK-LABEL: @class_finite_or_fcmp_issubnormal(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 504)
+; CHECK-NEXT: ret i1 [[IS_FINITE_CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
%is.subnormal = fcmp olt half %fabs, 0xH0400
@@ -177,8 +174,8 @@ define i1 @class_finite_or_fcmp_issubnormal(half %x) {
; -> issubnormal
define i1 @fcmp_issubnormal_and_class_finite(half %x) {
; CHECK-LABEL: @fcmp_issubnormal_and_class_finite(
-; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
-; CHECK-NEXT: ret i1 [[AND]]
+; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
+; CHECK-NEXT: ret i1 [[IS_FINITE_CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
%is.subnormal = fcmp olt half %fabs, 0xH0400
@@ -189,8 +186,8 @@ define i1 @fcmp_issubnormal_and_class_finite(half %x) {
define i1 @class_inf_or_fcmp_issubnormal(half %x) {
; CHECK-LABEL: @class_inf_or_fcmp_issubnormal(
-; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[IS_INF_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
+; CHECK-NEXT: ret i1 [[IS_INF_CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
%is.subnormal = fcmp olt half %fabs, 0xH0400
@@ -202,9 +199,8 @@ define i1 @class_inf_or_fcmp_issubnormal(half %x) {
; -> isfinite
define <2 x i1> @class_finite_or_fcmp_issubnormal_vector(<2 x half> %x) {
; CHECK-LABEL: @class_finite_or_fcmp_issubnormal_vector(
-; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp one <2 x half> [[TMP1]], <half 0xH7C00, half 0xH7C00>
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 504)
+; CHECK-NEXT: ret <2 x i1> [[IS_FINITE_CLASS]]
;
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
%is.subnormal = fcmp olt <2 x half> %fabs, <half 0xH0400, half 0xH0400>
diff --git a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
index ea056de3f8ee71..8a51396ef577e9 100644
--- a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
@@ -250,8 +250,7 @@ define i1 @olt_0_or_fabs_ueq_inf(half %x) {
; Negative test
define i1 @oeq_0_or_fabs_ult_inf(half %x) {
; CHECK-LABEL: @oeq_0_or_fabs_ult_inf(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 507)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -624,8 +623,7 @@ define i1 @fneg_fabs_olt_neg_smallest_normal_or_inf(half %x) {
define i1 @issubnormal_or_finite_olt(half %x) {
; CHECK-LABEL: @issubnormal_or_finite_olt(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 504)
; CHECK-NEXT: ret i1 [[OR]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -726,8 +724,7 @@ define i1 @is_finite_or_ord(half %x) {
define i1 @is_finite_or_uno(half %x) {
; CHECK-LABEL: @is_finite_or_uno(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 519)
; CHECK-NEXT: ret i1 [[OR]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -739,8 +736,7 @@ define i1 @is_finite_or_uno(half %x) {
define i1 @oeq_isinf_or_uno(half %x) {
; CHECK-LABEL: @oeq_isinf_or_uno(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 519)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -775,8 +771,7 @@ define i1 @oeq_isinf_and_uno(half %x) {
define i1 @oeq_isinf_and_ord(half %x) {
; CHECK-LABEL: @oeq_isinf_and_ord(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -907,8 +902,7 @@ define i1 @isnormalinf_or_posinf(half %x) #0 {
; -> pinf|ninf
define i1 @isnormalinf_and_inf(half %x) #0 {
; CHECK-LABEL: @isnormalinf_and_inf(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -976,8 +970,7 @@ define i1 @not_isnormalinf_and_ord(half %x) #0 {
; -> ~ninf
define i1 @not_isnormalinf_or_inf(half %x) #0 {
; CHECK-LABEL: @not_isnormalinf_or_inf(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 507)
; CHECK-NEXT: ret i1 [[OR]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -1294,8 +1287,7 @@ define i1 @olt_smallest_normal_and_une_inf_or_one_smallest_normal(half %x) #0 {
define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 {
; CHECK-LABEL: @oge_fabs_eq_inf_and_ord(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[AND]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -1318,8 +1310,7 @@ define i1 @oge_eq_inf_and_ord(half %x) #0 {
define i1 @oge_fabs_eq_inf_or_uno(half %x) #0 {
; CHECK-LABEL: @oge_fabs_eq_inf_or_uno(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 519)
; CHECK-NEXT: ret i1 [[OR]]
;
%fabs = call half @llvm.fabs.f16(half %x)
@@ -1366,8 +1357,7 @@ define i1 @ult_eq_inf_and_ord(half %x) #0 {
define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 {
; CHECK-LABEL: @ult_fabs_eq_inf_or_uno(
-; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
-; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
+; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 507)
; CHECK-NEXT: ret i1 [[OR]]
;
%fabs = call half @llvm.fabs.f16(half %x)
diff --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll
index ad0bcd1b0c437c..7cc357cc1ef9e7 100644
--- a/llvm/test/Transforms/InstCombine/is_fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll
@@ -107,7 +107,7 @@ define <2 x i1> @test_class_isnan_v2f32(<2 x float> %x) {
define i1 @test_class_isnan_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_isnan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 3) strictfp
@@ -333,7 +333,7 @@ define <2 x i1> @test_class_is_not_p0_n0_v2f32(<2 x float> %x) {
define i1 @test_class_is_not_p0_n0_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_not_p0_n0_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 927) strictfp ; ~fcZero & fcAllFlags
@@ -387,7 +387,7 @@ define i1 @test_class_is_not_p0_n0_psub_nsub_f32_dynamic(float %x) "denormal-fp-
define i1 @test_class_is_p0_n0_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_p0_n0_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 96) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 96) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 96) strictfp
@@ -540,8 +540,7 @@ define <2 x i1> @test_class_is_ninf_v2f32(<2 x float> %x) {
define i1 @test_class_is_inf_f32(float %x) {
; CHECK-LABEL: @test_class_is_inf_f32(
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
-; CHECK-NEXT: [[VAL:%.*]] = fcmp oeq float [[TMP1]], 0x7FF0000000000000
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; fcInf
@@ -550,8 +549,7 @@ define i1 @test_class_is_inf_f32(float %x) {
define <2 x i1> @test_class_is_inf_v2f32(<2 x float> %x) {
; CHECK-LABEL: @test_class_is_inf_v2f32(
-; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
-; CHECK-NEXT: [[VAL:%.*]] = fcmp oeq <2 x float> [[TMP1]], <float 0x7FF0000000000000, float 0x7FF0000000000000>
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 516)
; CHECK-NEXT: ret <2 x i1> [[VAL]]
;
%val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 516) ; fcInf
@@ -560,8 +558,7 @@ define <2 x i1> @test_class_is_inf_v2f32(<2 x float> %x) {
define i1 @test_class_is_inf_or_nan_f32(float %x) {
; CHECK-LABEL: @test_class_is_inf_or_nan_f32(
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
-; CHECK-NEXT: [[VAL:%.*]] = fcmp ueq float [[TMP1]], 0x7FF0000000000000
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519)
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; fcInf|fcNan
@@ -570,7 +567,7 @@ define i1 @test_class_is_inf_or_nan_f32(float %x) {
define i1 @test_class_is_pinf_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_pinf_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 512) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 512) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 512) strictfp ; fcPosInf
@@ -579,7 +576,7 @@ define i1 @test_class_is_pinf_f32_strict(float %x) strictfp {
define i1 @test_class_is_ninf_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_ninf_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 4) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 4) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 4) strictfp ; fcNegInf
@@ -588,7 +585,7 @@ define i1 @test_class_is_ninf_f32_strict(float %x) strictfp {
define i1 @test_class_is_inf_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_inf_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 516) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 516) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 516) strictfp ; fcInf
@@ -597,7 +594,7 @@ define i1 @test_class_is_inf_f32_strict(float %x) strictfp {
define i1 @test_class_is_pinf_or_nan_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_pinf_or_nan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 515) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 515) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 515) strictfp ; fcPosInf|fcNan
@@ -606,7 +603,7 @@ define i1 @test_class_is_pinf_or_nan_f32_strict(float %x) strictfp {
define i1 @test_class_is_ninf_or_nan_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_ninf_or_nan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 7) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 7) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 7) strictfp ; fcNegInf|fcNan
@@ -615,7 +612,7 @@ define i1 @test_class_is_ninf_or_nan_f32_strict(float %x) strictfp {
define i1 @test_class_is_inf_or_nan_f32_strict(float %x) strictfp {
; CHECK-LABEL: @test_class_is_inf_or_nan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519) #[[ATTR0]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 519) strictfp ; fcInf|fcNan
@@ -952,8 +949,7 @@ define i1 @test_class_not_is_nan_multi_use(float %x, ptr %ptr) {
define i1 @test_class_not_is_inf_nan(float %x) {
; CHECK-LABEL: @test_class_not_is_inf_nan(
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
-; CHECK-NEXT: [[CLASS:%.*]] = fcmp one float [[TMP1]], 0x7FF0000000000000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 504)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 519)
@@ -1743,7 +1739,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan(float %arg)
; -> ninf|pnormal|negsubnormal|pzero|snan
define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(
-; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341) #[[ATTR0]]
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fneg = fneg float %arg
@@ -1897,8 +1893,7 @@ define i1 @test_class_fabs_posnormal(float %arg) {
; -> posinf
define i1 @test_class_fabs_posinf(float %arg) {
; CHECK-LABEL: @test_class_fabs_posinf(
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[TMP1]], 0x7FF0000000000000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 516)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fabs = call float @llvm.fabs.f32(float %arg)
@@ -2075,7 +2070,7 @@ define i1 @test_class_fabs_posinf_negnormal_possubnormal_negzero_nan(float %arg)
; -> pinf|psubnormal|snan
define i1 @test_class_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
; CHECK-LABEL: @test_class_fabs_posinf_negnorma...
[truncated]
|
This reverts commit 2b58244.
02436da
to
a646e87
Compare
I still think fabs+fcmp is a better canonical form. Between some targets offering free fabs, and other combines between fabs and sources/sinks, I think it's better to split out this way. Any codegen regression should be addressed in the backend. |
@dtcxzyw are you planning on a codegen patch to improve the backend handling? |
I will post a patch this week. |
…1572) In commit 2b58244, we canonicalize the isInf/isNanOrInf idiom into fabs+fcmp for better analysis/codegen (See also the discussion in #76338). This patch reverses the fabs+fcmp to `is.fpclass`. If the `is.fpclass` is not supported by the target, it will be expanded by TLI. Fixes the regression introduced by 2b58244 and #80414 (comment).
This reverts commit 2b58244.
I found that this patch caused regressions when I tried to canonicalize the idiom
icmp eq (and (bitcast X to int), ExponentMask), ExponentMask
intois.fpclass(X, fcNan | fcInf)
.In general,
is.fpclass
is better thanfabs+fcmp
for the backend.Godbolt: https://godbolt.org/z/TvKoYPfTx
See also D159084. (This link seems broken)