[llvm-branch-commits] [llvm] DAG: Lower single infinity is.fpclass tests to fcmp (PR #100380)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jul 26 11:48:24 PDT 2024
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/100380
>From 6226f310c474650b267a41d2509df5d0396ac481 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 1 Feb 2023 09:52:34 -0400
Subject: [PATCH] DAG: Lower single infinity is.fpclass tests to fcmp
InstCombine also should have taken care of this, but this
should be helpful when the fcmp based lowering strategy tries
to combine multiple tests.
---
llvm/lib/CodeGen/CodeGenCommonISel.cpp | 2 +
.../CodeGen/SelectionDAG/TargetLowering.cpp | 25 +++-
llvm/test/CodeGen/AArch64/isinf.ll | 22 ++-
llvm/test/CodeGen/X86/is_fpclass-fp80.ll | 52 +++----
llvm/test/CodeGen/X86/is_fpclass.ll | 137 +++++++++---------
5 files changed, 127 insertions(+), 111 deletions(-)
diff --git a/llvm/lib/CodeGen/CodeGenCommonISel.cpp b/llvm/lib/CodeGen/CodeGenCommonISel.cpp
index 88c643c568027..942cf442e9098 100644
--- a/llvm/lib/CodeGen/CodeGenCommonISel.cpp
+++ b/llvm/lib/CodeGen/CodeGenCommonISel.cpp
@@ -202,6 +202,8 @@ FPClassTest llvm::invertFPClassTestIfSimpler(FPClassTest Test, bool UseFCmp) {
case fcSubnormal | fcZero | fcNan:
return InvertedTest;
case fcInf | fcNan:
+ case fcPosInf | fcNan:
+ case fcNegInf | fcNan:
// If we're trying to use fcmp, we can take advantage of the nan check
// behavior of the compare (but this is more instructions in the integer
// expansion).
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 1e12d7937ba79..18cd368e24259 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8628,18 +8628,29 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
return DAG.getSetCC(DL, ResultVT, Op, Op,
IsInvertedFP ? ISD::SETO : ISD::SETUO);
- bool IsOrderedInf = FPTestMask == fcInf;
- if ((FPTestMask == fcInf || FPTestMask == (fcInf | fcNan)) &&
- isCondCodeLegalOrCustom(IsOrderedInf ? OrderedCmpOpcode
- : UnorderedCmpOpcode,
- OperandVT.getScalarType().getSimpleVT()) &&
- isOperationLegalOrCustom(ISD::FABS, OperandVT.getScalarType())) {
+ if (OrderedFPTestMask == fcInf &&
+ isCondCodeLegalOrCustom(IsOrdered ? OrderedCmpOpcode
+ : UnorderedCmpOpcode,
+ OperandVT.getScalarType().getSimpleVT())) {
// isinf(x) --> fabs(x) == inf
SDValue Abs = DAG.getNode(ISD::FABS, DL, OperandVT, Op);
SDValue Inf =
DAG.getConstantFP(APFloat::getInf(Semantics), DL, OperandVT);
return DAG.getSetCC(DL, ResultVT, Abs, Inf,
- IsOrderedInf ? OrderedCmpOpcode : UnorderedCmpOpcode);
+ IsOrdered ? OrderedCmpOpcode : UnorderedCmpOpcode);
+ }
+
+ if (OrderedFPTestMask == fcPosInf || OrderedFPTestMask == fcNegInf) {
+ // isposinf(x) --> x == inf
+ // isneginf(x) --> x == -inf
+ // isposinf(x) || nan --> x u== inf
+ // isneginf(x) || nan --> x u== -inf
+
+ SDValue Inf = DAG.getConstantFP(
+ APFloat::getInf(Semantics, OrderedFPTestMask == fcNegInf), DL,
+ OperandVT);
+ return DAG.getSetCC(DL, ResultVT, Op, Inf,
+ IsOrdered ? OrderedCmpOpcode : UnorderedCmpOpcode);
}
if (OrderedFPTestMask == (fcSubnormal | fcZero) && !IsOrdered) {
diff --git a/llvm/test/CodeGen/AArch64/isinf.ll b/llvm/test/CodeGen/AArch64/isinf.ll
index 834417b98743a..458bd7eeba16c 100644
--- a/llvm/test/CodeGen/AArch64/isinf.ll
+++ b/llvm/test/CodeGen/AArch64/isinf.ll
@@ -58,14 +58,22 @@ define i32 @replace_isinf_call_f64(double %x) {
define i32 @replace_isinf_call_f128(fp128 %x) {
; CHECK-LABEL: replace_isinf_call_f128:
; CHECK: // %bb.0:
-; CHECK-NEXT: str q0, [sp, #-16]!
-; CHECK-NEXT: .cfi_def_cfa_offset 16
-; CHECK-NEXT: ldp x9, x8, [sp], #16
-; CHECK-NEXT: and x8, x8, #0x7fffffffffffffff
-; CHECK-NEXT: eor x8, x8, #0x7fff000000000000
-; CHECK-NEXT: orr x8, x9, x8
-; CHECK-NEXT: cmp x8, #0
+; CHECK-NEXT: sub sp, sp, #32
+; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: .cfi_offset w30, -16
+; CHECK-NEXT: str q0, [sp]
+; CHECK-NEXT: ldrb w8, [sp, #15]
+; CHECK-NEXT: and w8, w8, #0x7f
+; CHECK-NEXT: strb w8, [sp, #15]
+; CHECK-NEXT: adrp x8, .LCPI3_0
+; CHECK-NEXT: ldr q0, [sp]
+; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI3_0]
+; CHECK-NEXT: bl __eqtf2
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-NEXT: cset w0, eq
+; CHECK-NEXT: add sp, sp, #32
; CHECK-NEXT: ret
%abs = tail call fp128 @llvm.fabs.f128(fp128 %x)
%cmpinf = fcmp oeq fp128 %abs, 0xL00000000000000007FFF000000000000
diff --git a/llvm/test/CodeGen/X86/is_fpclass-fp80.ll b/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
index cc162c2d43d67..8c1405ff7106b 100644
--- a/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
+++ b/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
@@ -265,23 +265,24 @@ entry:
define i1 @is_posinf_f80(x86_fp80 %x) nounwind {
; X86-LABEL: is_posinf_f80:
; X86: # %bb.0: # %entry
-; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: xorl $32767, %eax # imm = 0x7FFF
-; X86-NEXT: orl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: orl %ecx, %eax
-; X86-NEXT: sete %al
+; X86-NEXT: fldt {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fxch %st(1)
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setae %al
; X86-NEXT: retl
;
; X64-LABEL: is_posinf_f80:
; X64: # %bb.0: # %entry
-; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
-; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx
-; X64-NEXT: xorq $32767, %rax # imm = 0x7FFF
-; X64-NEXT: orq %rcx, %rax
-; X64-NEXT: sete %al
+; X64-NEXT: fldt {{[0-9]+}}(%rsp)
+; X64-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
+; X64-NEXT: fxch %st(1)
+; X64-NEXT: fucompi %st(1), %st
+; X64-NEXT: fstp %st(0)
+; X64-NEXT: setae %al
; X64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 512) ; 0x200 = "+inf"
@@ -291,23 +292,22 @@ entry:
define i1 @is_neginf_f80(x86_fp80 %x) nounwind {
; X86-LABEL: is_neginf_f80:
; X86: # %bb.0: # %entry
-; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: xorl $65535, %eax # imm = 0xFFFF
-; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: orl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: orl %ecx, %eax
-; X86-NEXT: sete %al
+; X86-NEXT: fldt {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setae %al
; X86-NEXT: retl
;
; X64-LABEL: is_neginf_f80:
; X64: # %bb.0: # %entry
-; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
-; X64-NEXT: xorq $65535, %rax # imm = 0xFFFF
-; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx
-; X64-NEXT: orq %rax, %rcx
-; X64-NEXT: sete %al
+; X64-NEXT: fldt {{[0-9]+}}(%rsp)
+; X64-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
+; X64-NEXT: fucompi %st(1), %st
+; X64-NEXT: fstp %st(0)
+; X64-NEXT: setae %al
; X64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 4) ; "-inf"
diff --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll
index 9636c35a8a69f..0322b22fec7f4 100644
--- a/llvm/test/CodeGen/X86/is_fpclass.ll
+++ b/llvm/test/CodeGen/X86/is_fpclass.ll
@@ -186,15 +186,20 @@ entry:
define i1 @is_plus_inf_f(float %x) {
; X86-LABEL: is_plus_inf_f:
; X86: # %bb.0: # %entry
-; X86-NEXT: cmpl $2139095040, {{[0-9]+}}(%esp) # imm = 0x7F800000
-; X86-NEXT: sete %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fxch %st(1)
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setae %al
; X86-NEXT: retl
;
; X64-LABEL: is_plus_inf_f:
; X64: # %bb.0: # %entry
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X64-NEXT: sete %al
+; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: setae %al
; X64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 512) ; 0x200 = "+inf"
@@ -204,15 +209,20 @@ entry:
define i1 @is_minus_inf_f(float %x) {
; X86-LABEL: is_minus_inf_f:
; X86: # %bb.0: # %entry
-; X86-NEXT: cmpl $-8388608, {{[0-9]+}}(%esp) # imm = 0xFF800000
-; X86-NEXT: sete %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setae %al
; X86-NEXT: retl
;
; X64-LABEL: is_minus_inf_f:
; X64: # %bb.0: # %entry
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X64-NEXT: sete %al
+; X64-NEXT: movss {{.*#+}} xmm1 = [-Inf,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT: ucomiss %xmm0, %xmm1
+; X64-NEXT: setae %al
; X64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; "-inf"
@@ -222,15 +232,20 @@ entry:
define i1 @not_is_minus_inf_f(float %x) {
; X86-LABEL: not_is_minus_inf_f:
; X86: # %bb.0: # %entry
-; X86-NEXT: cmpl $-8388608, {{[0-9]+}}(%esp) # imm = 0xFF800000
-; X86-NEXT: setne %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setb %al
; X86-NEXT: retl
;
; X64-LABEL: not_is_minus_inf_f:
; X64: # %bb.0: # %entry
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X64-NEXT: setne %al
+; X64-NEXT: movss {{.*#+}} xmm1 = [-Inf,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT: ucomiss %xmm0, %xmm1
+; X64-NEXT: setb %al
; X64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1019) ; ~"-inf"
@@ -2116,24 +2131,19 @@ entry:
define i1 @is_plus_inf_or_nan_f(float %x) {
; X86-LABEL: is_plus_inf_or_nan_f:
; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X86-NEXT: sete %cl
-; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X86-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
-; X86-NEXT: setge %al
-; X86-NEXT: orb %cl, %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: sete %al
; X86-NEXT: retl
;
; X64-LABEL: is_plus_inf_or_nan_f:
; X64: # %bb.0:
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X64-NEXT: sete %cl
-; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X64-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
-; X64-NEXT: setge %al
-; X64-NEXT: orb %cl, %al
+; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: sete %al
; X64-NEXT: retq
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 515) ; 0x200|0x3 = "+inf|nan"
ret i1 %class
@@ -2142,24 +2152,19 @@ define i1 @is_plus_inf_or_nan_f(float %x) {
define i1 @is_minus_inf_or_nan_f(float %x) {
; X86-LABEL: is_minus_inf_or_nan_f:
; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X86-NEXT: sete %cl
-; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X86-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
-; X86-NEXT: setge %al
-; X86-NEXT: orb %cl, %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: sete %al
; X86-NEXT: retl
;
; X64-LABEL: is_minus_inf_or_nan_f:
; X64: # %bb.0:
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X64-NEXT: sete %cl
-; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X64-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
-; X64-NEXT: setge %al
-; X64-NEXT: orb %cl, %al
+; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: sete %al
; X64-NEXT: retq
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 7) ; "-inf|nan"
ret i1 %class
@@ -2168,24 +2173,19 @@ define i1 @is_minus_inf_or_nan_f(float %x) {
define i1 @not_is_plus_inf_or_nan_f(float %x) {
; X86-LABEL: not_is_plus_inf_or_nan_f:
; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X86-NEXT: sete %cl
-; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X86-NEXT: setl %al
-; X86-NEXT: orb %cl, %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setne %al
; X86-NEXT: retl
;
; X64-LABEL: not_is_plus_inf_or_nan_f:
; X64: # %bb.0:
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
-; X64-NEXT: sete %cl
-; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X64-NEXT: setl %al
-; X64-NEXT: orb %cl, %al
+; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: setne %al
; X64-NEXT: retq
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)"
ret i1 %class
@@ -2194,24 +2194,19 @@ define i1 @not_is_plus_inf_or_nan_f(float %x) {
define i1 @not_is_minus_inf_or_nan_f(float %x) {
; X86-LABEL: not_is_minus_inf_or_nan_f:
; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X86-NEXT: sete %cl
-; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X86-NEXT: setl %al
-; X86-NEXT: orb %cl, %al
+; X86-NEXT: flds {{[0-9]+}}(%esp)
+; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT: fucompp
+; X86-NEXT: fnstsw %ax
+; X86-NEXT: # kill: def $ah killed $ah killed $ax
+; X86-NEXT: sahf
+; X86-NEXT: setne %al
; X86-NEXT: retl
;
; X64-LABEL: not_is_minus_inf_or_nan_f:
; X64: # %bb.0:
-; X64-NEXT: movd %xmm0, %eax
-; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X64-NEXT: sete %cl
-; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
-; X64-NEXT: setl %al
-; X64-NEXT: orb %cl, %al
+; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: setne %al
; X64-NEXT: retq
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1016) ; "~(-inf|nan)"
ret i1 %class
More information about the llvm-branch-commits
mailing list