https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/100380
InstCombine also should have taken care of this, but this should be helpful when the fcmp based lowering strategy tries to combine multiple tests. >From c27e0441cacf32077d0c101304a0b0b3d336058c Mon Sep 17 00:00:00 2001 From: Matt Arsenault <matthew.arsena...@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 | 35 ++++- llvm/test/CodeGen/X86/is_fpclass-fp80.ll | 52 +++---- llvm/test/CodeGen/X86/is_fpclass.ll | 137 +++++++++--------- 4 files changed, 122 insertions(+), 104 deletions(-) diff --git a/llvm/lib/CodeGen/CodeGenCommonISel.cpp b/llvm/lib/CodeGen/CodeGenCommonISel.cpp index f5207d8b9d124..bb09b0d1140fc 100644 --- a/llvm/lib/CodeGen/CodeGenCommonISel.cpp +++ b/llvm/lib/CodeGen/CodeGenCommonISel.cpp @@ -202,6 +202,8 @@ FPClassTest llvm::invertFPClassTestIfSimpler(FPClassTest Test, bool UseFP) { 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 ba7c89a33f604..0036c182ab9db 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -8599,6 +8599,16 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op, ISD::CondCode OrderedCmpOpcode = IsInvertedFP ? ISD::SETUNE : ISD::SETOEQ; ISD::CondCode UnorderedCmpOpcode = IsInvertedFP ? ISD::SETONE : ISD::SETUEQ; + // See if we can fold an | fcNan into an unordered compare. + FPClassTest OrderedFPTestMask = FPTestMask & ~fcNan; + + // Can't fold the ordered check if we're only testing for snan or qnan + // individually. + if ((FPTestMask & fcNan) != fcNan) + OrderedFPTestMask = FPTestMask; + + const bool IsOrdered = FPTestMask == OrderedFPTestMask; + if (std::optional<bool> IsCmp0 = isFCmpEqualZero(FPTestMask, Semantics, DAG.getMachineFunction()); IsCmp0 && (isCondCodeLegalOrCustom( @@ -8618,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); } } diff --git a/llvm/test/CodeGen/X86/is_fpclass-fp80.ll b/llvm/test/CodeGen/X86/is_fpclass-fp80.ll index 52d294ca01720..56d3ba7cd7b2b 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 86cee3d2c8e69..ba7d13aca03d1 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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits