[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