From db0e6591612b53910a1b366863348bdb9d7d2fb1 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 31 Jan 2023 14:23:56 -0400 Subject: [PATCH] DAG: Fix broken lowering of is.fplcass fcZero with DAZ is.fpclass x, fcZero is not equivalent to fcmp with 0 if denormals are treated as 0. It would be equivalent to fcZero|fcSubnormal which can be done separately; this is the minimal correctness fix. The same optimization was not ported to the GlobalISel version. --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 17 +++++++++--- llvm/test/CodeGen/X86/is_fpclass.ll | 34 ++++++------------------ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 429184d..db26fd2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -8042,10 +8042,19 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op, // exceptions are ignored. if (Flags.hasNoFPExcept() && isOperationLegalOrCustom(ISD::SETCC, OperandVT.getScalarType())) { - if (Test == fcZero) - return DAG.getSetCC(DL, ResultVT, Op, - DAG.getConstantFP(0.0, DL, OperandVT), - IsInverted ? ISD::SETUNE : ISD::SETOEQ); + 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 (Test == fcNan) return DAG.getSetCC(DL, ResultVT, Op, Op, IsInverted ? ISD::SETO : ISD::SETUO); diff --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll index 10183fb..edeadd0 100644 --- a/llvm/test/CodeGen/X86/is_fpclass.ll +++ b/llvm/test/CodeGen/X86/is_fpclass.ll @@ -416,24 +416,15 @@ entry: define i1 @iszero_f_daz(float %x) #0 { ; CHECK-32-LABEL: iszero_f_daz: ; CHECK-32: # %bb.0: # %entry -; 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: testl $2147483647, {{[0-9]+}}(%esp) # imm = 0x7FFFFFFF ; CHECK-32-NEXT: sete %al -; CHECK-32-NEXT: andb %cl, %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: iszero_f_daz: ; CHECK-64: # %bb.0: # %entry -; 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: movd %xmm0, %eax +; CHECK-64-NEXT: testl $2147483647, %eax # imm = 0x7FFFFFFF +; CHECK-64-NEXT: sete %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 96) ; 0x60 = "zero" @@ -443,24 +434,15 @@ entry: define i1 @iszero_f_maybe_daz(float %x) #1 { ; CHECK-32-LABEL: iszero_f_maybe_daz: ; CHECK-32: # %bb.0: # %entry -; 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: testl $2147483647, {{[0-9]+}}(%esp) # imm = 0x7FFFFFFF ; CHECK-32-NEXT: sete %al -; CHECK-32-NEXT: andb %cl, %al ; CHECK-32-NEXT: retl ; ; CHECK-64-LABEL: iszero_f_maybe_daz: ; CHECK-64: # %bb.0: # %entry -; 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: movd %xmm0, %eax +; CHECK-64-NEXT: testl $2147483647, %eax # imm = 0x7FFFFFFF +; CHECK-64-NEXT: sete %al ; CHECK-64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 96) ; 0x60 = "zero" -- 2.7.4