[llvm-branch-commits] [llvm] release/23.x: [X86] Fix NaN handling in minimumnum/maximumnum zero fixup (#217420) (PR #218645)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 25 02:28:28 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Nikita Popov (nikic)

<details>
<summary>Changes</summary>

(cherry picked from commit 4a1c14678024d9b424cbca33774afdccdb14019e)

---

Patch is 97.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218645.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+7) 
- (modified) llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll (+819-245) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9452d18018db6..1183ad64f1554 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -30194,6 +30194,13 @@ static SDValue LowerFMINIMUM_FMAXIMUM(SDValue Op, const X86Subtarget &Subtarget,
                            DAG.getVectorIdxConstant(0, DL));
     else
       MinMax = Result;
+
+    // The signed-zero fixup may corrupt the numeric NewY result with the sign
+    // bit of a NaN NewX. Restore NewY in that case.
+    if (IsNum && !IgnoreNaN && !IsXNeverNaN) {
+      SDValue IsXNaN = DAG.getSetCC(DL, SetCCType, NewX, NewX, ISD::SETUO);
+      MinMax = DAG.getSelect(DL, VT, IsXNaN, NewY, MinMax);
+    }
   }
 
   if (IgnoreNaN || DAG.isKnownNeverNaN(IsNum ? NewY : NewX))
diff --git a/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll b/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
index 8abd68701676c..19d7832ea6991 100644
--- a/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
+++ b/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
@@ -27,16 +27,21 @@ declare <4 x bfloat> @llvm.maximumnum.v4bf16(<4 x bfloat>, <4 x bfloat>)
 define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; SSE2-LABEL: test_fmaximumnum:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm3
-; SSE2-NEXT:    maxss %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    cmpunordss %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm2, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm4
+; SSE2-NEXT:    maxss %xmm1, %xmm4
+; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    orps %xmm0, %xmm5
+; SSE2-NEXT:    andps %xmm4, %xmm5
+; SSE2-NEXT:    andnps %xmm5, %xmm2
+; SSE2-NEXT:    orps %xmm3, %xmm2
 ; SSE2-NEXT:    cmpunordss %xmm1, %xmm1
-; SSE2-NEXT:    movaps %xmm1, %xmm2
-; SSE2-NEXT:    andps %xmm0, %xmm2
-; SSE2-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    andps %xmm3, %xmm0
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm2
-; SSE2-NEXT:    movaps %xmm2, %xmm0
+; SSE2-NEXT:    andps %xmm1, %xmm0
+; SSE2-NEXT:    andnps %xmm2, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; AVX1-LABEL: test_fmaximumnum:
@@ -44,6 +49,8 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; AVX1-NEXT:    vmaxss %xmm1, %xmm0, %xmm2
 ; AVX1-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
 ; AVX1-NEXT:    vandps %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm3
+; AVX1-NEXT:    vblendvps %xmm3, %xmm1, %xmm2, %xmm2
 ; AVX1-NEXT:    vcmpunordss %xmm1, %xmm1, %xmm1
 ; AVX1-NEXT:    vblendvps %xmm1, %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    retq
@@ -54,6 +61,8 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; AVX512F-NEXT:    vorps %xmm2, %xmm0, %xmm2
 ; AVX512F-NEXT:    vmaxss %xmm1, %xmm0, %xmm3
 ; AVX512F-NEXT:    vandps %xmm3, %xmm2, %xmm2
+; AVX512F-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512F-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512F-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512F-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512F-NEXT:    vmovaps %xmm2, %xmm0
@@ -65,6 +74,8 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; AVX512DQ-NEXT:    vorps %xmm2, %xmm0, %xmm2
 ; AVX512DQ-NEXT:    vmaxss %xmm1, %xmm0, %xmm3
 ; AVX512DQ-NEXT:    vandps %xmm3, %xmm2, %xmm2
+; AVX512DQ-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512DQ-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512DQ-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512DQ-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512DQ-NEXT:    vmovaps %xmm2, %xmm0
@@ -74,6 +85,8 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; AVX512BF16:       # %bb.0:
 ; AVX512BF16-NEXT:    vmaxss %xmm1, %xmm0, %xmm2
 ; AVX512BF16-NEXT:    vpternlogd {{.*#+}} xmm2 = xmm2 & (xmm0 | m32bcst)
+; AVX512BF16-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512BF16-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512BF16-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512BF16-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512BF16-NEXT:    vmovaps %xmm2, %xmm0
@@ -92,6 +105,8 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
 ; X86-NEXT:    vmaxss %xmm0, %xmm1, %xmm2
 ; X86-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1, %xmm3
 ; X86-NEXT:    vandps %xmm2, %xmm3, %xmm2
+; X86-NEXT:    vcmpunordss %xmm1, %xmm1, %xmm3
+; X86-NEXT:    vblendvps %xmm3, %xmm0, %xmm2, %xmm2
 ; X86-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm0
 ; X86-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
 ; X86-NEXT:    vmovss %xmm0, (%esp)
@@ -102,6 +117,103 @@ define float @test_fmaximumnum(float %x, float %y) nounwind {
   ret float %1
 }
 
+; Keep both operands unknown so lowering must handle a NaN in the first operand
+; after the signed-zero fixup.
+define double @test_fmaximumnum_f64(double %x, double %y) nounwind {
+; SSE2-LABEL: test_fmaximumnum_f64:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    cmpunordsd %xmm0, %xmm2
+; SSE2-NEXT:    movapd %xmm2, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    movapd %xmm0, %xmm4
+; SSE2-NEXT:    maxsd %xmm1, %xmm4
+; SSE2-NEXT:    movapd {{.*#+}} xmm5 = [NaN,NaN]
+; SSE2-NEXT:    orpd %xmm0, %xmm5
+; SSE2-NEXT:    andpd %xmm4, %xmm5
+; SSE2-NEXT:    andnpd %xmm5, %xmm2
+; SSE2-NEXT:    orpd %xmm3, %xmm2
+; SSE2-NEXT:    cmpunordsd %xmm1, %xmm1
+; SSE2-NEXT:    andpd %xmm1, %xmm0
+; SSE2-NEXT:    andnpd %xmm2, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm0
+; SSE2-NEXT:    retq
+;
+; AVX1-LABEL: test_fmaximumnum_f64:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vmaxsd %xmm1, %xmm0, %xmm2
+; AVX1-NEXT:    vorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX1-NEXT:    vandpd %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vcmpunordsd %xmm0, %xmm0, %xmm3
+; AVX1-NEXT:    vblendvpd %xmm3, %xmm1, %xmm2, %xmm2
+; AVX1-NEXT:    vcmpunordsd %xmm1, %xmm1, %xmm1
+; AVX1-NEXT:    vblendvpd %xmm1, %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    retq
+;
+; AVX512F-LABEL: test_fmaximumnum_f64:
+; AVX512F:       # %bb.0:
+; AVX512F-NEXT:    vmaxsd %xmm1, %xmm0, %xmm2
+; AVX512F-NEXT:    vorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX512F-NEXT:    vandpd %xmm2, %xmm3, %xmm2
+; AVX512F-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512F-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512F-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512F-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512F-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512F-NEXT:    retq
+;
+; AVX512DQ-LABEL: test_fmaximumnum_f64:
+; AVX512DQ:       # %bb.0:
+; AVX512DQ-NEXT:    vmaxsd %xmm1, %xmm0, %xmm2
+; AVX512DQ-NEXT:    vorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX512DQ-NEXT:    vandpd %xmm2, %xmm3, %xmm2
+; AVX512DQ-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512DQ-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512DQ-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512DQ-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512DQ-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512DQ-NEXT:    retq
+;
+; AVX512BF16-LABEL: test_fmaximumnum_f64:
+; AVX512BF16:       # %bb.0:
+; AVX512BF16-NEXT:    vmaxsd %xmm1, %xmm0, %xmm2
+; AVX512BF16-NEXT:    vpternlogq {{.*#+}} xmm2 = xmm2 & (xmm0 | m64bcst)
+; AVX512BF16-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512BF16-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512BF16-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512BF16-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512BF16-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512BF16-NEXT:    retq
+;
+; AVX10_2-LABEL: test_fmaximumnum_f64:
+; AVX10_2:       # %bb.0:
+; AVX10_2-NEXT:    vminmaxsd $21, %xmm1, %xmm0
+; AVX10_2-NEXT:    retq
+;
+; X86-LABEL: test_fmaximumnum_f64:
+; X86:       # %bb.0:
+; X86-NEXT:    pushl %ebp
+; X86-NEXT:    movl %esp, %ebp
+; X86-NEXT:    andl $-8, %esp
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; X86-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
+; X86-NEXT:    vmaxsd %xmm0, %xmm1, %xmm2
+; X86-NEXT:    vorpd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1, %xmm3
+; X86-NEXT:    vandpd %xmm2, %xmm3, %xmm2
+; X86-NEXT:    vcmpunordsd %xmm1, %xmm1, %xmm3
+; X86-NEXT:    vblendvpd %xmm3, %xmm0, %xmm2, %xmm2
+; X86-NEXT:    vcmpunordsd %xmm0, %xmm0, %xmm0
+; X86-NEXT:    vblendvpd %xmm0, %xmm1, %xmm2, %xmm0
+; X86-NEXT:    vmovlpd %xmm0, (%esp)
+; X86-NEXT:    fldl (%esp)
+; X86-NEXT:    movl %ebp, %esp
+; X86-NEXT:    popl %ebp
+; X86-NEXT:    retl
+  %r = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %r
+}
+
 define <4 x float> @test_fmaximumnum_scalarize(<4 x float> %x, <4 x float> %y) {
 ; SSE2-LABEL: test_fmaximumnum_scalarize:
 ; SSE2:       # %bb.0:
@@ -403,26 +515,38 @@ define float @test_fmaximumnum_combine_cmps(float %x, float %y) nounwind {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    divss %xmm0, %xmm1
 ; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    maxss %xmm1, %xmm2
+; SSE2-NEXT:    cmpunordss %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm2, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm4
+; SSE2-NEXT:    maxss %xmm1, %xmm4
 ; SSE2-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andps %xmm4, %xmm0
+; SSE2-NEXT:    andnps %xmm0, %xmm2
+; SSE2-NEXT:    orps %xmm3, %xmm2
+; SSE2-NEXT:    movaps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; AVX1-LABEL: test_fmaximumnum_combine_cmps:
 ; AVX1:       # %bb.0:
 ; AVX1-NEXT:    vdivss %xmm0, %xmm1, %xmm1
-; AVX1-NEXT:    vmaxss %xmm1, %xmm0, %xmm1
-; AVX1-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vandps %xmm1, %xmm0, %xmm0
+; AVX1-NEXT:    vmaxss %xmm1, %xmm0, %xmm2
+; AVX1-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX1-NEXT:    vandps %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm0
+; AVX1-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX512F-LABEL: test_fmaximumnum_combine_cmps:
 ; AVX512F:       # %bb.0:
-; AVX512F-NEXT:    vdivss %xmm0, %xmm1, %xmm1
-; AVX512F-NEXT:    vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
-; AVX512F-NEXT:    vorps %xmm2, %xmm0, %xmm2
-; AVX512F-NEXT:    vmaxss %xmm1, %xmm0, %xmm0
-; AVX512F-NEXT:    vandps %xmm0, %xmm2, %xmm0
+; AVX512F-NEXT:    vdivss %xmm0, %xmm1, %xmm2
+; AVX512F-NEXT:    vbroadcastss {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; AVX512F-NEXT:    vorps %xmm1, %xmm0, %xmm1
+; AVX512F-NEXT:    vmaxss %xmm2, %xmm0, %xmm3
+; AVX512F-NEXT:    vandps %xmm3, %xmm1, %xmm1
+; AVX512F-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512F-NEXT:    vmovss %xmm2, %xmm1, %xmm1 {%k1}
+; AVX512F-NEXT:    vmovaps %xmm1, %xmm0
 ; AVX512F-NEXT:    retq
 ;
 ; AVX512DQ-LABEL: test_fmaximumnum_combine_cmps:
@@ -438,9 +562,12 @@ define float @test_fmaximumnum_combine_cmps(float %x, float %y) nounwind {
 ;
 ; AVX512BF16-LABEL: test_fmaximumnum_combine_cmps:
 ; AVX512BF16:       # %bb.0:
-; AVX512BF16-NEXT:    vdivss %xmm0, %xmm1, %xmm1
-; AVX512BF16-NEXT:    vmaxss %xmm1, %xmm0, %xmm1
-; AVX512BF16-NEXT:    vpternlogd {{.*#+}} xmm0 = xmm1 & (xmm0 | m32bcst)
+; AVX512BF16-NEXT:    vdivss %xmm0, %xmm1, %xmm2
+; AVX512BF16-NEXT:    vmaxss %xmm2, %xmm0, %xmm1
+; AVX512BF16-NEXT:    vpternlogd {{.*#+}} xmm1 = xmm1 & (xmm0 | m32bcst)
+; AVX512BF16-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512BF16-NEXT:    vmovss %xmm2, %xmm1, %xmm1 {%k1}
+; AVX512BF16-NEXT:    vmovaps %xmm1, %xmm0
 ; AVX512BF16-NEXT:    retq
 ;
 ; AVX10_2-LABEL: test_fmaximumnum_combine_cmps:
@@ -455,9 +582,11 @@ define float @test_fmaximumnum_combine_cmps(float %x, float %y) nounwind {
 ; X86-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
 ; X86-NEXT:    vdivss %xmm0, %xmm1, %xmm1
-; X86-NEXT:    vmaxss %xmm1, %xmm0, %xmm1
-; X86-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0, %xmm0
-; X86-NEXT:    vandps %xmm1, %xmm0, %xmm0
+; X86-NEXT:    vmaxss %xmm1, %xmm0, %xmm2
+; X86-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0, %xmm3
+; X86-NEXT:    vandps %xmm2, %xmm3, %xmm2
+; X86-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm0
+; X86-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
 ; X86-NEXT:    vmovss %xmm0, (%esp)
 ; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    popl %eax
@@ -474,16 +603,21 @@ define float @test_fmaximumnum_combine_cmps(float %x, float %y) nounwind {
 define float @test_fminimumnum(float %x, float %y) nounwind {
 ; SSE2-LABEL: test_fminimumnum:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm3
-; SSE2-NEXT:    minss %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    cmpunordss %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm2, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm4
+; SSE2-NEXT:    minss %xmm1, %xmm4
+; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
+; SSE2-NEXT:    andps %xmm0, %xmm5
+; SSE2-NEXT:    orps %xmm4, %xmm5
+; SSE2-NEXT:    andnps %xmm5, %xmm2
+; SSE2-NEXT:    orps %xmm3, %xmm2
 ; SSE2-NEXT:    cmpunordss %xmm1, %xmm1
-; SSE2-NEXT:    movaps %xmm1, %xmm2
-; SSE2-NEXT:    andps %xmm0, %xmm2
-; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    orps %xmm3, %xmm0
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm2
-; SSE2-NEXT:    movaps %xmm2, %xmm0
+; SSE2-NEXT:    andps %xmm1, %xmm0
+; SSE2-NEXT:    andnps %xmm2, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; AVX1-LABEL: test_fminimumnum:
@@ -491,6 +625,8 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
 ; AVX1-NEXT:    vminss %xmm1, %xmm0, %xmm2
 ; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
 ; AVX1-NEXT:    vorps %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm3
+; AVX1-NEXT:    vblendvps %xmm3, %xmm1, %xmm2, %xmm2
 ; AVX1-NEXT:    vcmpunordss %xmm1, %xmm1, %xmm1
 ; AVX1-NEXT:    vblendvps %xmm1, %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    retq
@@ -501,6 +637,8 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
 ; AVX512F-NEXT:    vandps %xmm2, %xmm0, %xmm2
 ; AVX512F-NEXT:    vminss %xmm1, %xmm0, %xmm3
 ; AVX512F-NEXT:    vorps %xmm3, %xmm2, %xmm2
+; AVX512F-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512F-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512F-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512F-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512F-NEXT:    vmovaps %xmm2, %xmm0
@@ -512,6 +650,8 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
 ; AVX512DQ-NEXT:    vandps %xmm2, %xmm0, %xmm2
 ; AVX512DQ-NEXT:    vminss %xmm1, %xmm0, %xmm3
 ; AVX512DQ-NEXT:    vorps %xmm3, %xmm2, %xmm2
+; AVX512DQ-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512DQ-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512DQ-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512DQ-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512DQ-NEXT:    vmovaps %xmm2, %xmm0
@@ -521,6 +661,8 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
 ; AVX512BF16:       # %bb.0:
 ; AVX512BF16-NEXT:    vminss %xmm1, %xmm0, %xmm2
 ; AVX512BF16-NEXT:    vpternlogd {{.*#+}} xmm2 = xmm2 | (xmm0 & m32bcst)
+; AVX512BF16-NEXT:    vcmpunordss %xmm0, %xmm0, %k1
+; AVX512BF16-NEXT:    vmovss %xmm1, %xmm2, %xmm2 {%k1}
 ; AVX512BF16-NEXT:    vcmpunordss %xmm1, %xmm1, %k1
 ; AVX512BF16-NEXT:    vmovss %xmm0, %xmm2, %xmm2 {%k1}
 ; AVX512BF16-NEXT:    vmovaps %xmm2, %xmm0
@@ -539,6 +681,8 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
 ; X86-NEXT:    vminss %xmm0, %xmm1, %xmm2
 ; X86-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1, %xmm3
 ; X86-NEXT:    vorps %xmm2, %xmm3, %xmm2
+; X86-NEXT:    vcmpunordss %xmm1, %xmm1, %xmm3
+; X86-NEXT:    vblendvps %xmm3, %xmm0, %xmm2, %xmm2
 ; X86-NEXT:    vcmpunordss %xmm0, %xmm0, %xmm0
 ; X86-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
 ; X86-NEXT:    vmovss %xmm0, (%esp)
@@ -549,6 +693,103 @@ define float @test_fminimumnum(float %x, float %y) nounwind {
   ret float %1
 }
 
+; Keep both operands unknown so lowering must handle a NaN in the first operand
+; after the signed-zero fixup.
+define double @test_fminimumnum_f64(double %x, double %y) nounwind {
+; SSE2-LABEL: test_fminimumnum_f64:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    cmpunordsd %xmm0, %xmm2
+; SSE2-NEXT:    movapd %xmm2, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    movapd %xmm0, %xmm4
+; SSE2-NEXT:    minsd %xmm1, %xmm4
+; SSE2-NEXT:    movapd {{.*#+}} xmm5 = [-0.0E+0,-0.0E+0]
+; SSE2-NEXT:    andpd %xmm0, %xmm5
+; SSE2-NEXT:    orpd %xmm4, %xmm5
+; SSE2-NEXT:    andnpd %xmm5, %xmm2
+; SSE2-NEXT:    orpd %xmm3, %xmm2
+; SSE2-NEXT:    cmpunordsd %xmm1, %xmm1
+; SSE2-NEXT:    andpd %xmm1, %xmm0
+; SSE2-NEXT:    andnpd %xmm2, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm0
+; SSE2-NEXT:    retq
+;
+; AVX1-LABEL: test_fminimumnum_f64:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vminsd %xmm1, %xmm0, %xmm2
+; AVX1-NEXT:    vandpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX1-NEXT:    vorpd %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vcmpunordsd %xmm0, %xmm0, %xmm3
+; AVX1-NEXT:    vblendvpd %xmm3, %xmm1, %xmm2, %xmm2
+; AVX1-NEXT:    vcmpunordsd %xmm1, %xmm1, %xmm1
+; AVX1-NEXT:    vblendvpd %xmm1, %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    retq
+;
+; AVX512F-LABEL: test_fminimumnum_f64:
+; AVX512F:       # %bb.0:
+; AVX512F-NEXT:    vminsd %xmm1, %xmm0, %xmm2
+; AVX512F-NEXT:    vandpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX512F-NEXT:    vorpd %xmm2, %xmm3, %xmm2
+; AVX512F-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512F-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512F-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512F-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512F-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512F-NEXT:    retq
+;
+; AVX512DQ-LABEL: test_fminimumnum_f64:
+; AVX512DQ:       # %bb.0:
+; AVX512DQ-NEXT:    vminsd %xmm1, %xmm0, %xmm2
+; AVX512DQ-NEXT:    vandpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm3
+; AVX512DQ-NEXT:    vorpd %xmm2, %xmm3, %xmm2
+; AVX512DQ-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512DQ-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512DQ-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512DQ-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512DQ-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512DQ-NEXT:    retq
+;
+; AVX512BF16-LABEL: test_fminimumnum_f64:
+; AVX512BF16:       # %bb.0:
+; AVX512BF16-NEXT:    vminsd %xmm1, %xmm0, %xmm2
+; AVX512BF16-NEXT:    vpternlogq {{.*#+}} xmm2 = xmm2 | (xmm0 & m64bcst)
+; AVX512BF16-NEXT:    vcmpunordsd %xmm0, %xmm0, %k1
+; AVX512BF16-NEXT:    vmovsd %xmm1, %xmm2, %xmm2 {%k1}
+; AVX512BF16-NEXT:    vcmpunordsd %xmm1, %xmm1, %k1
+; AVX512BF16-NEXT:    vmovsd %xmm0, %xmm2, %xmm2 {%k1}
+; AVX512BF16-NEXT:    vmovapd %xmm2, %xmm0
+; AVX512BF16-NEXT:    retq
+;
+; AVX10_2-LABEL: test_fminimumnum_f64:
+; AVX10_2:       # %bb.0:
+; AVX10_2-NEXT:    vminmaxsd $20, %xmm1, %xmm0
+; AVX10_2-NEXT:    retq
+;
+; X86-LABEL: test_fminimumnum_f64:
+; X86:       # %bb.0:
+; X86-NEXT:    pushl %ebp
+; X86-NEXT:    movl %esp, %ebp
+; X86-NEXT:    andl $-8, %esp
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; X86-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
+; X86-NEXT:    vminsd %xmm0, %xmm1, %xmm2
+; X86-NEXT:    vandpd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1, %xmm3
+; X86-NEXT:    vorpd %xmm2, %xmm3, %xmm2
+; X86-NEXT:    vcmpunordsd %xmm1, %xmm1, %xmm3
+; X86-NEXT:    vblendvpd %xmm3, %xmm0, %xmm2, %xmm2
+; X86-NEXT:    vcmpunordsd %xmm0, %xmm0, %xmm0
+; X86-NEXT:    vblendvpd %xmm0, %xmm1, %xmm2, %xmm0
+; X86-NEXT:    vmovlpd %xmm0, (%esp)
+; X86-NEXT:    fldl (%esp)
+; X86-NEXT:    movl %ebp, %esp
+; X86-NEXT:    popl %ebp
+; X86-NEXT:    retl
+  %r = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %r
+}
+
 define <2 x double> @test_fminimumnum_scalarize(<2 x double> %x, <2 x double> %y) {
 ; SSE2-LABEL: test_fminimumnum_scalarize:
 ; SSE2:       # %bb.0:
@@ -827,26 +1068,38 @@ define float @test_fminimumnum_combine_cmps(float %x, float %y) nounwind {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    divss %xmm0, %xmm1
 ; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    minss %xmm1, %xmm2
+; SSE2-NEXT:    cmpunordss %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm2, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    movaps %xmm0, %xmm4
+; SSE2-NEXT:    minss %xmm1, %xmm4
 ; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    orps %xmm4, %xmm0
+; SS...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/218645


More information about the llvm-branch-commits mailing list