[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