[llvm] [X86] Fix fcmp+select to min/max lowering (PR #185594)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 12 03:33:14 PDT 2026


https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/185594

>From 5fc2720123966f6e2f784174ffd6f92d35359492 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 9 Mar 2026 16:13:52 +0100
Subject: [PATCH] [X86] Fix fcmp+select to min/max lowering

This does a few changes that are hard to separate from each other:
 * Consider forming minnum/maxnum from setcc+select non-profitable.
   X86 has instructions specifically for the setcc+select pattern.
 * Reduce duplication in the code for forming FMIN/FMAX, by using
   predicate inversion (to make setcc and select operand order
   match) and predicate invswap (to canonicalize to ordered
   predicates). This leaves us with just ordered and NaN-less
   predicates.
 * For non-strict non-less predicates, convert them to strict
   ones via invswap (i.e. swapping the operands of both the setcc
   and select). Previously this just treated them the same as
   strict predicates, but I believe that's incorrect in terms of
   signed zero handling.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 175 +++++-------------
 llvm/lib/Target/X86/X86ISelLowering.h         |   6 +
 llvm/test/CodeGen/X86/avx-minmax.ll           |  16 +-
 .../CodeGen/X86/avx512-broadcast-unfold.ll    |  60 +++---
 llvm/test/CodeGen/X86/sse-minmax-finite.ll    | 120 ++++++------
 llvm/test/CodeGen/X86/sse-minmax.ll           |  22 ++-
 6 files changed, 164 insertions(+), 235 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index aacca810c527a..a813bd39f8ee0 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -48242,137 +48242,60 @@ static SDValue combineSelectToMinMax(SelectionDAG &DAG,
   SDValue Op0 = Cond.getOperand(IsStrict ? 1 : 0);
   SDValue Op1 = Cond.getOperand(IsStrict ? 2 : 1);
 
-  unsigned Opcode = 0;
   // Check for x CC y ? x : y.
-  if (DAG.isEqualTo(LHS, Op0) && DAG.isEqualTo(RHS, Op1)) {
-    switch (CC) {
-    default:
-      break;
-    case ISD::SETULT:
-      // Converting this to a min would handle NaNs incorrectly, and swapping
-      // the operands would cause it to handle comparisons between positive
-      // and negative zero incorrectly.
-      if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
-        if (!N->getFlags().hasNoSignedZeros() &&
-            !(DAG.isKnownNeverZeroFloat(LHS) || DAG.isKnownNeverZeroFloat(RHS)))
-          break;
-        std::swap(LHS, RHS);
-      }
-      Opcode = X86ISD::FMIN;
-      break;
-    case ISD::SETOLE:
-      // Converting this to a min would handle comparisons between positive
-      // and negative zero incorrectly.
-      if (!N->getFlags().hasNoSignedZeros() &&
-          !DAG.isKnownNeverZeroFloat(LHS) && !DAG.isKnownNeverZeroFloat(RHS))
-        break;
-      Opcode = X86ISD::FMIN;
-      break;
-    case ISD::SETULE:
-      // Converting this to a min would handle both negative zeros and NaNs
-      // incorrectly, but we can swap the operands to fix both.
-      std::swap(LHS, RHS);
-      [[fallthrough]];
-    case ISD::SETOLT:
-    case ISD::SETLT:
-    case ISD::SETLE:
-      Opcode = X86ISD::FMIN;
-      break;
+  if (!DAG.isEqualTo(LHS, Op0) || !DAG.isEqualTo(RHS, Op1)) {
+    if (!DAG.isEqualTo(LHS, Op1) || !DAG.isEqualTo(RHS, Op0))
+      return SDValue();
 
-    case ISD::SETOGE:
-      // Converting this to a max would handle comparisons between positive
-      // and negative zero incorrectly.
-      if (!N->getFlags().hasNoSignedZeros() &&
-          !DAG.isKnownNeverZeroFloat(LHS) && !DAG.isKnownNeverZeroFloat(RHS))
-        break;
-      Opcode = X86ISD::FMAX;
-      break;
-    case ISD::SETUGT:
-      // Converting this to a max would handle NaNs incorrectly, and swapping
-      // the operands would cause it to handle comparisons between positive
-      // and negative zero incorrectly.
-      if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
-        if (!N->getFlags().hasNoSignedZeros() &&
-            !(DAG.isKnownNeverZeroFloat(LHS) || DAG.isKnownNeverZeroFloat(RHS)))
-          break;
-        std::swap(LHS, RHS);
-      }
-      Opcode = X86ISD::FMAX;
-      break;
-    case ISD::SETUGE:
-      // Converting this to a max would handle both negative zeros and NaNs
-      // incorrectly, but we can swap the operands to fix both.
-      std::swap(LHS, RHS);
-      [[fallthrough]];
-    case ISD::SETOGT:
-    case ISD::SETGT:
-    case ISD::SETGE:
-      Opcode = X86ISD::FMAX;
-      break;
-    }
-    // Check for x CC y ? y : x -- a min/max with reversed arms.
-  } else if (DAG.isEqualTo(LHS, Op1) && DAG.isEqualTo(RHS, Op0)) {
-    switch (CC) {
-    default:
-      break;
-    case ISD::SETOGE:
-      // Converting this to a min would handle comparisons between positive
-      // and negative zero incorrectly, and swapping the operands would
-      // cause it to handle NaNs incorrectly.
-      if (!N->getFlags().hasNoSignedZeros() &&
-          !(DAG.isKnownNeverZeroFloat(LHS) || DAG.isKnownNeverZeroFloat(RHS))) {
-        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
-          break;
-        std::swap(LHS, RHS);
-      }
-      Opcode = X86ISD::FMIN;
-      break;
-    case ISD::SETUGT:
-      // Converting this to a min would handle NaNs incorrectly.
-      if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
-        break;
-      Opcode = X86ISD::FMIN;
-      break;
-    case ISD::SETUGE:
-      // Converting this to a min would handle both negative zeros and NaNs
-      // incorrectly, but we can swap the operands to fix both.
-      std::swap(LHS, RHS);
-      [[fallthrough]];
-    case ISD::SETOGT:
-    case ISD::SETGT:
-    case ISD::SETGE:
-      Opcode = X86ISD::FMIN;
-      break;
+    // Convert x CC y ? y : x to x inv(CC) y ? x : y.
+    CC = ISD::getSetCCInverse(CC, VT);
+    std::swap(LHS, RHS);
+  }
 
-    case ISD::SETULT:
-      // Converting this to a max would handle NaNs incorrectly.
-      if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
-        break;
-      Opcode = X86ISD::FMAX;
-      break;
-    case ISD::SETOLE:
-      // Converting this to a max would handle comparisons between positive
-      // and negative zero incorrectly, and swapping the operands would
-      // cause it to handle NaNs incorrectly.
-      if (!N->getFlags().hasNoSignedZeros() &&
-          !DAG.isKnownNeverZeroFloat(LHS) && !DAG.isKnownNeverZeroFloat(RHS)) {
-        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
-          break;
-        std::swap(LHS, RHS);
-      }
-      Opcode = X86ISD::FMAX;
+  // Convert x CC y ? x : y to y swap(inv(CC)) x ? y : x
+  // to convert an unordered into an ordered comparison.
+  if (ISD::getUnorderedFlavor(CC) == 1) {
+    CC = ISD::getSetCCSwappedOperands(ISD::getSetCCInverse(CC, VT));
+    std::swap(LHS, RHS);
+  }
+
+  unsigned Opcode = 0;
+  switch (CC) {
+  default:
+    break;
+  case ISD::SETOLE:
+    // Converting this to a min would handle comparisons between positive
+    // and negative zero incorrectly.
+    if (!N->getFlags().hasNoSignedZeros() && !DAG.isKnownNeverZeroFloat(LHS) &&
+        !DAG.isKnownNeverZeroFloat(RHS))
       break;
-    case ISD::SETULE:
-      // Converting this to a max would handle both negative zeros and NaNs
-      // incorrectly, but we can swap the operands to fix both.
-      std::swap(LHS, RHS);
-      [[fallthrough]];
-    case ISD::SETOLT:
-    case ISD::SETLT:
-    case ISD::SETLE:
-      Opcode = X86ISD::FMAX;
+    Opcode = X86ISD::FMIN;
+    break;
+  case ISD::SETLE:
+    // Convert setle to setlt via inv+swap.
+    std::swap(LHS, RHS);
+    [[fallthrough]];
+  case ISD::SETOLT:
+  case ISD::SETLT:
+    Opcode = X86ISD::FMIN;
+    break;
+
+  case ISD::SETOGE:
+    // Converting this to a max would handle comparisons between positive
+    // and negative zero incorrectly.
+    if (!N->getFlags().hasNoSignedZeros() && !DAG.isKnownNeverZeroFloat(LHS) &&
+        !DAG.isKnownNeverZeroFloat(RHS))
       break;
-    }
+    Opcode = X86ISD::FMAX;
+    break;
+  case ISD::SETGE:
+    // Convert setge to setgt via inv+swap.
+    std::swap(LHS, RHS);
+    [[fallthrough]];
+  case ISD::SETOGT:
+  case ISD::SETGT:
+    Opcode = X86ISD::FMAX;
+    break;
   }
 
   if (!Opcode)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 620efd8bf19d3..5c7c54cacd239 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -599,6 +599,12 @@ namespace llvm {
                                  const SelectionDAG &DAG,
                                  const MachineMemOperand &MMO) const override;
 
+    bool isProfitableToCombineMinNumMaxNum(EVT VT) const override {
+      // X86 has instructions that correspond to cmp + select, so forming
+      // minnum/maxnum is not profitable.
+      return false;
+    }
+
     Register getRegisterByName(const char* RegName, LLT VT,
                                const MachineFunction &MF) const override;
 
diff --git a/llvm/test/CodeGen/X86/avx-minmax.ll b/llvm/test/CodeGen/X86/avx-minmax.ll
index 27864a9eefa8e..58b36ba0e4ac5 100644
--- a/llvm/test/CodeGen/X86/avx-minmax.ll
+++ b/llvm/test/CodeGen/X86/avx-minmax.ll
@@ -4,7 +4,7 @@
 define <2 x double> @maxpd(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: maxpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vmaxpd %xmm1, %xmm0, %xmm0
+; CHECK-NEXT:    vmaxpd %xmm0, %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <2 x double> %x, %y
   %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
@@ -14,7 +14,7 @@ define <2 x double> @maxpd(<2 x double> %x, <2 x double> %y) {
 define <2 x double> @minpd(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: minpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vminpd %xmm1, %xmm0, %xmm0
+; CHECK-NEXT:    vminpd %xmm0, %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <2 x double> %x, %y
   %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
@@ -24,7 +24,7 @@ define <2 x double> @minpd(<2 x double> %x, <2 x double> %y) {
 define <4 x float> @maxps(<4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: maxps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
+; CHECK-NEXT:    vmaxps %xmm0, %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <4 x float> %x, %y
   %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y
@@ -34,7 +34,7 @@ define <4 x float> @maxps(<4 x float> %x, <4 x float> %y) {
 define <4 x float> @minps(<4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: minps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vminps %xmm1, %xmm0, %xmm0
+; CHECK-NEXT:    vminps %xmm0, %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <4 x float> %x, %y
   %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y
@@ -44,7 +44,7 @@ define <4 x float> @minps(<4 x float> %x, <4 x float> %y) {
 define <4 x double> @vmaxpd(<4 x double> %x, <4 x double> %y) {
 ; CHECK-LABEL: vmaxpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vmaxpd %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vmaxpd %ymm0, %ymm1, %ymm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <4 x double> %x, %y
   %max = select <4 x i1> %max_is_x, <4 x double> %x, <4 x double> %y
@@ -54,7 +54,7 @@ define <4 x double> @vmaxpd(<4 x double> %x, <4 x double> %y) {
 define <4 x double> @vminpd(<4 x double> %x, <4 x double> %y) {
 ; CHECK-LABEL: vminpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vminpd %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vminpd %ymm0, %ymm1, %ymm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <4 x double> %x, %y
   %min = select <4 x i1> %min_is_x, <4 x double> %x, <4 x double> %y
@@ -64,7 +64,7 @@ define <4 x double> @vminpd(<4 x double> %x, <4 x double> %y) {
 define <8 x float> @vmaxps(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: vmaxps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vmaxps %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vmaxps %ymm0, %ymm1, %ymm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <8 x float> %x, %y
   %max = select <8 x i1> %max_is_x, <8 x float> %x, <8 x float> %y
@@ -74,7 +74,7 @@ define <8 x float> @vmaxps(<8 x float> %x, <8 x float> %y) {
 define <8 x float> @vminps(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: vminps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vminps %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vminps %ymm0, %ymm1, %ymm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <8 x float> %x, %y
   %min = select <8 x i1> %min_is_x, <8 x float> %x, <8 x float> %y
diff --git a/llvm/test/CodeGen/X86/avx512-broadcast-unfold.ll b/llvm/test/CodeGen/X86/avx512-broadcast-unfold.ll
index 4f1ba8d35e5f1..2f86499a2df9e 100644
--- a/llvm/test/CodeGen/X86/avx512-broadcast-unfold.ll
+++ b/llvm/test/CodeGen/X86/avx512-broadcast-unfold.ll
@@ -1974,9 +1974,8 @@ define void @bcast_unfold_fmax_v4f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB60_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %xmm1
-; CHECK-NEXT:    vmaxps %xmm0, %xmm1, %xmm1
-; CHECK-NEXT:    vmovups %xmm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltps 4096(%rdi,%rax), %xmm0, %k1
+; CHECK-NEXT:    vmovups %xmm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $16, %rax
 ; CHECK-NEXT:    jne .LBB60_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2007,9 +2006,8 @@ define void @bcast_unfold_fmax_v8f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB61_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %ymm1
-; CHECK-NEXT:    vmaxps %ymm0, %ymm1, %ymm1
-; CHECK-NEXT:    vmovups %ymm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltps 4096(%rdi,%rax), %ymm0, %k1
+; CHECK-NEXT:    vmovups %ymm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $32, %rax
 ; CHECK-NEXT:    jne .LBB61_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2041,9 +2039,8 @@ define void @bcast_unfold_fmax_v16f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB62_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %zmm1
-; CHECK-NEXT:    vmaxps %zmm0, %zmm1, %zmm1
-; CHECK-NEXT:    vmovups %zmm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltps 4096(%rdi,%rax), %zmm0, %k1
+; CHECK-NEXT:    vmovups %zmm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $64, %rax
 ; CHECK-NEXT:    jne .LBB62_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2076,9 +2073,8 @@ define void @bcast_unfold_fmax_v2f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB63_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %xmm1
-; CHECK-NEXT:    vmaxpd %xmm0, %xmm1, %xmm1
-; CHECK-NEXT:    vmovupd %xmm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltpd 8192(%rdi,%rax), %xmm0, %k1
+; CHECK-NEXT:    vmovupd %xmm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $16, %rax
 ; CHECK-NEXT:    jne .LBB63_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2109,9 +2105,8 @@ define void @bcast_unfold_fmax_v4f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB64_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %ymm1
-; CHECK-NEXT:    vmaxpd %ymm0, %ymm1, %ymm1
-; CHECK-NEXT:    vmovupd %ymm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltpd 8192(%rdi,%rax), %ymm0, %k1
+; CHECK-NEXT:    vmovupd %ymm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $32, %rax
 ; CHECK-NEXT:    jne .LBB64_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2143,9 +2138,8 @@ define void @bcast_unfold_fmax_v8f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB65_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %zmm1
-; CHECK-NEXT:    vmaxpd %zmm0, %zmm1, %zmm1
-; CHECK-NEXT:    vmovupd %zmm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpnltpd 8192(%rdi,%rax), %zmm0, %k1
+; CHECK-NEXT:    vmovupd %zmm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $64, %rax
 ; CHECK-NEXT:    jne .LBB65_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2177,9 +2171,8 @@ define void @bcast_unfold_fmin_v4f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB66_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %xmm1
-; CHECK-NEXT:    vminps %xmm0, %xmm1, %xmm1
-; CHECK-NEXT:    vmovups %xmm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtps 4096(%rdi,%rax), %xmm0, %k1
+; CHECK-NEXT:    vmovups %xmm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $16, %rax
 ; CHECK-NEXT:    jne .LBB66_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2210,9 +2203,8 @@ define void @bcast_unfold_fmin_v8f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB67_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %ymm1
-; CHECK-NEXT:    vminps %ymm0, %ymm1, %ymm1
-; CHECK-NEXT:    vmovups %ymm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtps 4096(%rdi,%rax), %ymm0, %k1
+; CHECK-NEXT:    vmovups %ymm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $32, %rax
 ; CHECK-NEXT:    jne .LBB67_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2244,9 +2236,8 @@ define void @bcast_unfold_fmin_v16f32(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB68_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovups 4096(%rdi,%rax), %zmm1
-; CHECK-NEXT:    vminps %zmm0, %zmm1, %zmm1
-; CHECK-NEXT:    vmovups %zmm1, 4096(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtps 4096(%rdi,%rax), %zmm0, %k1
+; CHECK-NEXT:    vmovups %zmm0, 4096(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $64, %rax
 ; CHECK-NEXT:    jne .LBB68_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2279,9 +2270,8 @@ define void @bcast_unfold_fmin_v2f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB69_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %xmm1
-; CHECK-NEXT:    vminpd %xmm0, %xmm1, %xmm1
-; CHECK-NEXT:    vmovupd %xmm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtpd 8192(%rdi,%rax), %xmm0, %k1
+; CHECK-NEXT:    vmovupd %xmm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $16, %rax
 ; CHECK-NEXT:    jne .LBB69_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2312,9 +2302,8 @@ define void @bcast_unfold_fmin_v4f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB70_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %ymm1
-; CHECK-NEXT:    vminpd %ymm0, %ymm1, %ymm1
-; CHECK-NEXT:    vmovupd %ymm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtpd 8192(%rdi,%rax), %ymm0, %k1
+; CHECK-NEXT:    vmovupd %ymm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $32, %rax
 ; CHECK-NEXT:    jne .LBB70_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
@@ -2346,9 +2335,8 @@ define void @bcast_unfold_fmin_v8f64(ptr %arg) {
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  .LBB71_1: # %bb1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    vmovupd 8192(%rdi,%rax), %zmm1
-; CHECK-NEXT:    vminpd %zmm0, %zmm1, %zmm1
-; CHECK-NEXT:    vmovupd %zmm1, 8192(%rdi,%rax)
+; CHECK-NEXT:    vcmpngtpd 8192(%rdi,%rax), %zmm0, %k1
+; CHECK-NEXT:    vmovupd %zmm0, 8192(%rdi,%rax) {%k1}
 ; CHECK-NEXT:    addq $64, %rax
 ; CHECK-NEXT:    jne .LBB71_1
 ; CHECK-NEXT:  # %bb.2: # %bb10
diff --git a/llvm/test/CodeGen/X86/sse-minmax-finite.ll b/llvm/test/CodeGen/X86/sse-minmax-finite.ll
index 469637964d849..0dff5296a8e51 100644
--- a/llvm/test/CodeGen/X86/sse-minmax-finite.ll
+++ b/llvm/test/CodeGen/X86/sse-minmax-finite.ll
@@ -56,7 +56,8 @@ define double @olt_inverse(double %x, double %y)  {
 define double @oge(double %x, double %y)  {
 ; CHECK-LABEL: oge:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, %y
   %d = select i1 %c, double %x, double %y
@@ -66,7 +67,8 @@ define double @oge(double %x, double %y)  {
 define double @ole(double %x, double %y)  {
 ; CHECK-LABEL: ole:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, %y
   %d = select i1 %c, double %x, double %y
@@ -80,8 +82,7 @@ define double @oge_inverse(double %x, double %y)  {
 ; RELAX-NEXT:    retq
 ; CHECK-LABEL: oge_inverse:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, %y
   %d = select i1 %c, double %y, double %x
@@ -95,8 +96,7 @@ define double @ole_inverse(double %x, double %y)  {
 ; RELAX-NEXT:    retq
 ; CHECK-LABEL: ole_inverse:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, %y
   %d = select i1 %c, double %y, double %x
@@ -153,7 +153,8 @@ define double @oge_x(double %x)  {
 ; CHECK-LABEL: oge_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    maxsd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, 0.000000e+00
   %d = select i1 %c, double %x, double 0.000000e+00
@@ -164,7 +165,8 @@ define double @ole_x(double %x)  {
 ; CHECK-LABEL: ole_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    minsd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, 0.000000e+00
   %d = select i1 %c, double %x, double 0.000000e+00
@@ -180,8 +182,7 @@ define double @oge_inverse_x(double %x)  {
 ; CHECK-LABEL: oge_inverse_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -197,8 +198,7 @@ define double @ole_inverse_x(double %x)  {
 ; CHECK-LABEL: ole_inverse_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -258,7 +258,8 @@ define double @ult_inverse(double %x, double %y)  {
 define double @uge(double %x, double %y)  {
 ; CHECK-LABEL: uge:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, %y
   %d = select i1 %c, double %x, double %y
@@ -268,7 +269,8 @@ define double @uge(double %x, double %y)  {
 define double @ule(double %x, double %y)  {
 ; CHECK-LABEL: ule:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, %y
   %d = select i1 %c, double %x, double %y
@@ -278,8 +280,7 @@ define double @ule(double %x, double %y)  {
 define double @uge_inverse(double %x, double %y)  {
 ; CHECK-LABEL: uge_inverse:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, %y
   %d = select i1 %c, double %y, double %x
@@ -289,8 +290,7 @@ define double @uge_inverse(double %x, double %y)  {
 define double @ule_inverse(double %x, double %y)  {
 ; CHECK-LABEL: ule_inverse:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, %y
   %d = select i1 %c, double %y, double %x
@@ -357,7 +357,8 @@ define double @uge_x(double %x)  {
 ; CHECK-LABEL: uge_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    maxsd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, 0.000000e+00
   %d = select i1 %c, double %x, double 0.000000e+00
@@ -368,7 +369,8 @@ define double @ule_x(double %x)  {
 ; CHECK-LABEL: ule_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    minsd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, 0.000000e+00
   %d = select i1 %c, double %x, double 0.000000e+00
@@ -379,8 +381,7 @@ define double @uge_inverse_x(double %x)  {
 ; CHECK-LABEL: uge_inverse_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -391,8 +392,7 @@ define double @ule_inverse_x(double %x)  {
 ; CHECK-LABEL: ule_inverse_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -446,7 +446,9 @@ define double @olt_inverse_y(double %x)  {
 define double @oge_y(double %x)  {
 ; CHECK-LABEL: oge_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, -0.000000e+00
   %d = select i1 %c, double %x, double -0.000000e+00
@@ -456,7 +458,9 @@ define double @oge_y(double %x)  {
 define double @ole_y(double %x)  {
 ; CHECK-LABEL: ole_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, -0.000000e+00
   %d = select i1 %c, double %x, double -0.000000e+00
@@ -470,9 +474,7 @@ define double @oge_inverse_y(double %x)  {
 ; RELAX-NEXT:    retq
 ; CHECK-LABEL: oge_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan oge double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x
@@ -486,9 +488,7 @@ define double @ole_inverse_y(double %x)  {
 ; RELAX-NEXT:    retq
 ; CHECK-LABEL: ole_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ole double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x
@@ -550,7 +550,9 @@ define double @ult_inverse_y(double %x)  {
 define double @uge_y(double %x)  {
 ; CHECK-LABEL: uge_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
+; CHECK-NEXT:    maxsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, -0.000000e+00
   %d = select i1 %c, double %x, double -0.000000e+00
@@ -560,7 +562,9 @@ define double @uge_y(double %x)  {
 define double @ule_y(double %x)  {
 ; CHECK-LABEL: ule_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
+; CHECK-NEXT:    minsd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, -0.000000e+00
   %d = select i1 %c, double %x, double -0.000000e+00
@@ -570,9 +574,7 @@ define double @ule_y(double %x)  {
 define double @uge_inverse_y(double %x)  {
 ; CHECK-LABEL: uge_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan uge double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x
@@ -582,9 +584,7 @@ define double @uge_inverse_y(double %x)  {
 define double @ule_inverse_y(double %x)  {
 ; CHECK-LABEL: ule_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0]
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp nnan ule double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x
@@ -608,9 +608,7 @@ define double @clampTo3k_a(double %x)  {
 define double @clampTo3k_b(double %x)  {
 ; CHECK-LABEL: clampTo3k_b:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0]
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %t0 = fcmp nnan uge double %x, 3.000000e+03
   %y = select i1 %t0, double 3.000000e+03, double %x
@@ -632,9 +630,7 @@ define double @clampTo3k_c(double %x)  {
 define double @clampTo3k_d(double %x)  {
 ; CHECK-LABEL: clampTo3k_d:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0]
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %t0 = fcmp nnan ule double %x, 3.000000e+03
   %y = select i1 %t0, double 3.000000e+03, double %x
@@ -656,9 +652,7 @@ define double @clampTo3k_e(double %x)  {
 define double @clampTo3k_f(double %x)  {
 ; CHECK-LABEL: clampTo3k_f:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0]
-; CHECK-NEXT:    maxsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %t0 = fcmp nnan ule double %x, 3.000000e+03
   %y = select i1 %t0, double 3.000000e+03, double %x
@@ -680,9 +674,7 @@ define double @clampTo3k_g(double %x)  {
 define double @clampTo3k_h(double %x)  {
 ; CHECK-LABEL: clampTo3k_h:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0]
-; CHECK-NEXT:    minsd %xmm0, %xmm1
-; CHECK-NEXT:    movapd %xmm1, %xmm0
+; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %t0 = fcmp nnan uge double %x, 3.000000e+03
   %y = select i1 %t0, double 3.000000e+03, double %x
@@ -692,7 +684,8 @@ define double @clampTo3k_h(double %x)  {
 define <2 x double> @test_maxpd(<2 x double> %x, <2 x double> %y)  {
 ; CHECK-LABEL: test_maxpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxpd %xmm1, %xmm0
+; CHECK-NEXT:    maxpd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <2 x double> %x, %y
   %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
@@ -702,7 +695,8 @@ define <2 x double> @test_maxpd(<2 x double> %x, <2 x double> %y)  {
 define <2 x double> @test_minpd(<2 x double> %x, <2 x double> %y)  {
 ; CHECK-LABEL: test_minpd:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minpd %xmm1, %xmm0
+; CHECK-NEXT:    minpd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <2 x double> %x, %y
   %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
@@ -712,7 +706,8 @@ define <2 x double> @test_minpd(<2 x double> %x, <2 x double> %y)  {
 define <4 x float> @test_maxps(<4 x float> %x, <4 x float> %y)  {
 ; CHECK-LABEL: test_maxps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxps %xmm1, %xmm0
+; CHECK-NEXT:    maxps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <4 x float> %x, %y
   %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y
@@ -722,7 +717,8 @@ define <4 x float> @test_maxps(<4 x float> %x, <4 x float> %y)  {
 define <4 x float> @test_minps(<4 x float> %x, <4 x float> %y)  {
 ; CHECK-LABEL: test_minps:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minps %xmm1, %xmm0
+; CHECK-NEXT:    minps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <4 x float> %x, %y
   %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y
@@ -732,7 +728,8 @@ define <4 x float> @test_minps(<4 x float> %x, <4 x float> %y)  {
 define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
 ; CHECK-LABEL: test_maxps_illegal_v2f32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxps %xmm1, %xmm0
+; CHECK-NEXT:    maxps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <2 x float> %x, %y
   %max = select <2 x i1> %max_is_x, <2 x float> %x, <2 x float> %y
@@ -742,7 +739,8 @@ define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
 define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
 ; CHECK-LABEL: test_minps_illegal_v2f32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minps %xmm1, %xmm0
+; CHECK-NEXT:    minps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <2 x float> %x, %y
   %min = select <2 x i1> %min_is_x, <2 x float> %x, <2 x float> %y
@@ -752,7 +750,8 @@ define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
 define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y)  {
 ; CHECK-LABEL: test_maxps_illegal_v3f32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxps %xmm1, %xmm0
+; CHECK-NEXT:    maxps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %max_is_x = fcmp nnan oge <3 x float> %x, %y
   %max = select <3 x i1> %max_is_x, <3 x float> %x, <3 x float> %y
@@ -762,7 +761,8 @@ define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y)  {
 define <3 x float> @test_minps_illegal_v3f32(<3 x float> %x, <3 x float> %y)  {
 ; CHECK-LABEL: test_minps_illegal_v3f32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minps %xmm1, %xmm0
+; CHECK-NEXT:    minps %xmm0, %xmm1
+; CHECK-NEXT:    movaps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %min_is_x = fcmp nnan ole <3 x float> %x, %y
   %min = select <3 x i1> %min_is_x, <3 x float> %x, <3 x float> %y
diff --git a/llvm/test/CodeGen/X86/sse-minmax.ll b/llvm/test/CodeGen/X86/sse-minmax.ll
index c1fb1c6b87a23..2b97f98450973 100644
--- a/llvm/test/CodeGen/X86/sse-minmax.ll
+++ b/llvm/test/CodeGen/X86/sse-minmax.ll
@@ -365,8 +365,11 @@ define double @ult_x(double %x)  {
 define double @ugt_inverse_x(double %x)  {
 ; CHECK-LABEL: ugt_inverse_x:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    minsd %xmm1, %xmm0
+; CHECK-NEXT:    xorpd %xmm2, %xmm2
+; CHECK-NEXT:    movapd %xmm0, %xmm1
+; CHECK-NEXT:    cmpnlesd %xmm2, %xmm1
+; CHECK-NEXT:    andnpd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp ugt double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -377,7 +380,9 @@ define double @ult_inverse_x(double %x)  {
 ; CHECK-LABEL: ult_inverse_x:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    maxsd %xmm1, %xmm0
+; CHECK-NEXT:    cmpnlesd %xmm0, %xmm1
+; CHECK-NEXT:    andnpd %xmm0, %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp ult double %x, 0.000000e+00
   %d = select i1 %c, double 0.000000e+00, double %x
@@ -578,7 +583,10 @@ define double @ult_y(double %x)  {
 define double @ugt_inverse_y(double %x)  {
 ; CHECK-LABEL: ugt_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movapd %xmm0, %xmm1
+; CHECK-NEXT:    cmpnlesd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    blendvpd %xmm0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp ugt double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x
@@ -588,7 +596,11 @@ define double @ugt_inverse_y(double %x)  {
 define double @ult_inverse_y(double %x)  {
 ; CHECK-LABEL: ult_inverse_y:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movapd %xmm0, %xmm1
+; CHECK-NEXT:    movsd {{.*#+}} xmm0 = [-0.0E+0,0.0E+0]
+; CHECK-NEXT:    cmpnlesd %xmm1, %xmm0
+; CHECK-NEXT:    blendvpd %xmm0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; CHECK-NEXT:    movapd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = fcmp ult double %x, -0.000000e+00
   %d = select i1 %c, double -0.000000e+00, double %x



More information about the llvm-commits mailing list