[llvm] SelectionDAG: Support nofpclass with zero/pzero/nzero (PR #137305)

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 25 03:01:21 PDT 2025


https://github.com/wzssyqa created https://github.com/llvm/llvm-project/pull/137305

Add a new argument to isKnownNeverZeroFloat
   FPClassTest FPClassArg
so that we can detect any zero (fcZero) or negtive zero (fcNegZero), or postive zero (fcPosZero).

To utilize this change and figure out a test case, we also support it in expandFMINIMUM_FMAXIMUM: compare +0.0 vs -0.0 is not needed if the two arguments are
   neither negtive zero
or
   neither postive zero

>From 23dd068581bfc0c80240ce491a809ab6bdf362c3 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 25 Apr 2025 17:54:32 +0800
Subject: [PATCH] SelectionDAG: Support nofpclass with zero/pzero/nzero

Add a new argument to isKnownNeverZeroFloat
   FPClassTest FPClassArg
so that we can detect any zero (fcZero) or negtive zero (fcNegZero),
or postive zero (fcPosZero).

To utilize this change and figure out a test case, we also support
it in expandFMINIMUM_FMAXIMUM: compare +0.0 vs -0.0 is not needed if
the two arguments are
   neither negtive zero
or
   neither postive zero
---
 llvm/include/llvm/CodeGen/SelectionDAG.h      |   5 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  12 +-
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |   6 +-
 llvm/test/CodeGen/Mips/nofpclass-r2.ll        | 117 ++++++++
 llvm/test/CodeGen/X86/nofpclass.ll            | 263 ++++++++++++++++++
 5 files changed, 399 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/nofpclass-r2.ll
 create mode 100644 llvm/test/CodeGen/X86/nofpclass.ll

diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index c183149b0863a..f8774c5209f92 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -2169,8 +2169,9 @@ class SelectionDAG {
   }
 
   /// Test whether the given floating point SDValue is known to never be
-  /// positive or negative zero.
-  bool isKnownNeverZeroFloat(SDValue Op) const;
+  /// positive (FPClass is fcPosZero) or negative zero (FPClass is fcNegZero) or
+  /// any zero (FPClass is fcZero).
+  bool isKnownNeverZeroFloat(SDValue Op, FPClassTest FPClass = fcZero) const;
 
   /// Test whether the given SDValue is known to contain non-zero value(s).
   bool isKnownNeverZero(SDValue Op, unsigned Depth = 0) const;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9da2ba04f77cb..7a710482de89d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5852,10 +5852,20 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
   }
 }
 
-bool SelectionDAG::isKnownNeverZeroFloat(SDValue Op) const {
+bool SelectionDAG::isKnownNeverZeroFloat(SDValue Op,
+                                         FPClassTest FPClassArg) const {
   assert(Op.getValueType().isFloatingPoint() &&
          "Floating point type expected");
 
+  FPClassArg &= fcZero;
+  assert(FPClassArg != fcNone && "FPClassArg of isKnownNeverZeroFloat should "
+                                 "be one of fcZero/fcNegZero/fcPosZero");
+  if (Op->getOpcode() == ISD::AssertNoFPClass) {
+    FPClassTest NoFPClass =
+        static_cast<FPClassTest>(Op.getConstantOperandVal(1));
+    if ((NoFPClass & FPClassArg) == FPClassArg)
+      return true;
+  }
   // If the value is a constant, we can obviously see if it is a zero or not.
   return ISD::matchUnaryFpPredicate(
       Op, [](ConstantFPSDNode *C) { return !C->isZero(); });
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 6930b54ddb14a..19f361f23fbf2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8603,7 +8603,11 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
 
   // fminimum/fmaximum requires -0.0 less than +0.0
   if (!MinMaxMustRespectOrderedZero && !N->getFlags().hasNoSignedZeros() &&
-      !DAG.isKnownNeverZeroFloat(RHS) && !DAG.isKnownNeverZeroFloat(LHS)) {
+      !DAG.isKnownNeverZeroFloat(RHS) && !DAG.isKnownNeverZeroFloat(LHS) &&
+      !(DAG.isKnownNeverZeroFloat(RHS, fcNegZero) &&
+        DAG.isKnownNeverZeroFloat(LHS, fcNegZero)) &&
+      !(DAG.isKnownNeverZeroFloat(RHS, fcPosZero) &&
+        DAG.isKnownNeverZeroFloat(LHS, fcPosZero))) {
     SDValue IsZero = DAG.getSetCC(DL, CCVT, MinMax,
                                   DAG.getConstantFP(0.0, DL, VT), ISD::SETOEQ);
     SDValue TestZero =
diff --git a/llvm/test/CodeGen/Mips/nofpclass-r2.ll b/llvm/test/CodeGen/Mips/nofpclass-r2.ll
new file mode 100644
index 0000000000000..37fc73038317b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/nofpclass-r2.ll
@@ -0,0 +1,117 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=mips-linux-gnu < %s | FileCheck %s --check-prefix=MIPS32R2
+
+define float @min(float nofpclass(nan zero) %a, float nofpclass(nan zero) %b) {
+; MIPS32R2-LABEL: min:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.olt.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movt.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minN(float nofpclass(nan nzero) %a, float nofpclass(nan nzero) %b) {
+; MIPS32R2-LABEL: minN:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.olt.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movt.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minP(float nofpclass(nan pzero) %a, float nofpclass(nan pzero) %b) {
+; MIPS32R2-LABEL: minP:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.olt.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movt.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minNP(float nofpclass(nan nzero) %a, float nofpclass(nan pzero) %b) {
+; MIPS32R2-LABEL: minNP:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    c.olt.s $f12, $f14
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    movt.s $f0, $f12, $fcc0
+; MIPS32R2-NEXT:    mfc1 $1, $f12
+; MIPS32R2-NEXT:    lui $2, 32768
+; MIPS32R2-NEXT:    xor $1, $1, $2
+; MIPS32R2-NEXT:    mov.s $f1, $f0
+; MIPS32R2-NEXT:    movz.s $f1, $f12, $1
+; MIPS32R2-NEXT:    mfc1 $1, $f14
+; MIPS32R2-NEXT:    xor $1, $1, $2
+; MIPS32R2-NEXT:    movz.s $f1, $f14, $1
+; MIPS32R2-NEXT:    mtc1 $zero, $f2
+; MIPS32R2-NEXT:    c.eq.s $f0, $f2
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movt.s $f0, $f1, $fcc0
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @max(float nofpclass(nan zero) %a, float nofpclass(nan zero) %b) {
+; MIPS32R2-LABEL: max:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.ule.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movf.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxN(float nofpclass(nan nzero) %a, float nofpclass(nan nzero) %b) {
+; MIPS32R2-LABEL: maxN:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.ule.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movf.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxP(float nofpclass(nan pzero) %a, float nofpclass(nan pzero) %b) {
+; MIPS32R2-LABEL: maxP:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    c.ule.s $f12, $f14
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movf.s $f0, $f12, $fcc0
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxNP(float nofpclass(nan nzero) %a, float nofpclass(nan pzero) %b) {
+; MIPS32R2-LABEL: maxNP:
+; MIPS32R2:       # %bb.0: # %entry
+; MIPS32R2-NEXT:    c.ule.s $f12, $f14
+; MIPS32R2-NEXT:    mov.s $f0, $f14
+; MIPS32R2-NEXT:    movf.s $f0, $f12, $fcc0
+; MIPS32R2-NEXT:    mfc1 $1, $f12
+; MIPS32R2-NEXT:    mov.s $f1, $f0
+; MIPS32R2-NEXT:    movz.s $f1, $f12, $1
+; MIPS32R2-NEXT:    mfc1 $1, $f14
+; MIPS32R2-NEXT:    movz.s $f1, $f14, $1
+; MIPS32R2-NEXT:    mtc1 $zero, $f2
+; MIPS32R2-NEXT:    c.eq.s $f0, $f2
+; MIPS32R2-NEXT:    jr $ra
+; MIPS32R2-NEXT:    movt.s $f0, $f1, $fcc0
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
diff --git a/llvm/test/CodeGen/X86/nofpclass.ll b/llvm/test/CodeGen/X86/nofpclass.ll
new file mode 100644
index 0000000000000..be97d486df40c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/nofpclass.ll
@@ -0,0 +1,263 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=i686-linux-gnu < %s | FileCheck %s --check-prefix=I686
+
+define float @min(float nofpclass(nan zero) %a, float nofpclass(nan zero) %b) {
+; I686-LABEL: min:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB0_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fldz
+; I686-NEXT:  .LBB0_2: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minN(float nofpclass(nan nzero) %a, float nofpclass(nan nzero) %b) {
+; I686-LABEL: minN:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB1_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fldz
+; I686-NEXT:  .LBB1_2: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minP(float nofpclass(nan pzero) %a, float nofpclass(nan pzero) %b) {
+; I686-LABEL: minP:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB2_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fldz
+; I686-NEXT:  .LBB2_2: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @minNP(float nofpclass(nan nzero) %a, float nofpclass(nan pzero) %b) {
+; I686-LABEL: minNP:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    subl $8, %esp
+; I686-NEXT:    .cfi_def_cfa_offset 12
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fsts {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fsts (%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    fld %st(1)
+; I686-NEXT:    ja .LBB3_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    fld %st(0)
+; I686-NEXT:  .LBB3_2: # %entry
+; I686-NEXT:    xorl %eax, %eax
+; I686-NEXT:    cmpl {{[0-9]+}}(%esp), %eax
+; I686-NEXT:    jo .LBB3_4
+; I686-NEXT:  # %bb.3: # %entry
+; I686-NEXT:    fstp %st(2)
+; I686-NEXT:    fld %st(1)
+; I686-NEXT:    fxch %st(2)
+; I686-NEXT:  .LBB3_4: # %entry
+; I686-NEXT:    cmpl (%esp), %eax
+; I686-NEXT:    jo .LBB3_6
+; I686-NEXT:  # %bb.5: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(2)
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:  .LBB3_6: # %entry
+; I686-NEXT:    fstp %st(2)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(2)
+; I686-NEXT:    fucom %st(2)
+; I686-NEXT:    fstp %st(2)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    jne .LBB3_7
+; I686-NEXT:  # %bb.8: # %entry
+; I686-NEXT:    jp .LBB3_11
+; I686-NEXT:  # %bb.9: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    jmp .LBB3_10
+; I686-NEXT:  .LBB3_7:
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:  .LBB3_10: # %entry
+; I686-NEXT:    fldz
+; I686-NEXT:  .LBB3_11: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    addl $8, %esp
+; I686-NEXT:    .cfi_def_cfa_offset 4
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.minimum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @max(float nofpclass(nan zero) %a, float nofpclass(nan zero) %b) {
+; I686-LABEL: max:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB4_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:  .LBB4_2: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxN(float nofpclass(nan nzero) %a, float nofpclass(nan nzero) %b) {
+; I686-LABEL: maxN:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB5_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:  .LBB5_2: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxP(float nofpclass(nan pzero) %a, float nofpclass(nan pzero) %b) {
+; I686-LABEL: maxP:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    ja .LBB6_2
+; I686-NEXT:  # %bb.1: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:  .LBB6_2: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}
+
+define float @maxNP(float nofpclass(nan nzero) %a, float nofpclass(nan pzero) %b) {
+; I686-LABEL: maxNP:
+; I686:       # %bb.0: # %entry
+; I686-NEXT:    subl $8, %esp
+; I686-NEXT:    .cfi_def_cfa_offset 12
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fsts {{[0-9]+}}(%esp)
+; I686-NEXT:    flds {{[0-9]+}}(%esp)
+; I686-NEXT:    fsts (%esp)
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    fld %st(0)
+; I686-NEXT:    jbe .LBB7_1
+; I686-NEXT:  # %bb.2: # %entry
+; I686-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
+; I686-NEXT:    jne .LBB7_3
+; I686-NEXT:  .LBB7_4: # %entry
+; I686-NEXT:    cmpl $0, (%esp)
+; I686-NEXT:    je .LBB7_6
+; I686-NEXT:  .LBB7_5: # %entry
+; I686-NEXT:    fstp %st(2)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:    fxch %st(2)
+; I686-NEXT:  .LBB7_6: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:    fucom %st(1)
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fnstsw %ax
+; I686-NEXT:    # kill: def $ah killed $ah killed $ax
+; I686-NEXT:    sahf
+; I686-NEXT:    jne .LBB7_7
+; I686-NEXT:  # %bb.8: # %entry
+; I686-NEXT:    jp .LBB7_11
+; I686-NEXT:  # %bb.9: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    jmp .LBB7_10
+; I686-NEXT:  .LBB7_1: # %entry
+; I686-NEXT:    fstp %st(0)
+; I686-NEXT:    fld %st(1)
+; I686-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
+; I686-NEXT:    je .LBB7_4
+; I686-NEXT:  .LBB7_3: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    fld %st(0)
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:    cmpl $0, (%esp)
+; I686-NEXT:    jne .LBB7_5
+; I686-NEXT:    jmp .LBB7_6
+; I686-NEXT:  .LBB7_7:
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:  .LBB7_10: # %entry
+; I686-NEXT:    fldz
+; I686-NEXT:    fxch %st(1)
+; I686-NEXT:  .LBB7_11: # %entry
+; I686-NEXT:    fstp %st(1)
+; I686-NEXT:    addl $8, %esp
+; I686-NEXT:    .cfi_def_cfa_offset 4
+; I686-NEXT:    retl
+entry:
+  %0 = tail call float @llvm.maximum.f32(float %a, float %b)
+  ret float %0
+}



More information about the llvm-commits mailing list