Skip to content

Commit 77f1b48

Browse files
authored
DAG: Lower single infinity is.fpclass tests to fcmp (llvm#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.
1 parent 8e35c86 commit 77f1b48

File tree

3 files changed

+54
-56
lines changed

3 files changed

+54
-56
lines changed

llvm/lib/CodeGen/CodeGenCommonISel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ FPClassTest llvm::invertFPClassTestIfSimpler(FPClassTest Test, bool UseFCmp) {
202202
case fcSubnormal | fcZero | fcNan:
203203
return InvertedTest;
204204
case fcInf | fcNan:
205+
case fcPosInf | fcNan:
206+
case fcNegInf | fcNan:
205207
// If we're trying to use fcmp, we can take advantage of the nan check
206208
// behavior of the compare (but this is more instructions in the integer
207209
// expansion).

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8754,6 +8754,22 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
87548754
IsOrderedInf ? OrderedCmpOpcode : UnorderedCmpOpcode);
87558755
}
87568756

8757+
if ((OrderedFPTestMask == fcPosInf || OrderedFPTestMask == fcNegInf) &&
8758+
isCondCodeLegalOrCustom(IsOrdered ? OrderedCmpOpcode
8759+
: UnorderedCmpOpcode,
8760+
OperandVT.getSimpleVT())) {
8761+
// isposinf(x) --> x == inf
8762+
// isneginf(x) --> x == -inf
8763+
// isposinf(x) || nan --> x u== inf
8764+
// isneginf(x) || nan --> x u== -inf
8765+
8766+
SDValue Inf = DAG.getConstantFP(
8767+
APFloat::getInf(Semantics, OrderedFPTestMask == fcNegInf), DL,
8768+
OperandVT);
8769+
return DAG.getSetCC(DL, ResultVT, Op, Inf,
8770+
IsOrdered ? OrderedCmpOpcode : UnorderedCmpOpcode);
8771+
}
8772+
87578773
if (OrderedFPTestMask == (fcSubnormal | fcZero) && !IsOrdered) {
87588774
// TODO: Could handle ordered case, but it produces worse code for
87598775
// x86. Maybe handle ordered if fabs is free?

llvm/test/CodeGen/X86/is_fpclass.ll

Lines changed: 36 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,24 +2116,19 @@ entry:
21162116
define i1 @is_plus_inf_or_nan_f(float %x) {
21172117
; X86-LABEL: is_plus_inf_or_nan_f:
21182118
; X86: # %bb.0:
2119-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
2120-
; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2121-
; X86-NEXT: sete %cl
2122-
; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2123-
; X86-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
2124-
; X86-NEXT: setge %al
2125-
; X86-NEXT: orb %cl, %al
2119+
; X86-NEXT: flds {{[0-9]+}}(%esp)
2120+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
2121+
; X86-NEXT: fucompp
2122+
; X86-NEXT: fnstsw %ax
2123+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
2124+
; X86-NEXT: sahf
2125+
; X86-NEXT: sete %al
21262126
; X86-NEXT: retl
21272127
;
21282128
; X64-LABEL: is_plus_inf_or_nan_f:
21292129
; X64: # %bb.0:
2130-
; X64-NEXT: movd %xmm0, %eax
2131-
; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2132-
; X64-NEXT: sete %cl
2133-
; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2134-
; X64-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
2135-
; X64-NEXT: setge %al
2136-
; X64-NEXT: orb %cl, %al
2130+
; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
2131+
; X64-NEXT: sete %al
21372132
; X64-NEXT: retq
21382133
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 515) ; 0x200|0x3 = "+inf|nan"
21392134
ret i1 %class
@@ -2142,24 +2137,19 @@ define i1 @is_plus_inf_or_nan_f(float %x) {
21422137
define i1 @is_minus_inf_or_nan_f(float %x) {
21432138
; X86-LABEL: is_minus_inf_or_nan_f:
21442139
; X86: # %bb.0:
2145-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
2146-
; X86-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
2147-
; X86-NEXT: sete %cl
2148-
; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2149-
; X86-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
2150-
; X86-NEXT: setge %al
2151-
; X86-NEXT: orb %cl, %al
2140+
; X86-NEXT: flds {{[0-9]+}}(%esp)
2141+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
2142+
; X86-NEXT: fucompp
2143+
; X86-NEXT: fnstsw %ax
2144+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
2145+
; X86-NEXT: sahf
2146+
; X86-NEXT: sete %al
21522147
; X86-NEXT: retl
21532148
;
21542149
; X64-LABEL: is_minus_inf_or_nan_f:
21552150
; X64: # %bb.0:
2156-
; X64-NEXT: movd %xmm0, %eax
2157-
; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
2158-
; X64-NEXT: sete %cl
2159-
; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2160-
; X64-NEXT: cmpl $2139095041, %eax # imm = 0x7F800001
2161-
; X64-NEXT: setge %al
2162-
; X64-NEXT: orb %cl, %al
2151+
; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
2152+
; X64-NEXT: sete %al
21632153
; X64-NEXT: retq
21642154
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 7) ; "-inf|nan"
21652155
ret i1 %class
@@ -2168,24 +2158,19 @@ define i1 @is_minus_inf_or_nan_f(float %x) {
21682158
define i1 @not_is_plus_inf_or_nan_f(float %x) {
21692159
; X86-LABEL: not_is_plus_inf_or_nan_f:
21702160
; X86: # %bb.0:
2171-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
2172-
; X86-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
2173-
; X86-NEXT: sete %cl
2174-
; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2175-
; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2176-
; X86-NEXT: setl %al
2177-
; X86-NEXT: orb %cl, %al
2161+
; X86-NEXT: flds {{[0-9]+}}(%esp)
2162+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
2163+
; X86-NEXT: fucompp
2164+
; X86-NEXT: fnstsw %ax
2165+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
2166+
; X86-NEXT: sahf
2167+
; X86-NEXT: setne %al
21782168
; X86-NEXT: retl
21792169
;
21802170
; X64-LABEL: not_is_plus_inf_or_nan_f:
21812171
; X64: # %bb.0:
2182-
; X64-NEXT: movd %xmm0, %eax
2183-
; X64-NEXT: cmpl $-8388608, %eax # imm = 0xFF800000
2184-
; X64-NEXT: sete %cl
2185-
; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2186-
; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2187-
; X64-NEXT: setl %al
2188-
; X64-NEXT: orb %cl, %al
2172+
; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
2173+
; X64-NEXT: setne %al
21892174
; X64-NEXT: retq
21902175
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)"
21912176
ret i1 %class
@@ -2194,24 +2179,19 @@ define i1 @not_is_plus_inf_or_nan_f(float %x) {
21942179
define i1 @not_is_minus_inf_or_nan_f(float %x) {
21952180
; X86-LABEL: not_is_minus_inf_or_nan_f:
21962181
; X86: # %bb.0:
2197-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
2198-
; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2199-
; X86-NEXT: sete %cl
2200-
; X86-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2201-
; X86-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2202-
; X86-NEXT: setl %al
2203-
; X86-NEXT: orb %cl, %al
2182+
; X86-NEXT: flds {{[0-9]+}}(%esp)
2183+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
2184+
; X86-NEXT: fucompp
2185+
; X86-NEXT: fnstsw %ax
2186+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
2187+
; X86-NEXT: sahf
2188+
; X86-NEXT: setne %al
22042189
; X86-NEXT: retl
22052190
;
22062191
; X64-LABEL: not_is_minus_inf_or_nan_f:
22072192
; X64: # %bb.0:
2208-
; X64-NEXT: movd %xmm0, %eax
2209-
; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2210-
; X64-NEXT: sete %cl
2211-
; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
2212-
; X64-NEXT: cmpl $2139095040, %eax # imm = 0x7F800000
2213-
; X64-NEXT: setl %al
2214-
; X64-NEXT: orb %cl, %al
2193+
; X64-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
2194+
; X64-NEXT: setne %al
22152195
; X64-NEXT: retq
22162196
%class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1016) ; "~(-inf|nan)"
22172197
ret i1 %class

0 commit comments

Comments
 (0)