[llvm] Allow MIN/MAX signedness flip when operands are known-negative (PR #174469)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 11 06:31:32 PST 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/174469

>From fd650e79844ff6bfbb508b73aa6eca7817633086 Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Mon, 5 Jan 2026 19:16:26 +0000
Subject: [PATCH 1/6] Allow MIN/MAX signedness flip when operands are
 known-negative

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 40 +++++++++-----
 .../X86/dagcombine-iminmax-knownsign.ll       | 52 +++++++++++++++++++
 2 files changed, 80 insertions(+), 12 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 74d00317c3649..2c7a61385e020 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6204,26 +6204,42 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
   if (SDValue RMINMAX = reassociateOps(Opcode, DL, N0, N1, N->getFlags()))
     return RMINMAX;
 
-  // Is sign bits are zero, flip between UMIN/UMAX and SMIN/SMAX.
+  // If both operands are known to have the same sign (both non-negative or both
+  // negative), flip between UMIN/UMAX and SMIN/SMAX.
   // Only do this if:
   // 1. The current op isn't legal and the flipped is.
   // 2. The saturation pattern is broken by canonicalization in InstCombine.
   bool IsOpIllegal = !TLI.isOperationLegal(Opcode, VT);
   bool IsSatBroken = Opcode == ISD::UMIN && N0.getOpcode() == ISD::SMAX;
-  if ((IsSatBroken || IsOpIllegal) && (N0.isUndef() || DAG.SignBitIsZero(N0)) &&
-      (N1.isUndef() || DAG.SignBitIsZero(N1))) {
-    unsigned AltOpcode;
-    switch (Opcode) {
-    case ISD::SMIN: AltOpcode = ISD::UMIN; break;
-    case ISD::SMAX: AltOpcode = ISD::UMAX; break;
-    case ISD::UMIN: AltOpcode = ISD::SMIN; break;
-    case ISD::UMAX: AltOpcode = ISD::SMAX; break;
-    default: llvm_unreachable("Unknown MINMAX opcode");
+
+  if (IsSatBroken || IsOpIllegal) {
+    auto HasKnownSameSign = [&](SDValue A, SDValue B) {
+      if (A.isUndef() || B.isUndef())
+        return true;
+
+      KnownBits KA = DAG.computeKnownBits(A);
+      KnownBits KB = DAG.computeKnownBits(B);
+
+      return (KA.isNonNegative() && KB.isNonNegative()) ||
+            (KA.isNegative() && KB.isNegative());
+    };
+
+    if (HasKnownSameSign(N0, N1)) {
+      unsigned AltOpcode;
+      switch (Opcode) {
+      case ISD::SMIN: AltOpcode = ISD::UMIN; break;
+      case ISD::SMAX: AltOpcode = ISD::UMAX; break;
+      case ISD::UMIN: AltOpcode = ISD::SMIN; break;
+      case ISD::UMAX: AltOpcode = ISD::SMAX; break;
+      default: llvm_unreachable("Unknown MINMAX opcode");
+      }
+
+      if ((IsSatBroken && IsOpIllegal) || TLI.isOperationLegal(AltOpcode, VT))
+        return DAG.getNode(AltOpcode, DL, VT, N0, N1);
     }
-    if ((IsSatBroken && IsOpIllegal) || TLI.isOperationLegal(AltOpcode, VT))
-      return DAG.getNode(AltOpcode, DL, VT, N0, N1);
   }
 
+
   if (Opcode == ISD::SMIN || Opcode == ISD::SMAX)
     if (SDValue S = PerformMinMaxFpToSatCombine(
             N0, N1, N0, N1, Opcode == ISD::SMIN ? ISD::SETLT : ISD::SETGT, DAG))
diff --git a/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll b/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll
new file mode 100644
index 0000000000000..71298b5c38b90
--- /dev/null
+++ b/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll
@@ -0,0 +1,52 @@
+; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse2,-sse4.1 < %s | FileCheck %s
+
+declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
+
+define <16 x i8> @smax_both_negative(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: smax_both_negative:
+; CHECK: pmaxub
+  %mask0 = insertelement <16 x i8> poison, i8 -128, i64 0
+  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
+                        <16 x i32> zeroinitializer
+  %a1 = or <16 x i8> %a, %mask
+  %b1 = or <16 x i8> %b, %mask
+  %r = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a1, <16 x i8> %b1)
+  ret <16 x i8> %r
+}
+
+define <16 x i8> @smin_both_negative(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: smin_both_negative:
+; CHECK: pminub
+  %mask0 = insertelement <16 x i8> poison, i8 -128, i64 0
+  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
+                        <16 x i32> zeroinitializer
+  %a1 = or <16 x i8> %a, %mask
+  %b1 = or <16 x i8> %b, %mask
+  %r = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a1, <16 x i8> %b1)
+  ret <16 x i8> %r
+}
+
+define <16 x i8> @smax_both_nonnegative(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: smax_both_nonnegative:
+; CHECK: pmaxub
+  %mask0 = insertelement <16 x i8> poison, i8 127, i64 0
+  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
+                        <16 x i32> zeroinitializer
+  %a1 = and <16 x i8> %a, %mask
+  %b1 = and <16 x i8> %b, %mask
+  %r = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a1, <16 x i8> %b1)
+  ret <16 x i8> %r
+}
+
+define <16 x i8> @smin_both_nonnegative(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: smin_both_nonnegative:
+; CHECK: pminub
+  %mask0 = insertelement <16 x i8> poison, i8 127, i64 0
+  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
+                        <16 x i32> zeroinitializer
+  %a1 = and <16 x i8> %a, %mask
+  %b1 = and <16 x i8> %b, %mask
+  %r = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a1, <16 x i8> %b1)
+  ret <16 x i8> %r
+}

>From 301c24ee6c4aad4a04217f84f247b83facb6f8f6 Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Mon, 5 Jan 2026 21:06:24 +0000
Subject: [PATCH 2/6] avoid redundant computeKnownBits calls when operand sign
 cannot be proven in visitIMINMAX

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 2c7a61385e020..06afb0f45901f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6218,10 +6218,13 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
         return true;
 
       KnownBits KA = DAG.computeKnownBits(A);
-      KnownBits KB = DAG.computeKnownBits(B);
+      if (!KA.isNonNegative() && !KA.isNegative())
+        return false;
 
-      return (KA.isNonNegative() && KB.isNonNegative()) ||
-            (KA.isNegative() && KB.isNegative());
+      KnownBits KB = DAG.computeKnownBits(B);
+      if (KA.isNonNegative())
+        return KB.isNonNegative();
+      return KB.isNegative();
     };
 
     if (HasKnownSameSign(N0, N1)) {

>From 34d7f9a84a0c80222edff22fecfd25768b1acedf Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Mon, 5 Jan 2026 23:02:31 +0000
Subject: [PATCH 3/6] add getOppositeSignednessMinMaxOpcode

---
 llvm/include/llvm/CodeGen/ISDOpcodes.h         |  5 +++++
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp  | 10 +---------
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 +++++++++++++++
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 27a9019a258f8..8fce76f021ec0 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1612,6 +1612,11 @@ inline bool isBitwiseLogicOp(unsigned Opcode) {
 /// ISD::(U|S)MAX and ISD::(U|S)MIN, respectively.
 LLVM_ABI NodeType getInverseMinMaxOpcode(unsigned MinMaxOpc);
 
+/// Given a \p MinMaxOpc of ISD::(U|S)MIN or ISD::(U|S)MAX, returns the
+/// corresponding opcode with the opposite signedness:
+/// ISD::SMIN <-> ISD::UMIN, ISD::SMAX <-> ISD::UMAX.
+LLVM_ABI NodeType getOppositeSignednessMinMaxOpcode(unsigned MinMaxOpc);
+
 /// Get underlying scalar opcode for VECREDUCE opcode.
 /// For example ISD::AND for ISD::VECREDUCE_AND.
 LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode);
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 06afb0f45901f..608845e690a32 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6228,15 +6228,7 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
     };
 
     if (HasKnownSameSign(N0, N1)) {
-      unsigned AltOpcode;
-      switch (Opcode) {
-      case ISD::SMIN: AltOpcode = ISD::UMIN; break;
-      case ISD::SMAX: AltOpcode = ISD::UMAX; break;
-      case ISD::UMIN: AltOpcode = ISD::SMIN; break;
-      case ISD::UMAX: AltOpcode = ISD::SMAX; break;
-      default: llvm_unreachable("Unknown MINMAX opcode");
-      }
-
+      unsigned AltOpcode = ISD::getOppositeSignednessMinMaxOpcode(Opcode);
       if ((IsSatBroken && IsOpIllegal) || TLI.isOperationLegal(AltOpcode, VT))
         return DAG.getNode(AltOpcode, DL, VT, N0, N1);
     }
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index da43ae3b28d70..c99718f520029 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -433,6 +433,21 @@ ISD::NodeType ISD::getInverseMinMaxOpcode(unsigned MinMaxOpc) {
   }
 }
 
+ISD::NodeType ISD::getOppositeSignednessMinMaxOpcode(unsigned MinMaxOpc) {
+  switch (MinMaxOpc) {
+  default:
+    llvm_unreachable("unrecognized min/max opcode");
+  case ISD::SMIN:
+    return ISD::UMIN;
+  case ISD::SMAX:
+    return ISD::UMAX;
+  case ISD::UMIN:
+    return ISD::SMIN;
+  case ISD::UMAX:
+    return ISD::SMAX;
+  }
+}
+
 ISD::NodeType ISD::getVecReduceBaseOpcode(unsigned VecReduceOpcode) {
   switch (VecReduceOpcode) {
   default:

>From ce04e497ec2d91738e745829cb8ebb7d72cf1d35 Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Mon, 5 Jan 2026 23:05:51 +0000
Subject: [PATCH 4/6] run fmt

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 608845e690a32..b4587adf42275 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6234,7 +6234,6 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
     }
   }
 
-
   if (Opcode == ISD::SMIN || Opcode == ISD::SMAX)
     if (SDValue S = PerformMinMaxFpToSatCombine(
             N0, N1, N0, N1, Opcode == ISD::SMIN ? ISD::SETLT : ISD::SETGT, DAG))

>From e7323463358377b4dc31b14a2061285e622702a0 Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Tue, 6 Jan 2026 16:30:51 +0000
Subject: [PATCH 5/6] remove file test, extend existing ones

---
 llvm/test/CodeGen/X86/combine-smax.ll         | 22 ++++++++
 llvm/test/CodeGen/X86/combine-smin.ll         | 22 ++++++++
 .../X86/dagcombine-iminmax-knownsign.ll       | 52 -------------------
 3 files changed, 44 insertions(+), 52 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll

diff --git a/llvm/test/CodeGen/X86/combine-smax.ll b/llvm/test/CodeGen/X86/combine-smax.ll
index 0133827b85cae..16cc29ac5af76 100644
--- a/llvm/test/CodeGen/X86/combine-smax.ll
+++ b/llvm/test/CodeGen/X86/combine-smax.ll
@@ -66,6 +66,28 @@ define <16 x i8> @test_v16i8_nosignbit(<16 x i8> %a, <16 x i8> %b) {
   ret <16 x i8> %4
 }
 
+define <16 x i8> @test_v16i8_knownnegative(<16 x i8> %a, <16 x i8> %b) {
+; SSE2-LABEL: test_v16i8_knownnegative:
+; SSE2:       pmaxub
+;
+; SSE41-LABEL: test_v16i8_knownnegative:
+; SSE41:       pmaxsb
+;
+; SSE42-LABEL: test_v16i8_knownnegative:
+; SSE42:       pmaxsb
+;
+; AVX1-LABEL: test_v16i8_knownnegative:
+; AVX1:        vpmaxsb
+;
+; AVX2-LABEL: test_v16i8_knownnegative:
+; AVX2:        vpmaxsb
+  %1 = or <16 x i8> %a, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
+  %2 = or <16 x i8> %b, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
+  %3 = icmp sgt <16 x i8> %1, %2
+  %4 = select <16 x i1> %3, <16 x i8> %1, <16 x i8> %2
+  ret <16 x i8> %4
+}
+
 define <16 x i8> @test_v16i8_reassociation(<16 x i8> %a) {
 ; SSE2-LABEL: test_v16i8_reassociation:
 ; SSE2:       # %bb.0:
diff --git a/llvm/test/CodeGen/X86/combine-smin.ll b/llvm/test/CodeGen/X86/combine-smin.ll
index b58934256a209..d942e9aeed5a0 100644
--- a/llvm/test/CodeGen/X86/combine-smin.ll
+++ b/llvm/test/CodeGen/X86/combine-smin.ll
@@ -66,6 +66,28 @@ define <16 x i8> @test_v16i8_nosignbit(<16 x i8> %a, <16 x i8> %b) {
   ret <16 x i8> %4
 }
 
+define <16 x i8> @test_v16i8_knownnegative(<16 x i8> %a, <16 x i8> %b) {
+; SSE2-LABEL: test_v16i8_knownnegative:
+; SSE2:       pminub
+;
+; SSE41-LABEL: test_v16i8_knownnegative:
+; SSE41:       pminsb
+;
+; SSE42-LABEL: test_v16i8_knownnegative:
+; SSE42:       pminsb
+;
+; AVX1-LABEL: test_v16i8_knownnegative:
+; AVX1:        vpminsb
+;
+; AVX2-LABEL: test_v16i8_knownnegative:
+; AVX2:        vpminsb
+  %1 = or <16 x i8> %a, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
+  %2 = or <16 x i8> %b, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
+  %3 = icmp slt <16 x i8> %1, %2
+  %4 = select <16 x i1> %3, <16 x i8> %1, <16 x i8> %2
+  ret <16 x i8> %4
+}
+
 define <16 x i8> @test_v16i8_reassociation(<16 x i8> %a) {
 ; SSE2-LABEL: test_v16i8_reassociation:
 ; SSE2:       # %bb.0:
diff --git a/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll b/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll
deleted file mode 100644
index 71298b5c38b90..0000000000000
--- a/llvm/test/CodeGen/X86/dagcombine-iminmax-knownsign.ll
+++ /dev/null
@@ -1,52 +0,0 @@
-; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse2,-sse4.1 < %s | FileCheck %s
-
-declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
-declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
-
-define <16 x i8> @smax_both_negative(<16 x i8> %a, <16 x i8> %b) {
-; CHECK-LABEL: smax_both_negative:
-; CHECK: pmaxub
-  %mask0 = insertelement <16 x i8> poison, i8 -128, i64 0
-  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
-                        <16 x i32> zeroinitializer
-  %a1 = or <16 x i8> %a, %mask
-  %b1 = or <16 x i8> %b, %mask
-  %r = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a1, <16 x i8> %b1)
-  ret <16 x i8> %r
-}
-
-define <16 x i8> @smin_both_negative(<16 x i8> %a, <16 x i8> %b) {
-; CHECK-LABEL: smin_both_negative:
-; CHECK: pminub
-  %mask0 = insertelement <16 x i8> poison, i8 -128, i64 0
-  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
-                        <16 x i32> zeroinitializer
-  %a1 = or <16 x i8> %a, %mask
-  %b1 = or <16 x i8> %b, %mask
-  %r = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a1, <16 x i8> %b1)
-  ret <16 x i8> %r
-}
-
-define <16 x i8> @smax_both_nonnegative(<16 x i8> %a, <16 x i8> %b) {
-; CHECK-LABEL: smax_both_nonnegative:
-; CHECK: pmaxub
-  %mask0 = insertelement <16 x i8> poison, i8 127, i64 0
-  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
-                        <16 x i32> zeroinitializer
-  %a1 = and <16 x i8> %a, %mask
-  %b1 = and <16 x i8> %b, %mask
-  %r = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a1, <16 x i8> %b1)
-  ret <16 x i8> %r
-}
-
-define <16 x i8> @smin_both_nonnegative(<16 x i8> %a, <16 x i8> %b) {
-; CHECK-LABEL: smin_both_nonnegative:
-; CHECK: pminub
-  %mask0 = insertelement <16 x i8> poison, i8 127, i64 0
-  %mask = shufflevector <16 x i8> %mask0, <16 x i8> poison,
-                        <16 x i32> zeroinitializer
-  %a1 = and <16 x i8> %a, %mask
-  %b1 = and <16 x i8> %b, %mask
-  %r = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a1, <16 x i8> %b1)
-  ret <16 x i8> %r
-}

>From d8e942a433e8113644c1b833d037b43dcb0a8a05 Mon Sep 17 00:00:00 2001
From: fabioaugur <fabio at augurinitiative.ai>
Date: Tue, 6 Jan 2026 17:47:34 +0000
Subject: [PATCH 6/6] run update llc test checks on updated tests

---
 llvm/test/CodeGen/X86/combine-smax.ll | 35 +++++++++++++++++++++++----
 llvm/test/CodeGen/X86/combine-smin.ll | 35 +++++++++++++++++++++++----
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/llvm/test/CodeGen/X86/combine-smax.ll b/llvm/test/CodeGen/X86/combine-smax.ll
index 16cc29ac5af76..e6f85d31d1997 100644
--- a/llvm/test/CodeGen/X86/combine-smax.ll
+++ b/llvm/test/CodeGen/X86/combine-smax.ll
@@ -68,19 +68,44 @@ define <16 x i8> @test_v16i8_nosignbit(<16 x i8> %a, <16 x i8> %b) {
 
 define <16 x i8> @test_v16i8_knownnegative(<16 x i8> %a, <16 x i8> %b) {
 ; SSE2-LABEL: test_v16i8_knownnegative:
-; SSE2:       pmaxub
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE2-NEXT:    por %xmm2, %xmm0
+; SSE2-NEXT:    por %xmm1, %xmm2
+; SSE2-NEXT:    pmaxub %xmm2, %xmm0
+; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: test_v16i8_knownnegative:
-; SSE41:       pmaxsb
+; SSE41:       # %bb.0:
+; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE41-NEXT:    por %xmm2, %xmm0
+; SSE41-NEXT:    por %xmm1, %xmm2
+; SSE41-NEXT:    pmaxsb %xmm2, %xmm0
+; SSE41-NEXT:    retq
 ;
 ; SSE42-LABEL: test_v16i8_knownnegative:
-; SSE42:       pmaxsb
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE42-NEXT:    por %xmm2, %xmm0
+; SSE42-NEXT:    por %xmm1, %xmm2
+; SSE42-NEXT:    pmaxsb %xmm2, %xmm0
+; SSE42-NEXT:    retq
 ;
 ; AVX1-LABEL: test_v16i8_knownnegative:
-; AVX1:        vpmaxsb
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX1-NEXT:    vpor %xmm2, %xmm0, %xmm0
+; AVX1-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; AVX1-NEXT:    vpmaxsb %xmm1, %xmm0, %xmm0
+; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_v16i8_knownnegative:
-; AVX2:        vpmaxsb
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX2-NEXT:    vpor %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vpmaxsb %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    retq
   %1 = or <16 x i8> %a, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
   %2 = or <16 x i8> %b, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
   %3 = icmp sgt <16 x i8> %1, %2
diff --git a/llvm/test/CodeGen/X86/combine-smin.ll b/llvm/test/CodeGen/X86/combine-smin.ll
index d942e9aeed5a0..4e3482ae1f2bb 100644
--- a/llvm/test/CodeGen/X86/combine-smin.ll
+++ b/llvm/test/CodeGen/X86/combine-smin.ll
@@ -68,19 +68,44 @@ define <16 x i8> @test_v16i8_nosignbit(<16 x i8> %a, <16 x i8> %b) {
 
 define <16 x i8> @test_v16i8_knownnegative(<16 x i8> %a, <16 x i8> %b) {
 ; SSE2-LABEL: test_v16i8_knownnegative:
-; SSE2:       pminub
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE2-NEXT:    por %xmm2, %xmm0
+; SSE2-NEXT:    por %xmm1, %xmm2
+; SSE2-NEXT:    pminub %xmm2, %xmm0
+; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: test_v16i8_knownnegative:
-; SSE41:       pminsb
+; SSE41:       # %bb.0:
+; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE41-NEXT:    por %xmm2, %xmm0
+; SSE41-NEXT:    por %xmm1, %xmm2
+; SSE41-NEXT:    pminsb %xmm2, %xmm0
+; SSE41-NEXT:    retq
 ;
 ; SSE42-LABEL: test_v16i8_knownnegative:
-; SSE42:       pminsb
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE42-NEXT:    por %xmm2, %xmm0
+; SSE42-NEXT:    por %xmm1, %xmm2
+; SSE42-NEXT:    pminsb %xmm2, %xmm0
+; SSE42-NEXT:    retq
 ;
 ; AVX1-LABEL: test_v16i8_knownnegative:
-; AVX1:        vpminsb
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX1-NEXT:    vpor %xmm2, %xmm0, %xmm0
+; AVX1-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; AVX1-NEXT:    vpminsb %xmm1, %xmm0, %xmm0
+; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_v16i8_knownnegative:
-; AVX2:        vpminsb
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX2-NEXT:    vpor %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vpminsb %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    retq
   %1 = or <16 x i8> %a, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
   %2 = or <16 x i8> %b, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128>
   %3 = icmp slt <16 x i8> %1, %2



More information about the llvm-commits mailing list