[llvm] 18b9356 - DAG: Expand legalization of is.fpclass to fcmp for DAZ
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 22 03:18:09 PDT 2023
Author: Matt Arsenault
Date: 2023-06-22T06:18:02-04:00
New Revision: 18b93562cfcf0fb728e6fc985855f3e74aac438d
URL: https://github.com/llvm/llvm-project/commit/18b93562cfcf0fb728e6fc985855f3e74aac438d
DIFF: https://github.com/llvm/llvm-project/commit/18b93562cfcf0fb728e6fc985855f3e74aac438d.diff
LOG: DAG: Expand legalization of is.fpclass to fcmp for DAZ
Try to use a compare with 0 if DAZ is assumed.
FPClassTest really needs to be marked as a bimask enum, but the API
for that is currently broken.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/test/CodeGen/X86/is_fpclass.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 6da772d43f893..3d213d3449b8a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8054,6 +8054,19 @@ SDValue TargetLowering::expandFMINNUM_FMAXNUM(SDNode *Node,
return SDValue();
}
+/// If this FPClassTest can be performed with a fcmp to 0, return the test mask
+/// for the floating-point mode.
+static bool isFCmpEqualZero(FPClassTest Test, const fltSemantics &Semantics,
+ const MachineFunction &MF) {
+ if (Test == fcZero &&
+ MF.getDenormalMode(Semantics).Input == DenormalMode::IEEE)
+ return true;
+ if (Test == (fcZero | fcSubnormal) &&
+ MF.getDenormalMode(Semantics).inputsAreZero())
+ return true;
+ return false;
+}
+
SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
FPClassTest Test, SDNodeFlags Flags,
const SDLoc &DL,
@@ -8062,7 +8075,7 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
assert(OperandVT.isFloatingPoint());
// Degenerated cases.
- if (Test == 0)
+ if (Test == fcNone)
return DAG.getBoolConstant(false, DL, ResultVT, OperandVT);
if ((Test & fcAllFlags) == fcAllFlags)
return DAG.getBoolConstant(true, DL, ResultVT, OperandVT);
@@ -8092,18 +8105,14 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
// Some checks can be implemented using float comparisons, if floating point
// exceptions are ignored.
if (Flags.hasNoFPExcept() &&
+ // TODO: Should check isCondCodeLegal
isOperationLegalOrCustom(ISD::SETCC, OperandVT.getScalarType())) {
- if (Test == fcZero) {
- DenormalMode Mode = DAG.getMachineFunction().getDenormalMode(Semantics);
- if (Mode.Input == DenormalMode::IEEE) {
- // If denormals could be implicitly treated as 0, this is not equivalent
- // to a compare with 0 since it will also be true for denormals.
- //
- // TODO: With DAZ, check == fcZero | fcSubnormal
- return DAG.getSetCC(DL, ResultVT, Op,
- DAG.getConstantFP(0.0, DL, OperandVT),
- IsInverted ? ISD::SETUNE : ISD::SETOEQ);
- }
+ if (isFCmpEqualZero(Test, Semantics, DAG.getMachineFunction())) {
+ // If denormals could be implicitly treated as 0, this is not equivalent
+ // to a compare with 0 since it will also be true for denormals.
+ return DAG.getSetCC(DL, ResultVT, Op,
+ DAG.getConstantFP(0.0, DL, OperandVT),
+ IsInverted ? ISD::SETUNE : ISD::SETOEQ);
}
if (Test == fcNan)
diff --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll
index 6a531817e7719..fc3e5f7a19ad4 100644
--- a/llvm/test/CodeGen/X86/is_fpclass.ll
+++ b/llvm/test/CodeGen/X86/is_fpclass.ll
@@ -837,24 +837,24 @@ entry:
define i1 @issubnormal_or_zero_f_daz(float %x) #0 {
; CHECK-32-LABEL: issubnormal_or_zero_f_daz:
; CHECK-32: # %bb.0: # %entry
-; CHECK-32-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-32-NEXT: andl {{[0-9]+}}(%esp), %eax
-; CHECK-32-NEXT: sete %cl
-; CHECK-32-NEXT: decl %eax
-; CHECK-32-NEXT: cmpl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-32-NEXT: setb %al
-; CHECK-32-NEXT: orb %cl, %al
+; CHECK-32-NEXT: flds {{[0-9]+}}(%esp)
+; CHECK-32-NEXT: fldz
+; CHECK-32-NEXT: fucompp
+; CHECK-32-NEXT: fnstsw %ax
+; CHECK-32-NEXT: # kill: def $ah killed $ah killed $ax
+; CHECK-32-NEXT: sahf
+; CHECK-32-NEXT: setnp %cl
+; CHECK-32-NEXT: sete %al
+; CHECK-32-NEXT: andb %cl, %al
; CHECK-32-NEXT: retl
;
; CHECK-64-LABEL: issubnormal_or_zero_f_daz:
; CHECK-64: # %bb.0: # %entry
-; CHECK-64-NEXT: movd %xmm0, %eax
-; CHECK-64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-64-NEXT: sete %cl
-; CHECK-64-NEXT: decl %eax
-; CHECK-64-NEXT: cmpl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-64-NEXT: setb %al
-; CHECK-64-NEXT: orb %cl, %al
+; CHECK-64-NEXT: xorps %xmm1, %xmm1
+; CHECK-64-NEXT: cmpeqss %xmm0, %xmm1
+; CHECK-64-NEXT: movd %xmm1, %eax
+; CHECK-64-NEXT: andl $1, %eax
+; CHECK-64-NEXT: # kill: def $al killed $al killed $eax
; CHECK-64-NEXT: retq
entry:
%0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 240) ; 0xf0 = "subnormal|zero"
More information about the llvm-commits
mailing list