Skip to content

Commit 1b48c68

Browse files
committed
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.
1 parent 1e5da52 commit 1b48c68

File tree

6 files changed

+159
-121
lines changed

6 files changed

+159
-121
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 UseFP) {
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: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8599,6 +8599,16 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
85998599
ISD::CondCode OrderedCmpOpcode = IsInvertedFP ? ISD::SETUNE : ISD::SETOEQ;
86008600
ISD::CondCode UnorderedCmpOpcode = IsInvertedFP ? ISD::SETONE : ISD::SETUEQ;
86018601

8602+
// See if we can fold an | fcNan into an unordered compare.
8603+
FPClassTest OrderedFPTestMask = FPTestMask & ~fcNan;
8604+
8605+
// Can't fold the ordered check if we're only testing for snan or qnan
8606+
// individually.
8607+
if ((FPTestMask & fcNan) != fcNan)
8608+
OrderedFPTestMask = FPTestMask;
8609+
8610+
const bool IsOrdered = FPTestMask == OrderedFPTestMask;
8611+
86028612
if (std::optional<bool> IsCmp0 =
86038613
isFCmpEqualZero(FPTestMask, Semantics, DAG.getMachineFunction());
86048614
IsCmp0 && (isCondCodeLegalOrCustom(
@@ -8618,18 +8628,29 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
86188628
return DAG.getSetCC(DL, ResultVT, Op, Op,
86198629
IsInvertedFP ? ISD::SETO : ISD::SETUO);
86208630

8621-
bool IsOrderedInf = FPTestMask == fcInf;
8622-
if ((FPTestMask == fcInf || FPTestMask == (fcInf | fcNan)) &&
8623-
isCondCodeLegalOrCustom(IsOrderedInf ? OrderedCmpOpcode
8624-
: UnorderedCmpOpcode,
8625-
OperandVT.getScalarType().getSimpleVT()) &&
8626-
isOperationLegalOrCustom(ISD::FABS, OperandVT.getScalarType())) {
8631+
if (OrderedFPTestMask == fcInf &&
8632+
isCondCodeLegalOrCustom(IsOrdered ? OrderedCmpOpcode
8633+
: UnorderedCmpOpcode,
8634+
OperandVT.getScalarType().getSimpleVT())) {
86278635
// isinf(x) --> fabs(x) == inf
86288636
SDValue Abs = DAG.getNode(ISD::FABS, DL, OperandVT, Op);
86298637
SDValue Inf =
86308638
DAG.getConstantFP(APFloat::getInf(Semantics), DL, OperandVT);
86318639
return DAG.getSetCC(DL, ResultVT, Abs, Inf,
8632-
IsOrderedInf ? OrderedCmpOpcode : UnorderedCmpOpcode);
8640+
IsOrdered ? OrderedCmpOpcode : UnorderedCmpOpcode);
8641+
}
8642+
8643+
if (OrderedFPTestMask == fcPosInf || OrderedFPTestMask == fcNegInf) {
8644+
// isposinf(x) --> x == inf
8645+
// isneginf(x) --> x == -inf
8646+
// isposinf(x) || nan --> x u== inf
8647+
// isneginf(x) || nan --> x u== -inf
8648+
8649+
SDValue Inf = DAG.getConstantFP(
8650+
APFloat::getInf(Semantics, OrderedFPTestMask == fcNegInf), DL,
8651+
OperandVT);
8652+
return DAG.getSetCC(DL, ResultVT, Op, Inf,
8653+
IsOrdered ? OrderedCmpOpcode : UnorderedCmpOpcode);
86338654
}
86348655
}
86358656

llvm/test/CodeGen/AArch64/isinf.ll

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,22 @@ define i32 @replace_isinf_call_f64(double %x) {
5858
define i32 @replace_isinf_call_f128(fp128 %x) {
5959
; CHECK-LABEL: replace_isinf_call_f128:
6060
; CHECK: // %bb.0:
61-
; CHECK-NEXT: str q0, [sp, #-16]!
62-
; CHECK-NEXT: .cfi_def_cfa_offset 16
63-
; CHECK-NEXT: ldp x9, x8, [sp], #16
64-
; CHECK-NEXT: and x8, x8, #0x7fffffffffffffff
65-
; CHECK-NEXT: eor x8, x8, #0x7fff000000000000
66-
; CHECK-NEXT: orr x8, x9, x8
67-
; CHECK-NEXT: cmp x8, #0
61+
; CHECK-NEXT: sub sp, sp, #32
62+
; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
63+
; CHECK-NEXT: .cfi_def_cfa_offset 32
64+
; CHECK-NEXT: .cfi_offset w30, -16
65+
; CHECK-NEXT: str q0, [sp]
66+
; CHECK-NEXT: ldrb w8, [sp, #15]
67+
; CHECK-NEXT: and w8, w8, #0x7f
68+
; CHECK-NEXT: strb w8, [sp, #15]
69+
; CHECK-NEXT: adrp x8, .LCPI3_0
70+
; CHECK-NEXT: ldr q0, [sp]
71+
; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI3_0]
72+
; CHECK-NEXT: bl __eqtf2
73+
; CHECK-NEXT: cmp w0, #0
74+
; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
6875
; CHECK-NEXT: cset w0, eq
76+
; CHECK-NEXT: add sp, sp, #32
6977
; CHECK-NEXT: ret
7078
%abs = tail call fp128 @llvm.fabs.f128(fp128 %x)
7179
%cmpinf = fcmp oeq fp128 %abs, 0xL00000000000000007FFF000000000000

llvm/test/CodeGen/PowerPC/fp-classify.ll

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,30 @@ entry:
5757
define zeroext i1 @abs_isinfq(fp128 %x) {
5858
; P8-LABEL: abs_isinfq:
5959
; P8: # %bb.0: # %entry
60+
; P8-NEXT: mflr 0
61+
; P8-NEXT: stdu 1, -48(1)
62+
; P8-NEXT: std 0, 64(1)
63+
; P8-NEXT: .cfi_def_cfa_offset 48
64+
; P8-NEXT: .cfi_offset lr, 16
6065
; P8-NEXT: xxswapd 0, 34
61-
; P8-NEXT: addi 3, 1, -16
62-
; P8-NEXT: li 5, 32767
66+
; P8-NEXT: addi 3, 1, 32
6367
; P8-NEXT: stxvd2x 0, 0, 3
64-
; P8-NEXT: rldic 5, 5, 48, 1
65-
; P8-NEXT: ld 4, -8(1)
66-
; P8-NEXT: ld 3, -16(1)
67-
; P8-NEXT: clrldi 4, 4, 1
68-
; P8-NEXT: xor 4, 4, 5
69-
; P8-NEXT: or 3, 3, 4
70-
; P8-NEXT: cntlzd 3, 3
71-
; P8-NEXT: rldicl 3, 3, 58, 63
68+
; P8-NEXT: lbz 4, 47(1)
69+
; P8-NEXT: clrlwi 4, 4, 25
70+
; P8-NEXT: stb 4, 47(1)
71+
; P8-NEXT: lxvd2x 0, 0, 3
72+
; P8-NEXT: addis 3, 2, .LCPI2_0@toc@ha
73+
; P8-NEXT: addi 3, 3, .LCPI2_0@toc@l
74+
; P8-NEXT: xxswapd 34, 0
75+
; P8-NEXT: lxvd2x 0, 0, 3
76+
; P8-NEXT: xxswapd 35, 0
77+
; P8-NEXT: bl __eqkf2
78+
; P8-NEXT: nop
79+
; P8-NEXT: cntlzw 3, 3
80+
; P8-NEXT: srwi 3, 3, 5
81+
; P8-NEXT: addi 1, 1, 48
82+
; P8-NEXT: ld 0, 16(1)
83+
; P8-NEXT: mtlr 0
7284
; P8-NEXT: blr
7385
;
7486
; P9-LABEL: abs_isinfq:

llvm/test/CodeGen/X86/is_fpclass-fp80.ll

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -265,23 +265,24 @@ entry:
265265
define i1 @is_posinf_f80(x86_fp80 %x) nounwind {
266266
; X86-LABEL: is_posinf_f80:
267267
; X86: # %bb.0: # %entry
268-
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
269-
; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
270-
; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
271-
; X86-NEXT: xorl $32767, %eax # imm = 0x7FFF
272-
; X86-NEXT: orl {{[0-9]+}}(%esp), %eax
273-
; X86-NEXT: orl %ecx, %eax
274-
; X86-NEXT: sete %al
268+
; X86-NEXT: fldt {{[0-9]+}}(%esp)
269+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
270+
; X86-NEXT: fxch %st(1)
271+
; X86-NEXT: fucompp
272+
; X86-NEXT: fnstsw %ax
273+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
274+
; X86-NEXT: sahf
275+
; X86-NEXT: setae %al
275276
; X86-NEXT: retl
276277
;
277278
; X64-LABEL: is_posinf_f80:
278279
; X64: # %bb.0: # %entry
279-
; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
280-
; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
281-
; X64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx
282-
; X64-NEXT: xorq $32767, %rax # imm = 0x7FFF
283-
; X64-NEXT: orq %rcx, %rax
284-
; X64-NEXT: sete %al
280+
; X64-NEXT: fldt {{[0-9]+}}(%rsp)
281+
; X64-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
282+
; X64-NEXT: fxch %st(1)
283+
; X64-NEXT: fucompi %st(1), %st
284+
; X64-NEXT: fstp %st(0)
285+
; X64-NEXT: setae %al
285286
; X64-NEXT: retq
286287
entry:
287288
%0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 512) ; 0x200 = "+inf"
@@ -291,23 +292,22 @@ entry:
291292
define i1 @is_neginf_f80(x86_fp80 %x) nounwind {
292293
; X86-LABEL: is_neginf_f80:
293294
; X86: # %bb.0: # %entry
294-
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
295-
; X86-NEXT: xorl $65535, %eax # imm = 0xFFFF
296-
; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
297-
; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
298-
; X86-NEXT: orl {{[0-9]+}}(%esp), %eax
299-
; X86-NEXT: orl %ecx, %eax
300-
; X86-NEXT: sete %al
295+
; X86-NEXT: fldt {{[0-9]+}}(%esp)
296+
; X86-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}
297+
; X86-NEXT: fucompp
298+
; X86-NEXT: fnstsw %ax
299+
; X86-NEXT: # kill: def $ah killed $ah killed $ax
300+
; X86-NEXT: sahf
301+
; X86-NEXT: setae %al
301302
; X86-NEXT: retl
302303
;
303304
; X64-LABEL: is_neginf_f80:
304305
; X64: # %bb.0: # %entry
305-
; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
306-
; X64-NEXT: xorq $65535, %rax # imm = 0xFFFF
307-
; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
308-
; X64-NEXT: xorq {{[0-9]+}}(%rsp), %rcx
309-
; X64-NEXT: orq %rax, %rcx
310-
; X64-NEXT: sete %al
306+
; X64-NEXT: fldt {{[0-9]+}}(%rsp)
307+
; X64-NEXT: flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
308+
; X64-NEXT: fucompi %st(1), %st
309+
; X64-NEXT: fstp %st(0)
310+
; X64-NEXT: setae %al
311311
; X64-NEXT: retq
312312
entry:
313313
%0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 4) ; "-inf"

0 commit comments

Comments
 (0)