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 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
