Skip to content

Commit 4a4b918

Browse files
committed
optimize is_finite on floating points
1 parent 2936852 commit 4a4b918

File tree

3 files changed

+268
-159
lines changed

3 files changed

+268
-159
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9122,8 +9122,16 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
91229122
; // Detect finite numbers of f80 by checking individual classes because
91239123
// they have different settings of the explicit integer bit.
91249124
else if ((Test & fcFinite) == fcFinite) {
9125-
// finite(V) ==> abs(V) < exp_mask
9126-
PartialRes = DAG.getSetCC(DL, ResultVT, AbsV, ExpMaskV, ISD::SETLT);
9125+
// Float arithmetic may emit FP exceptions.
9126+
if (Flags.hasNoFPExcept()) {
9127+
// finite(V) ==> (V - V) == (V - V)
9128+
SDValue Sub = DAG.getNode(ISD::FSUB, DL, OperandVT, Op, Op);
9129+
SDValue Zero = DAG.getConstantFP(0.0, DL, OperandVT);
9130+
PartialRes = DAG.getSetCC(DL, ResultVT, Sub, Zero, ISD::SETO);
9131+
} else {
9132+
// finite(V) ==> abs(V) < exp_mask
9133+
PartialRes = DAG.getSetCC(DL, ResultVT, AbsV, ExpMaskV, ISD::SETLT);
9134+
}
91279135
Test &= ~fcFinite;
91289136
} else if ((Test & fcFinite) == fcPosFinite) {
91299137
// finite(V) && V > 0 ==> V < exp_mask
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3+
; RUN: llc -mtriple=aarch64 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4+
5+
define i1 @isfinite_f(float %x) {
6+
; CHECK-SD-LABEL: isfinite_f:
7+
; CHECK-SD: // %bb.0: // %entry
8+
; CHECK-SD-NEXT: fsub s0, s0, s0
9+
; CHECK-SD-NEXT: fcmp s0, s0
10+
; CHECK-SD-NEXT: cset w0, vc
11+
; CHECK-SD-NEXT: ret
12+
;
13+
; CHECK-GI-LABEL: isfinite_f:
14+
; CHECK-GI: // %bb.0: // %entry
15+
; CHECK-GI-NEXT: fmov w9, s0
16+
; CHECK-GI-NEXT: mov w8, #2139095040 // =0x7f800000
17+
; CHECK-GI-NEXT: and w9, w9, #0x7fffffff
18+
; CHECK-GI-NEXT: cmp w9, w8
19+
; CHECK-GI-NEXT: cset w0, lo
20+
; CHECK-GI-NEXT: ret
21+
entry:
22+
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; 0x1f8 = "finite"
23+
ret i1 %0
24+
}
25+
26+
define i1 @not_isfinite_f(float %x) {
27+
; CHECK-SD-LABEL: not_isfinite_f:
28+
; CHECK-SD: // %bb.0: // %entry
29+
; CHECK-SD-NEXT: fsub s0, s0, s0
30+
; CHECK-SD-NEXT: fcmp s0, s0
31+
; CHECK-SD-NEXT: cset w0, vs
32+
; CHECK-SD-NEXT: ret
33+
;
34+
; CHECK-GI-LABEL: not_isfinite_f:
35+
; CHECK-GI: // %bb.0: // %entry
36+
; CHECK-GI-NEXT: fmov w9, s0
37+
; CHECK-GI-NEXT: mov w8, #2139095040 // =0x7f800000
38+
; CHECK-GI-NEXT: and w9, w9, #0x7fffffff
39+
; CHECK-GI-NEXT: cmp w9, w8
40+
; CHECK-GI-NEXT: cset w8, eq
41+
; CHECK-GI-NEXT: cset w9, hi
42+
; CHECK-GI-NEXT: orr w0, w8, w9
43+
; CHECK-GI-NEXT: ret
44+
entry:
45+
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; ~0x1f8 = "~finite"
46+
ret i1 %0
47+
}
48+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
49+
; CHECK: {{.*}}

0 commit comments

Comments
 (0)