From 226d97740d9043607ebe3f7b68bf31e2333f2b4b Mon Sep 17 00:00:00 2001 From: Matt Arsenault 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 | 16 ++++ llvm/test/CodeGen/X86/is_fpclass.ll | 92 ++++++++----------- 3 files changed, 54 insertions(+), 56 deletions(-) diff --git a/llvm/lib/CodeGen/CodeGenCommonISel.cpp b/llvm/lib/CodeGen/CodeGenCommonISel.cpp index d985751e2be0b..4cd2f6ae2fdb1 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 c3affabb19d37..2b41b8a9a810e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -8754,6 +8754,22 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op, IsOrderedInf ? OrderedCmpOpcode : UnorderedCmpOpcode); } + if ((OrderedFPTestMask == fcPosInf || OrderedFPTestMask == fcNegInf) && + isCondCodeLegalOrCustom(IsOrdered ? OrderedCmpOpcode + : UnorderedCmpOpcode, + OperandVT.getSimpleVT())) { + // 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) { // TODO: Could handle ordered case, but it produces worse code for // x86. Maybe handle ordered if fabs is free? diff --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll index cc4d4c4543a51..97136dafa6c2c 100644 --- a/llvm/test/CodeGen/X86/is_fpclass.ll +++ b/llvm/test/CodeGen/X86/is_fpclass.ll @@ -2116,24 +2116,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 +2137,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 +2158,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 +2179,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