[llvm-branch-commits] [llvm] release/23.x: [X86] combineShiftRightLogical - fold srl(vecreduce_umax(x), bw-1) as MOVMSK signbit reduction (#210281) (PR #210740)

Douglas Yung via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 22 06:54:47 PDT 2026


https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/210740

>From 2cb2b2979ca4ad0c8d2b836e687d82fbb75723db Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 20 Jul 2026 13:04:22 +0100
Subject: [PATCH] [X86] combineShiftRightLogical - fold
 srl(vecreduce_umax(x),bw-1) as MOVMSK signbit reduction (#210281)

VectorCombine may have folded:
  icmp_eq(vecreduce_or(splatsign(x)),0) --> icmp_sgt(vecreduce_umax(x),-1)

which DAG folds to:
  srl(vecreduce_umax(x),bw-1).

This match attempts to lower:
  srl(vecreduce_umax(x),bw-1) --> icmp_ne(movmsk(x),0) "any_of negative"
  srl(not(vecreduce_umax(x)),bw-1) --> icmp_eq(movmsk(x),0) "none_of negative"

The correct fix would be to improve vecreduce_or costs to prevent
VectorCombine doing this, but that change is far too big to be merged
into 23.x - so I've created the narrow backend fix.

Fixes #209714

(cherry picked from commit 8abc26930cf9ee0f059228acdbd1d22cd1c325e3)
---
 llvm/lib/Target/X86/X86ISelLowering.cpp |   32 +
 llvm/test/CodeGen/X86/pr209714.ll       | 1407 +++++++++++++++++++++++
 2 files changed, 1439 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/pr209714.ll

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d3fff2d4b54e2..f651dba18be8f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -50910,6 +50910,38 @@ static SDValue combineShiftRightLogical(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  // VectorCombine may have folded:
+  // icmp_eq(vecreduce_or(splatsign(x)),0) --> icmp_sgt(vecreduce_umax(x),-1)
+  // which DAG folds to: srl(vecreduce_umax(x),bw-1).
+  // This attempts to reconstruct the signbit reduction.
+  if (sd_match(N1, m_SpecificInt(EltSizeInBits - 1))) {
+    SDValue X = N0;
+    ISD::CondCode CC = ISD::SETNE;
+    if (sd_match(N0, m_Not(m_Value(X))))
+      CC = ISD::SETEQ;
+    if (X.getOpcode() == ISD::VECREDUCE_UMAX) {
+      SDValue V = X.getOperand(0);
+      EVT VecVT = V.getValueType();
+      if (DAG.getTargetLoweringInfo().isTypeLegal(VecVT) &&
+          VecVT.getScalarSizeInBits() >= 8) {
+        if (VecVT.is512BitVector()) {
+          auto [Lo, Hi] = DAG.SplitVector(V, DL);
+          V = DAG.getNode(ISD::OR, DL, Lo.getValueType(), Lo, Hi);
+          VecVT = V.getValueType();
+        }
+        if (VecVT == MVT::v16i16) {
+          auto [Lo, Hi] = DAG.SplitVector(V, DL);
+          V = DAG.getNode(X86ISD::PACKSS, DL, MVT::v16i8, Lo, Hi);
+        } else if (VecVT == MVT::v8i16) {
+          V = DAG.getNode(X86ISD::PACKSS, DL, MVT::v16i8, V, V);
+        }
+        V = getPMOVMSKB(DL, V, DAG, Subtarget);
+        V = DAG.getSetCC(DL, MVT::i8, V, DAG.getConstant(0, DL, MVT::i32), CC);
+        return DAG.getZExtOrTrunc(V, DL, VT);
+      }
+    }
+  }
+
   // Only do this on the last DAG combine as it can interfere with other
   // combines.
   if (!DCI.isAfterLegalizeDAG())
diff --git a/llvm/test/CodeGen/X86/pr209714.ll b/llvm/test/CodeGen/X86/pr209714.ll
new file mode 100644
index 0000000000000..9a487696bb847
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr209714.ll
@@ -0,0 +1,1407 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686--   -mattr=+sse2     | FileCheck %s --check-prefixes=X86-SSE,X86-SSE2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2     | FileCheck %s --check-prefixes=X64-SSE,X64-SSE2
+; RUN: llc < %s -mtriple=i686--   -mattr=+sse4.1   | FileCheck %s --check-prefixes=X86-SSE,X86-SSE4,X86-SSE41
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1   | FileCheck %s --check-prefixes=X64-SSE,X64-SSE4
+; RUN: llc < %s -mtriple=i686--   -mattr=+sse4.2   | FileCheck %s --check-prefixes=X86-SSE,X86-SSE4,X86-SSE42
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.2   | FileCheck %s --check-prefixes=X64-SSE,X64-SSE4
+; RUN: llc < %s -mtriple=i686--   -mattr=+avx      | FileCheck %s --check-prefixes=X86-AVX,X86-AVX1
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx      | FileCheck %s --check-prefixes=X64-AVX,X64-AVX1
+; RUN: llc < %s -mtriple=i686--   -mattr=+avx2     | FileCheck %s --check-prefixes=X86-AVX,X86-AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2     | FileCheck %s --check-prefixes=X64-AVX,X64-AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512bw | FileCheck %s --check-prefixes=AVX512,AVX512BW
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512bw,+avx512dq,+avx512vl | FileCheck %s --check-prefixes=AVX512,AVX512BWVL
+
+; Ensure umax reductions which only demand the signbit correctly fold to MOVSMSK/TESTP style patterns.
+
+define i8 @reduce_umax_v16i8_signbit(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v16i8_signbit:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE-NEXT:    pand (%eax), %xmm0
+; X86-SSE-NEXT:    pmovmskb %xmm0, %eax
+; X86-SSE-NEXT:    testl %eax, %eax
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v16i8_signbit:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movdqa (%rsi), %xmm0
+; X64-SSE-NEXT:    pand (%rdi), %xmm0
+; X64-SSE-NEXT:    pmovmskb %xmm0, %eax
+; X64-SSE-NEXT:    testl %eax, %eax
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v16i8_signbit:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    vmovdqa (%ecx), %xmm0
+; X86-AVX-NEXT:    vpand (%eax), %xmm0, %xmm0
+; X86-AVX-NEXT:    vpmovmskb %xmm0, %eax
+; X86-AVX-NEXT:    testl %eax, %eax
+; X86-AVX-NEXT:    sete %al
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v16i8_signbit:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovdqa (%rsi), %xmm0
+; X64-AVX-NEXT:    vpand (%rdi), %xmm0, %xmm0
+; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
+; X64-AVX-NEXT:    testl %eax, %eax
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v16i8_signbit:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa (%rsi), %xmm0
+; AVX512-NEXT:    vpand (%rdi), %xmm0, %xmm0
+; AVX512-NEXT:    vpmovmskb %xmm0, %eax
+; AVX512-NEXT:    testl %eax, %eax
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    retq
+  %a = load <16 x i8>, ptr %pa
+  %b = load <16 x i8>, ptr %pb
+  %and = and <16 x i8> %b, %a
+  %rdx = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %and)
+  %cmp = icmp sgt i8 %rdx, -1
+  %res = zext i1 %cmp to i8
+  ret i8 %res
+}
+
+define i16 @reduce_umax_v8i16_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v8i16_signbit_not:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE-NEXT:    pandn (%eax), %xmm0
+; X86-SSE-NEXT:    packsswb %xmm0, %xmm0
+; X86-SSE-NEXT:    pmovmskb %xmm0, %ecx
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    testl %ecx, %ecx
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v8i16_signbit_not:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movdqa (%rdi), %xmm0
+; X64-SSE-NEXT:    pandn (%rsi), %xmm0
+; X64-SSE-NEXT:    packsswb %xmm0, %xmm0
+; X64-SSE-NEXT:    pmovmskb %xmm0, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v8i16_signbit_not:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    vmovdqa (%ecx), %xmm0
+; X86-AVX-NEXT:    vpandn (%eax), %xmm0, %xmm0
+; X86-AVX-NEXT:    vpacksswb %xmm0, %xmm0, %xmm0
+; X86-AVX-NEXT:    vpmovmskb %xmm0, %ecx
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    testl %ecx, %ecx
+; X86-AVX-NEXT:    sete %al
+; X86-AVX-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v8i16_signbit_not:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovdqa (%rdi), %xmm0
+; X64-AVX-NEXT:    vpandn (%rsi), %xmm0, %xmm0
+; X64-AVX-NEXT:    vpacksswb %xmm0, %xmm0, %xmm0
+; X64-AVX-NEXT:    vpmovmskb %xmm0, %ecx
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    testl %ecx, %ecx
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v8i16_signbit_not:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa (%rdi), %xmm0
+; AVX512-NEXT:    vpandn (%rsi), %xmm0, %xmm0
+; AVX512-NEXT:    vpacksswb %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vpmovmskb %xmm0, %ecx
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    testl %ecx, %ecx
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX512-NEXT:    retq
+  %a = load <8 x i16>, ptr %pa
+  %b = load <8 x i16>, ptr %pb
+  %a.not = xor <8 x i16> %a, splat (i16 -1)
+  %and = and <8 x i16> %b, %a.not
+  %rdx = call i16 @llvm.vector.reduce.umax.v8i16(<8 x i16> %and)
+  %cmp = icmp sgt i16 %rdx, -1
+  %res = zext i1 %cmp to i16
+  ret i16 %res
+}
+
+define i32 @reduce_umax_v4i32_signbit(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v4i32_signbit:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movaps (%ecx), %xmm0
+; X86-SSE-NEXT:    andps (%eax), %xmm0
+; X86-SSE-NEXT:    movmskps %xmm0, %ecx
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    testl %ecx, %ecx
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v4i32_signbit:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movaps (%rsi), %xmm0
+; X64-SSE-NEXT:    andps (%rdi), %xmm0
+; X64-SSE-NEXT:    movmskps %xmm0, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v4i32_signbit:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    vmovaps (%eax), %xmm0
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    vtestps (%ecx), %xmm0
+; X86-AVX-NEXT:    sete %al
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v4i32_signbit:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovaps (%rdi), %xmm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestps (%rsi), %xmm0
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v4i32_signbit:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovaps (%rdi), %xmm0
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    vtestps (%rsi), %xmm0
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    retq
+  %a = load <4 x i32>, ptr %pa
+  %b = load <4 x i32>, ptr %pb
+  %and = and <4 x i32> %b, %a
+  %rdx = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %and)
+  %cmp = icmp sgt i32 %rdx, -1
+  %res = zext i1 %cmp to i32
+  ret i32 %res
+}
+
+define i64 @reduce_umax_v2i64_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v2i64_signbit_not:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movapd (%ecx), %xmm0
+; X86-SSE-NEXT:    andnpd (%eax), %xmm0
+; X86-SSE-NEXT:    movmskpd %xmm0, %ecx
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    testl %ecx, %ecx
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    xorl %edx, %edx
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v2i64_signbit_not:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movapd (%rdi), %xmm0
+; X64-SSE-NEXT:    andnpd (%rsi), %xmm0
+; X64-SSE-NEXT:    movmskpd %xmm0, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v2i64_signbit_not:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    vmovapd (%eax), %xmm0
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    vtestpd (%ecx), %xmm0
+; X86-AVX-NEXT:    setb %al
+; X86-AVX-NEXT:    xorl %edx, %edx
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v2i64_signbit_not:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovapd (%rdi), %xmm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestpd (%rsi), %xmm0
+; X64-AVX-NEXT:    setb %al
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v2i64_signbit_not:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovapd (%rdi), %xmm0
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    vtestpd (%rsi), %xmm0
+; AVX512-NEXT:    setb %al
+; AVX512-NEXT:    retq
+  %a = load <2 x i64>, ptr %pa
+  %b = load <2 x i64>, ptr %pb
+  %a.not = xor <2 x i64> %a, splat (i64 -1)
+  %and = and <2 x i64> %b, %a.not
+  %rdx = call i64 @llvm.vector.reduce.umax.v2i64(<2 x i64> %and)
+  %cmp = icmp sgt i64 %rdx, -1
+  %res = zext i1 %cmp to i64
+  ret i64 %res
+}
+
+define i8 @reduce_umax_v32i8_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v32i8_signbit_not:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE-NEXT:    pandn 16(%eax), %xmm1
+; X86-SSE-NEXT:    pandn (%eax), %xmm0
+; X86-SSE-NEXT:    por %xmm1, %xmm0
+; X86-SSE-NEXT:    pmovmskb %xmm0, %eax
+; X86-SSE-NEXT:    testl %eax, %eax
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v32i8_signbit_not:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movdqa (%rdi), %xmm0
+; X64-SSE-NEXT:    movdqa 16(%rdi), %xmm1
+; X64-SSE-NEXT:    pandn 16(%rsi), %xmm1
+; X64-SSE-NEXT:    pandn (%rsi), %xmm0
+; X64-SSE-NEXT:    por %xmm1, %xmm0
+; X64-SSE-NEXT:    pmovmskb %xmm0, %eax
+; X64-SSE-NEXT:    testl %eax, %eax
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX1-LABEL: reduce_umax_v32i8_signbit_not:
+; X86-AVX1:       # %bb.0:
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX1-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX1-NEXT:    vandnps (%eax), %ymm0, %ymm0
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; X86-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vpmovmskb %xmm0, %eax
+; X86-AVX1-NEXT:    testl %eax, %eax
+; X86-AVX1-NEXT:    sete %al
+; X86-AVX1-NEXT:    vzeroupper
+; X86-AVX1-NEXT:    retl
+;
+; X64-AVX1-LABEL: reduce_umax_v32i8_signbit_not:
+; X64-AVX1:       # %bb.0:
+; X64-AVX1-NEXT:    vmovaps (%rdi), %ymm0
+; X64-AVX1-NEXT:    vandnps (%rsi), %ymm0, %ymm0
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; X64-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
+; X64-AVX1-NEXT:    testl %eax, %eax
+; X64-AVX1-NEXT:    sete %al
+; X64-AVX1-NEXT:    vzeroupper
+; X64-AVX1-NEXT:    retq
+;
+; X86-AVX2-LABEL: reduce_umax_v32i8_signbit_not:
+; X86-AVX2:       # %bb.0:
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX2-NEXT:    vmovdqa (%ecx), %ymm0
+; X86-AVX2-NEXT:    vpandn (%eax), %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpmovmskb %ymm0, %eax
+; X86-AVX2-NEXT:    testl %eax, %eax
+; X86-AVX2-NEXT:    sete %al
+; X86-AVX2-NEXT:    vzeroupper
+; X86-AVX2-NEXT:    retl
+;
+; X64-AVX2-LABEL: reduce_umax_v32i8_signbit_not:
+; X64-AVX2:       # %bb.0:
+; X64-AVX2-NEXT:    vmovdqa (%rdi), %ymm0
+; X64-AVX2-NEXT:    vpandn (%rsi), %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
+; X64-AVX2-NEXT:    testl %eax, %eax
+; X64-AVX2-NEXT:    sete %al
+; X64-AVX2-NEXT:    vzeroupper
+; X64-AVX2-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v32i8_signbit_not:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa (%rdi), %ymm0
+; AVX512-NEXT:    vpandn (%rsi), %ymm0, %ymm0
+; AVX512-NEXT:    vpmovmskb %ymm0, %eax
+; AVX512-NEXT:    testl %eax, %eax
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <32 x i8>, ptr %pa
+  %b = load <32 x i8>, ptr %pb
+  %a.not = xor <32 x i8> %a, splat (i8 -1)
+  %and = and <32 x i8> %b, %a.not
+  %rdx = call i8 @llvm.vector.reduce.umax.v32i8(<32 x i8> %and)
+  %cmp = icmp sgt i8 %rdx, -1
+  %res = zext i1 %cmp to i8
+  ret i8 %res
+}
+
+define i16 @reduce_umax_v16i16_signbit(ptr %pa, ptr %pb) {
+; X86-SSE2-LABEL: reduce_umax_v16i16_signbit:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE2-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE2-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE2-NEXT:    pand (%eax), %xmm0
+; X86-SSE2-NEXT:    pand 16(%eax), %xmm1
+; X86-SSE2-NEXT:    psubusw %xmm0, %xmm1
+; X86-SSE2-NEXT:    paddw %xmm0, %xmm1
+; X86-SSE2-NEXT:    packsswb %xmm1, %xmm1
+; X86-SSE2-NEXT:    pmovmskb %xmm1, %ecx
+; X86-SSE2-NEXT:    xorl %eax, %eax
+; X86-SSE2-NEXT:    testl %ecx, %ecx
+; X86-SSE2-NEXT:    sete %al
+; X86-SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE2-LABEL: reduce_umax_v16i16_signbit:
+; X64-SSE2:       # %bb.0:
+; X64-SSE2-NEXT:    movdqa (%rsi), %xmm0
+; X64-SSE2-NEXT:    movdqa 16(%rsi), %xmm1
+; X64-SSE2-NEXT:    pand (%rdi), %xmm0
+; X64-SSE2-NEXT:    pand 16(%rdi), %xmm1
+; X64-SSE2-NEXT:    psubusw %xmm0, %xmm1
+; X64-SSE2-NEXT:    paddw %xmm0, %xmm1
+; X64-SSE2-NEXT:    packsswb %xmm1, %xmm1
+; X64-SSE2-NEXT:    pmovmskb %xmm1, %ecx
+; X64-SSE2-NEXT:    xorl %eax, %eax
+; X64-SSE2-NEXT:    testl %ecx, %ecx
+; X64-SSE2-NEXT:    sete %al
+; X64-SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-SSE2-NEXT:    retq
+;
+; X86-SSE4-LABEL: reduce_umax_v16i16_signbit:
+; X86-SSE4:       # %bb.0:
+; X86-SSE4-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE4-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE4-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE4-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE4-NEXT:    pand 16(%eax), %xmm1
+; X86-SSE4-NEXT:    pand (%eax), %xmm0
+; X86-SSE4-NEXT:    pmaxuw %xmm1, %xmm0
+; X86-SSE4-NEXT:    packsswb %xmm0, %xmm0
+; X86-SSE4-NEXT:    pmovmskb %xmm0, %ecx
+; X86-SSE4-NEXT:    xorl %eax, %eax
+; X86-SSE4-NEXT:    testl %ecx, %ecx
+; X86-SSE4-NEXT:    sete %al
+; X86-SSE4-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE4-NEXT:    retl
+;
+; X64-SSE4-LABEL: reduce_umax_v16i16_signbit:
+; X64-SSE4:       # %bb.0:
+; X64-SSE4-NEXT:    movdqa (%rsi), %xmm0
+; X64-SSE4-NEXT:    movdqa 16(%rsi), %xmm1
+; X64-SSE4-NEXT:    pand 16(%rdi), %xmm1
+; X64-SSE4-NEXT:    pand (%rdi), %xmm0
+; X64-SSE4-NEXT:    pmaxuw %xmm1, %xmm0
+; X64-SSE4-NEXT:    packsswb %xmm0, %xmm0
+; X64-SSE4-NEXT:    pmovmskb %xmm0, %ecx
+; X64-SSE4-NEXT:    xorl %eax, %eax
+; X64-SSE4-NEXT:    testl %ecx, %ecx
+; X64-SSE4-NEXT:    sete %al
+; X64-SSE4-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-SSE4-NEXT:    retq
+;
+; X86-AVX1-LABEL: reduce_umax_v16i16_signbit:
+; X86-AVX1:       # %bb.0:
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX1-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX1-NEXT:    vandps (%eax), %ymm0, %ymm0
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; X86-AVX1-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
+; X86-AVX1-NEXT:    xorl %eax, %eax
+; X86-AVX1-NEXT:    testl %ecx, %ecx
+; X86-AVX1-NEXT:    sete %al
+; X86-AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-AVX1-NEXT:    vzeroupper
+; X86-AVX1-NEXT:    retl
+;
+; X64-AVX1-LABEL: reduce_umax_v16i16_signbit:
+; X64-AVX1:       # %bb.0:
+; X64-AVX1-NEXT:    vmovaps (%rsi), %ymm0
+; X64-AVX1-NEXT:    vandps (%rdi), %ymm0, %ymm0
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; X64-AVX1-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
+; X64-AVX1-NEXT:    xorl %eax, %eax
+; X64-AVX1-NEXT:    testl %ecx, %ecx
+; X64-AVX1-NEXT:    sete %al
+; X64-AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX1-NEXT:    vzeroupper
+; X64-AVX1-NEXT:    retq
+;
+; X86-AVX2-LABEL: reduce_umax_v16i16_signbit:
+; X86-AVX2:       # %bb.0:
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX2-NEXT:    vmovdqa (%ecx), %ymm0
+; X86-AVX2-NEXT:    vpand (%eax), %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
+; X86-AVX2-NEXT:    xorl %eax, %eax
+; X86-AVX2-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X86-AVX2-NEXT:    sete %al
+; X86-AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-AVX2-NEXT:    vzeroupper
+; X86-AVX2-NEXT:    retl
+;
+; X64-AVX2-LABEL: reduce_umax_v16i16_signbit:
+; X64-AVX2:       # %bb.0:
+; X64-AVX2-NEXT:    vmovdqa (%rsi), %ymm0
+; X64-AVX2-NEXT:    vpand (%rdi), %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
+; X64-AVX2-NEXT:    xorl %eax, %eax
+; X64-AVX2-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X64-AVX2-NEXT:    sete %al
+; X64-AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX2-NEXT:    vzeroupper
+; X64-AVX2-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v16i16_signbit:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa (%rsi), %ymm0
+; AVX512-NEXT:    vpand (%rdi), %ymm0, %ymm0
+; AVX512-NEXT:    vpmovmskb %ymm0, %ecx
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <16 x i16>, ptr %pa
+  %b = load <16 x i16>, ptr %pb
+  %and = and <16 x i16> %b, %a
+  %rdx = call i16 @llvm.vector.reduce.umax.v16i16(<16 x i16> %and)
+  %cmp = icmp sgt i16 %rdx, -1
+  %res = zext i1 %cmp to i16
+  ret i16 %res
+}
+
+define i32 @reduce_umax_v8i32_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v8i32_signbit_not:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movaps (%ecx), %xmm0
+; X86-SSE-NEXT:    movaps 16(%ecx), %xmm1
+; X86-SSE-NEXT:    andnps 16(%eax), %xmm1
+; X86-SSE-NEXT:    andnps (%eax), %xmm0
+; X86-SSE-NEXT:    orps %xmm1, %xmm0
+; X86-SSE-NEXT:    movmskps %xmm0, %ecx
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    testl %ecx, %ecx
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v8i32_signbit_not:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movaps (%rdi), %xmm0
+; X64-SSE-NEXT:    movaps 16(%rdi), %xmm1
+; X64-SSE-NEXT:    andnps 16(%rsi), %xmm1
+; X64-SSE-NEXT:    andnps (%rsi), %xmm0
+; X64-SSE-NEXT:    orps %xmm1, %xmm0
+; X64-SSE-NEXT:    movmskps %xmm0, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v8i32_signbit_not:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    vmovaps (%eax), %ymm0
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    vtestps (%ecx), %ymm0
+; X86-AVX-NEXT:    setb %al
+; X86-AVX-NEXT:    vzeroupper
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v8i32_signbit_not:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovaps (%rdi), %ymm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestps (%rsi), %ymm0
+; X64-AVX-NEXT:    setb %al
+; X64-AVX-NEXT:    vzeroupper
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v8i32_signbit_not:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovaps (%rdi), %ymm0
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    vtestps (%rsi), %ymm0
+; AVX512-NEXT:    setb %al
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <8 x i32>, ptr %pa
+  %b = load <8 x i32>, ptr %pb
+  %a.not = xor <8 x i32> %a, splat (i32 -1)
+  %and = and <8 x i32> %b, %a.not
+  %rdx = call i32 @llvm.vector.reduce.umax.v8i32(<8 x i32> %and)
+  %cmp = icmp sgt i32 %rdx, -1
+  %res = zext i1 %cmp to i32
+  ret i32 %res
+}
+
+define i64 @reduce_umax_v4i64_signbit(ptr %pa, ptr %pb) {
+; X86-SSE2-LABEL: reduce_umax_v4i64_signbit:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE2-NEXT:    movdqa (%ecx), %xmm0
+; X86-SSE2-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE2-NEXT:    pand (%eax), %xmm0
+; X86-SSE2-NEXT:    pand 16(%eax), %xmm1
+; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
+; X86-SSE2-NEXT:    movdqa %xmm1, %xmm3
+; X86-SSE2-NEXT:    pxor %xmm2, %xmm3
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm2
+; X86-SSE2-NEXT:    movdqa %xmm2, %xmm4
+; X86-SSE2-NEXT:    pcmpgtd %xmm3, %xmm4
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
+; X86-SSE2-NEXT:    pcmpeqd %xmm3, %xmm2
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
+; X86-SSE2-NEXT:    pand %xmm5, %xmm2
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
+; X86-SSE2-NEXT:    por %xmm2, %xmm3
+; X86-SSE2-NEXT:    pand %xmm3, %xmm0
+; X86-SSE2-NEXT:    pandn %xmm1, %xmm3
+; X86-SSE2-NEXT:    por %xmm0, %xmm3
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[3,3,3,3]
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,1,1,1]
+; X86-SSE2-NEXT:    por %xmm0, %xmm1
+; X86-SSE2-NEXT:    movd %xmm1, %eax
+; X86-SSE2-NEXT:    notl %eax
+; X86-SSE2-NEXT:    shrl $31, %eax
+; X86-SSE2-NEXT:    xorl %edx, %edx
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v4i64_signbit:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movapd (%rsi), %xmm0
+; X64-SSE-NEXT:    movapd 16(%rsi), %xmm1
+; X64-SSE-NEXT:    andpd 16(%rdi), %xmm1
+; X64-SSE-NEXT:    andpd (%rdi), %xmm0
+; X64-SSE-NEXT:    orpd %xmm1, %xmm0
+; X64-SSE-NEXT:    movmskpd %xmm0, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-SSE41-LABEL: reduce_umax_v4i64_signbit:
+; X86-SSE41:       # %bb.0:
+; X86-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE41-NEXT:    movdqa (%ecx), %xmm2
+; X86-SSE41-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE41-NEXT:    pand (%eax), %xmm2
+; X86-SSE41-NEXT:    pand 16(%eax), %xmm1
+; X86-SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648,2147483648,2147483648]
+; X86-SSE41-NEXT:    movdqa %xmm1, %xmm3
+; X86-SSE41-NEXT:    pxor %xmm0, %xmm3
+; X86-SSE41-NEXT:    pxor %xmm2, %xmm0
+; X86-SSE41-NEXT:    movdqa %xmm0, %xmm4
+; X86-SSE41-NEXT:    pcmpgtd %xmm3, %xmm4
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
+; X86-SSE41-NEXT:    pcmpeqd %xmm3, %xmm0
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
+; X86-SSE41-NEXT:    pand %xmm5, %xmm3
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm4[1,1,3,3]
+; X86-SSE41-NEXT:    por %xmm3, %xmm0
+; X86-SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
+; X86-SSE41-NEXT:    por %xmm1, %xmm0
+; X86-SSE41-NEXT:    pextrd $1, %xmm0, %eax
+; X86-SSE41-NEXT:    notl %eax
+; X86-SSE41-NEXT:    shrl $31, %eax
+; X86-SSE41-NEXT:    xorl %edx, %edx
+; X86-SSE41-NEXT:    retl
+;
+; X86-SSE42-LABEL: reduce_umax_v4i64_signbit:
+; X86-SSE42:       # %bb.0:
+; X86-SSE42-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE42-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE42-NEXT:    movdqa (%ecx), %xmm2
+; X86-SSE42-NEXT:    movdqa 16(%ecx), %xmm1
+; X86-SSE42-NEXT:    pand (%eax), %xmm2
+; X86-SSE42-NEXT:    pand 16(%eax), %xmm1
+; X86-SSE42-NEXT:    movdqa {{.*#+}} xmm0 = [0,2147483648,0,2147483648]
+; X86-SSE42-NEXT:    movdqa %xmm1, %xmm3
+; X86-SSE42-NEXT:    pxor %xmm0, %xmm3
+; X86-SSE42-NEXT:    pxor %xmm2, %xmm0
+; X86-SSE42-NEXT:    pcmpgtq %xmm3, %xmm0
+; X86-SSE42-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
+; X86-SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
+; X86-SSE42-NEXT:    por %xmm1, %xmm0
+; X86-SSE42-NEXT:    pextrd $1, %xmm0, %eax
+; X86-SSE42-NEXT:    notl %eax
+; X86-SSE42-NEXT:    shrl $31, %eax
+; X86-SSE42-NEXT:    xorl %edx, %edx
+; X86-SSE42-NEXT:    retl
+;
+; X86-AVX-LABEL: reduce_umax_v4i64_signbit:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    vmovapd (%eax), %ymm0
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    vtestpd (%ecx), %ymm0
+; X86-AVX-NEXT:    sete %al
+; X86-AVX-NEXT:    xorl %edx, %edx
+; X86-AVX-NEXT:    vzeroupper
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v4i64_signbit:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovapd (%rdi), %ymm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestpd (%rsi), %ymm0
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    vzeroupper
+; X64-AVX-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v4i64_signbit:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovapd (%rdi), %ymm0
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    vtestpd (%rsi), %ymm0
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <4 x i64>, ptr %pa
+  %b = load <4 x i64>, ptr %pb
+  %and = and <4 x i64> %b, %a
+  %rdx = call i64 @llvm.vector.reduce.umax.v4i64(<4 x i64> %and)
+  %cmp = icmp sgt i64 %rdx, -1
+  %res = zext i1 %cmp to i64
+  ret i64 %res
+}
+
+define i8 @reduce_umax_v64i8_signbit(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v64i8_signbit:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movdqa 48(%ecx), %xmm0
+; X86-SSE-NEXT:    movdqa (%ecx), %xmm1
+; X86-SSE-NEXT:    movdqa 16(%ecx), %xmm2
+; X86-SSE-NEXT:    movdqa 32(%ecx), %xmm3
+; X86-SSE-NEXT:    pand 32(%eax), %xmm3
+; X86-SSE-NEXT:    pand (%eax), %xmm1
+; X86-SSE-NEXT:    por %xmm3, %xmm1
+; X86-SSE-NEXT:    pand 48(%eax), %xmm0
+; X86-SSE-NEXT:    pand 16(%eax), %xmm2
+; X86-SSE-NEXT:    por %xmm0, %xmm2
+; X86-SSE-NEXT:    por %xmm1, %xmm2
+; X86-SSE-NEXT:    pmovmskb %xmm2, %eax
+; X86-SSE-NEXT:    testl %eax, %eax
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v64i8_signbit:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movdqa (%rsi), %xmm0
+; X64-SSE-NEXT:    movdqa 16(%rsi), %xmm1
+; X64-SSE-NEXT:    movdqa 32(%rsi), %xmm2
+; X64-SSE-NEXT:    movdqa 48(%rsi), %xmm3
+; X64-SSE-NEXT:    pand 32(%rdi), %xmm2
+; X64-SSE-NEXT:    pand (%rdi), %xmm0
+; X64-SSE-NEXT:    por %xmm2, %xmm0
+; X64-SSE-NEXT:    pand 48(%rdi), %xmm3
+; X64-SSE-NEXT:    pand 16(%rdi), %xmm1
+; X64-SSE-NEXT:    por %xmm3, %xmm1
+; X64-SSE-NEXT:    por %xmm0, %xmm1
+; X64-SSE-NEXT:    pmovmskb %xmm1, %eax
+; X64-SSE-NEXT:    testl %eax, %eax
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX1-LABEL: reduce_umax_v64i8_signbit:
+; X86-AVX1:       # %bb.0:
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX1-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX1-NEXT:    vmovaps 32(%ecx), %ymm1
+; X86-AVX1-NEXT:    vandps (%eax), %ymm0, %ymm0
+; X86-AVX1-NEXT:    vandps 32(%eax), %ymm1, %ymm1
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
+; X86-AVX1-NEXT:    vorps %xmm2, %xmm3, %xmm2
+; X86-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vorps %xmm2, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vpmovmskb %xmm0, %eax
+; X86-AVX1-NEXT:    testl %eax, %eax
+; X86-AVX1-NEXT:    sete %al
+; X86-AVX1-NEXT:    vzeroupper
+; X86-AVX1-NEXT:    retl
+;
+; X64-AVX1-LABEL: reduce_umax_v64i8_signbit:
+; X64-AVX1:       # %bb.0:
+; X64-AVX1-NEXT:    vmovaps (%rsi), %ymm0
+; X64-AVX1-NEXT:    vmovaps 32(%rsi), %ymm1
+; X64-AVX1-NEXT:    vandps (%rdi), %ymm0, %ymm0
+; X64-AVX1-NEXT:    vandps 32(%rdi), %ymm1, %ymm1
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
+; X64-AVX1-NEXT:    vorps %xmm2, %xmm3, %xmm2
+; X64-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vorps %xmm2, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
+; X64-AVX1-NEXT:    testl %eax, %eax
+; X64-AVX1-NEXT:    sete %al
+; X64-AVX1-NEXT:    vzeroupper
+; X64-AVX1-NEXT:    retq
+;
+; X86-AVX2-LABEL: reduce_umax_v64i8_signbit:
+; X86-AVX2:       # %bb.0:
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX2-NEXT:    vmovdqa (%ecx), %ymm0
+; X86-AVX2-NEXT:    vmovdqa 32(%ecx), %ymm1
+; X86-AVX2-NEXT:    vpand 32(%eax), %ymm1, %ymm1
+; X86-AVX2-NEXT:    vpand (%eax), %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpmovmskb %ymm0, %eax
+; X86-AVX2-NEXT:    testl %eax, %eax
+; X86-AVX2-NEXT:    sete %al
+; X86-AVX2-NEXT:    vzeroupper
+; X86-AVX2-NEXT:    retl
+;
+; X64-AVX2-LABEL: reduce_umax_v64i8_signbit:
+; X64-AVX2:       # %bb.0:
+; X64-AVX2-NEXT:    vmovdqa (%rsi), %ymm0
+; X64-AVX2-NEXT:    vmovdqa 32(%rsi), %ymm1
+; X64-AVX2-NEXT:    vpand 32(%rdi), %ymm1, %ymm1
+; X64-AVX2-NEXT:    vpand (%rdi), %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
+; X64-AVX2-NEXT:    testl %eax, %eax
+; X64-AVX2-NEXT:    sete %al
+; X64-AVX2-NEXT:    vzeroupper
+; X64-AVX2-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v64i8_signbit:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa64 (%rsi), %zmm0
+; AVX512-NEXT:    vpandq (%rdi), %zmm0, %zmm0
+; AVX512-NEXT:    vextracti64x4 $1, %zmm0, %ymm1
+; AVX512-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; AVX512-NEXT:    vpmovmskb %ymm0, %eax
+; AVX512-NEXT:    testl %eax, %eax
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <64 x i8>, ptr %pa
+  %b = load <64 x i8>, ptr %pb
+  %and = and <64 x i8> %b, %a
+  %rdx = call i8 @llvm.vector.reduce.umax.v64i8(<64 x i8> %and)
+  %cmp = icmp sgt i8 %rdx, -1
+  %res = zext i1 %cmp to i8
+  ret i8 %res
+}
+
+define i16 @reduce_umax_v32i16_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE2-LABEL: reduce_umax_v32i16_signbit_not:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE2-NEXT:    movdqa 32(%ecx), %xmm1
+; X86-SSE2-NEXT:    movdqa 48(%ecx), %xmm0
+; X86-SSE2-NEXT:    movdqa (%ecx), %xmm2
+; X86-SSE2-NEXT:    movdqa 16(%ecx), %xmm3
+; X86-SSE2-NEXT:    pandn 16(%eax), %xmm3
+; X86-SSE2-NEXT:    pandn 48(%eax), %xmm0
+; X86-SSE2-NEXT:    pandn (%eax), %xmm2
+; X86-SSE2-NEXT:    pandn 32(%eax), %xmm1
+; X86-SSE2-NEXT:    psubusw %xmm2, %xmm1
+; X86-SSE2-NEXT:    paddw %xmm2, %xmm1
+; X86-SSE2-NEXT:    psubusw %xmm3, %xmm0
+; X86-SSE2-NEXT:    paddw %xmm3, %xmm0
+; X86-SSE2-NEXT:    psubusw %xmm1, %xmm0
+; X86-SSE2-NEXT:    paddw %xmm1, %xmm0
+; X86-SSE2-NEXT:    packsswb %xmm0, %xmm0
+; X86-SSE2-NEXT:    pmovmskb %xmm0, %ecx
+; X86-SSE2-NEXT:    xorl %eax, %eax
+; X86-SSE2-NEXT:    testl %ecx, %ecx
+; X86-SSE2-NEXT:    sete %al
+; X86-SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE2-LABEL: reduce_umax_v32i16_signbit_not:
+; X64-SSE2:       # %bb.0:
+; X64-SSE2-NEXT:    movdqa (%rdi), %xmm0
+; X64-SSE2-NEXT:    movdqa 16(%rdi), %xmm1
+; X64-SSE2-NEXT:    movdqa 32(%rdi), %xmm2
+; X64-SSE2-NEXT:    movdqa 48(%rdi), %xmm3
+; X64-SSE2-NEXT:    pandn 16(%rsi), %xmm1
+; X64-SSE2-NEXT:    pandn 48(%rsi), %xmm3
+; X64-SSE2-NEXT:    pandn (%rsi), %xmm0
+; X64-SSE2-NEXT:    pandn 32(%rsi), %xmm2
+; X64-SSE2-NEXT:    psubusw %xmm0, %xmm2
+; X64-SSE2-NEXT:    paddw %xmm0, %xmm2
+; X64-SSE2-NEXT:    psubusw %xmm1, %xmm3
+; X64-SSE2-NEXT:    paddw %xmm1, %xmm3
+; X64-SSE2-NEXT:    psubusw %xmm2, %xmm3
+; X64-SSE2-NEXT:    paddw %xmm2, %xmm3
+; X64-SSE2-NEXT:    packsswb %xmm3, %xmm3
+; X64-SSE2-NEXT:    pmovmskb %xmm3, %ecx
+; X64-SSE2-NEXT:    xorl %eax, %eax
+; X64-SSE2-NEXT:    testl %ecx, %ecx
+; X64-SSE2-NEXT:    sete %al
+; X64-SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-SSE2-NEXT:    retq
+;
+; X86-SSE4-LABEL: reduce_umax_v32i16_signbit_not:
+; X86-SSE4:       # %bb.0:
+; X86-SSE4-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE4-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE4-NEXT:    movdqa 48(%ecx), %xmm1
+; X86-SSE4-NEXT:    movdqa (%ecx), %xmm2
+; X86-SSE4-NEXT:    movdqa 16(%ecx), %xmm0
+; X86-SSE4-NEXT:    movdqa 32(%ecx), %xmm3
+; X86-SSE4-NEXT:    pandn 32(%eax), %xmm3
+; X86-SSE4-NEXT:    pandn (%eax), %xmm2
+; X86-SSE4-NEXT:    pmaxuw %xmm3, %xmm2
+; X86-SSE4-NEXT:    pandn 48(%eax), %xmm1
+; X86-SSE4-NEXT:    pandn 16(%eax), %xmm0
+; X86-SSE4-NEXT:    pmaxuw %xmm1, %xmm0
+; X86-SSE4-NEXT:    pmaxuw %xmm2, %xmm0
+; X86-SSE4-NEXT:    packsswb %xmm0, %xmm0
+; X86-SSE4-NEXT:    pmovmskb %xmm0, %ecx
+; X86-SSE4-NEXT:    xorl %eax, %eax
+; X86-SSE4-NEXT:    testl %ecx, %ecx
+; X86-SSE4-NEXT:    sete %al
+; X86-SSE4-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE4-NEXT:    retl
+;
+; X64-SSE4-LABEL: reduce_umax_v32i16_signbit_not:
+; X64-SSE4:       # %bb.0:
+; X64-SSE4-NEXT:    movdqa (%rdi), %xmm0
+; X64-SSE4-NEXT:    movdqa 16(%rdi), %xmm1
+; X64-SSE4-NEXT:    movdqa 32(%rdi), %xmm2
+; X64-SSE4-NEXT:    movdqa 48(%rdi), %xmm3
+; X64-SSE4-NEXT:    pandn 32(%rsi), %xmm2
+; X64-SSE4-NEXT:    pandn (%rsi), %xmm0
+; X64-SSE4-NEXT:    pmaxuw %xmm2, %xmm0
+; X64-SSE4-NEXT:    pandn 48(%rsi), %xmm3
+; X64-SSE4-NEXT:    pandn 16(%rsi), %xmm1
+; X64-SSE4-NEXT:    pmaxuw %xmm3, %xmm1
+; X64-SSE4-NEXT:    pmaxuw %xmm0, %xmm1
+; X64-SSE4-NEXT:    packsswb %xmm1, %xmm1
+; X64-SSE4-NEXT:    pmovmskb %xmm1, %ecx
+; X64-SSE4-NEXT:    xorl %eax, %eax
+; X64-SSE4-NEXT:    testl %ecx, %ecx
+; X64-SSE4-NEXT:    sete %al
+; X64-SSE4-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-SSE4-NEXT:    retq
+;
+; X86-AVX1-LABEL: reduce_umax_v32i16_signbit_not:
+; X86-AVX1:       # %bb.0:
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX1-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX1-NEXT:    vmovaps 32(%ecx), %ymm1
+; X86-AVX1-NEXT:    vandnps (%eax), %ymm0, %ymm0
+; X86-AVX1-NEXT:    vandnps 32(%eax), %ymm1, %ymm1
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
+; X86-AVX1-NEXT:    vpor %xmm2, %xmm3, %xmm2
+; X86-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vpacksswb %xmm2, %xmm0, %xmm0
+; X86-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
+; X86-AVX1-NEXT:    xorl %eax, %eax
+; X86-AVX1-NEXT:    testl %ecx, %ecx
+; X86-AVX1-NEXT:    sete %al
+; X86-AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-AVX1-NEXT:    vzeroupper
+; X86-AVX1-NEXT:    retl
+;
+; X64-AVX1-LABEL: reduce_umax_v32i16_signbit_not:
+; X64-AVX1:       # %bb.0:
+; X64-AVX1-NEXT:    vmovaps (%rdi), %ymm0
+; X64-AVX1-NEXT:    vmovaps 32(%rdi), %ymm1
+; X64-AVX1-NEXT:    vandnps (%rsi), %ymm0, %ymm0
+; X64-AVX1-NEXT:    vandnps 32(%rsi), %ymm1, %ymm1
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
+; X64-AVX1-NEXT:    vpor %xmm2, %xmm3, %xmm2
+; X64-AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vpacksswb %xmm2, %xmm0, %xmm0
+; X64-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
+; X64-AVX1-NEXT:    xorl %eax, %eax
+; X64-AVX1-NEXT:    testl %ecx, %ecx
+; X64-AVX1-NEXT:    sete %al
+; X64-AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX1-NEXT:    vzeroupper
+; X64-AVX1-NEXT:    retq
+;
+; X86-AVX2-LABEL: reduce_umax_v32i16_signbit_not:
+; X86-AVX2:       # %bb.0:
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX2-NEXT:    vmovdqa (%ecx), %ymm0
+; X86-AVX2-NEXT:    vmovdqa 32(%ecx), %ymm1
+; X86-AVX2-NEXT:    vpandn 32(%eax), %ymm1, %ymm1
+; X86-AVX2-NEXT:    vpandn (%eax), %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
+; X86-AVX2-NEXT:    xorl %eax, %eax
+; X86-AVX2-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X86-AVX2-NEXT:    sete %al
+; X86-AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-AVX2-NEXT:    vzeroupper
+; X86-AVX2-NEXT:    retl
+;
+; X64-AVX2-LABEL: reduce_umax_v32i16_signbit_not:
+; X64-AVX2:       # %bb.0:
+; X64-AVX2-NEXT:    vmovdqa (%rdi), %ymm0
+; X64-AVX2-NEXT:    vmovdqa 32(%rdi), %ymm1
+; X64-AVX2-NEXT:    vpandn 32(%rsi), %ymm1, %ymm1
+; X64-AVX2-NEXT:    vpandn (%rsi), %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; X64-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
+; X64-AVX2-NEXT:    xorl %eax, %eax
+; X64-AVX2-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X64-AVX2-NEXT:    sete %al
+; X64-AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX2-NEXT:    vzeroupper
+; X64-AVX2-NEXT:    retq
+;
+; AVX512-LABEL: reduce_umax_v32i16_signbit_not:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa64 (%rdi), %zmm0
+; AVX512-NEXT:    vpandnq (%rsi), %zmm0, %zmm0
+; AVX512-NEXT:    vextracti64x4 $1, %zmm0, %ymm1
+; AVX512-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; AVX512-NEXT:    vpmovmskb %ymm0, %ecx
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    testl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; AVX512-NEXT:    sete %al
+; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
+  %a = load <32 x i16>, ptr %pa
+  %b = load <32 x i16>, ptr %pb
+  %a.not = xor <32 x i16> %a, splat (i16 -1)
+  %and = and <32 x i16> %b, %a.not
+  %rdx = call i16 @llvm.vector.reduce.umax.v32i16(<32 x i16> %and)
+  %cmp = icmp sgt i16 %rdx, -1
+  %res = zext i1 %cmp to i16
+  ret i16 %res
+}
+
+define i32 @reduce_umax_v16i32_signbit(ptr %pa, ptr %pb) {
+; X86-SSE-LABEL: reduce_umax_v16i32_signbit:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE-NEXT:    movaps 48(%ecx), %xmm0
+; X86-SSE-NEXT:    movaps (%ecx), %xmm1
+; X86-SSE-NEXT:    movaps 16(%ecx), %xmm2
+; X86-SSE-NEXT:    movaps 32(%ecx), %xmm3
+; X86-SSE-NEXT:    andps 32(%eax), %xmm3
+; X86-SSE-NEXT:    andps (%eax), %xmm1
+; X86-SSE-NEXT:    orps %xmm3, %xmm1
+; X86-SSE-NEXT:    andps 48(%eax), %xmm0
+; X86-SSE-NEXT:    andps 16(%eax), %xmm2
+; X86-SSE-NEXT:    orps %xmm0, %xmm2
+; X86-SSE-NEXT:    orps %xmm1, %xmm2
+; X86-SSE-NEXT:    movmskps %xmm2, %ecx
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    testl %ecx, %ecx
+; X86-SSE-NEXT:    sete %al
+; X86-SSE-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v16i32_signbit:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movaps (%rsi), %xmm0
+; X64-SSE-NEXT:    movaps 16(%rsi), %xmm1
+; X64-SSE-NEXT:    movaps 32(%rsi), %xmm2
+; X64-SSE-NEXT:    movaps 48(%rsi), %xmm3
+; X64-SSE-NEXT:    andps 32(%rdi), %xmm2
+; X64-SSE-NEXT:    andps (%rdi), %xmm0
+; X64-SSE-NEXT:    orps %xmm2, %xmm0
+; X64-SSE-NEXT:    andps 48(%rdi), %xmm3
+; X64-SSE-NEXT:    andps 16(%rdi), %xmm1
+; X64-SSE-NEXT:    orps %xmm3, %xmm1
+; X64-SSE-NEXT:    orps %xmm0, %xmm1
+; X64-SSE-NEXT:    movmskps %xmm1, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-AVX-LABEL: reduce_umax_v16i32_signbit:
+; X86-AVX:       # %bb.0:
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX-NEXT:    vmovaps 32(%ecx), %ymm1
+; X86-AVX-NEXT:    vandps 32(%eax), %ymm1, %ymm1
+; X86-AVX-NEXT:    vandps (%eax), %ymm0, %ymm0
+; X86-AVX-NEXT:    vorps %ymm1, %ymm0, %ymm0
+; X86-AVX-NEXT:    xorl %eax, %eax
+; X86-AVX-NEXT:    vtestps %ymm0, %ymm0
+; X86-AVX-NEXT:    sete %al
+; X86-AVX-NEXT:    vzeroupper
+; X86-AVX-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v16i32_signbit:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovaps (%rsi), %ymm0
+; X64-AVX-NEXT:    vmovaps 32(%rsi), %ymm1
+; X64-AVX-NEXT:    vandps 32(%rdi), %ymm1, %ymm1
+; X64-AVX-NEXT:    vandps (%rdi), %ymm0, %ymm0
+; X64-AVX-NEXT:    vorps %ymm1, %ymm0, %ymm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestps %ymm0, %ymm0
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    vzeroupper
+; X64-AVX-NEXT:    retq
+;
+; AVX512BW-LABEL: reduce_umax_v16i32_signbit:
+; AVX512BW:       # %bb.0:
+; AVX512BW-NEXT:    vmovdqa64 (%rsi), %zmm0
+; AVX512BW-NEXT:    vpandd (%rdi), %zmm0, %zmm0
+; AVX512BW-NEXT:    vextracti64x4 $1, %zmm0, %ymm1
+; AVX512BW-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; AVX512BW-NEXT:    xorl %eax, %eax
+; AVX512BW-NEXT:    vtestps %ymm0, %ymm0
+; AVX512BW-NEXT:    sete %al
+; AVX512BW-NEXT:    vzeroupper
+; AVX512BW-NEXT:    retq
+;
+; AVX512BWVL-LABEL: reduce_umax_v16i32_signbit:
+; AVX512BWVL:       # %bb.0:
+; AVX512BWVL-NEXT:    vmovaps (%rsi), %zmm0
+; AVX512BWVL-NEXT:    vandps (%rdi), %zmm0, %zmm0
+; AVX512BWVL-NEXT:    vextractf64x4 $1, %zmm0, %ymm1
+; AVX512BWVL-NEXT:    vorps %ymm1, %ymm0, %ymm0
+; AVX512BWVL-NEXT:    xorl %eax, %eax
+; AVX512BWVL-NEXT:    vtestps %ymm0, %ymm0
+; AVX512BWVL-NEXT:    sete %al
+; AVX512BWVL-NEXT:    vzeroupper
+; AVX512BWVL-NEXT:    retq
+  %a = load <16 x i32>, ptr %pa
+  %b = load <16 x i32>, ptr %pb
+  %and = and <16 x i32> %b, %a
+  %rdx = call i32 @llvm.vector.reduce.umax.v16i32(<16 x i32> %and)
+  %cmp = icmp sgt i32 %rdx, -1
+  %res = zext i1 %cmp to i32
+  ret i32 %res
+}
+
+define i64 @reduce_umax_v8i64_signbit_not(ptr %pa, ptr %pb) {
+; X86-SSE2-LABEL: reduce_umax_v8i64_signbit_not:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE2-NEXT:    movdqa 48(%ecx), %xmm4
+; X86-SSE2-NEXT:    movdqa 32(%ecx), %xmm1
+; X86-SSE2-NEXT:    movdqa 16(%ecx), %xmm5
+; X86-SSE2-NEXT:    pandn 16(%eax), %xmm5
+; X86-SSE2-NEXT:    pandn 48(%eax), %xmm4
+; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648,2147483648,2147483648]
+; X86-SSE2-NEXT:    movdqa %xmm4, %xmm2
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm2
+; X86-SSE2-NEXT:    movdqa %xmm5, %xmm3
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm3
+; X86-SSE2-NEXT:    movdqa %xmm3, %xmm6
+; X86-SSE2-NEXT:    pcmpgtd %xmm2, %xmm6
+; X86-SSE2-NEXT:    pcmpeqd %xmm2, %xmm3
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm6[0,0,2,2]
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm3[1,1,3,3]
+; X86-SSE2-NEXT:    pand %xmm2, %xmm7
+; X86-SSE2-NEXT:    movdqa (%ecx), %xmm3
+; X86-SSE2-NEXT:    pandn (%eax), %xmm3
+; X86-SSE2-NEXT:    pandn 32(%eax), %xmm1
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm6[1,1,3,3]
+; X86-SSE2-NEXT:    por %xmm7, %xmm2
+; X86-SSE2-NEXT:    pand %xmm2, %xmm5
+; X86-SSE2-NEXT:    pandn %xmm4, %xmm2
+; X86-SSE2-NEXT:    por %xmm5, %xmm2
+; X86-SSE2-NEXT:    movdqa %xmm1, %xmm4
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm4
+; X86-SSE2-NEXT:    movdqa %xmm3, %xmm5
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm5
+; X86-SSE2-NEXT:    movdqa %xmm5, %xmm6
+; X86-SSE2-NEXT:    pcmpgtd %xmm4, %xmm6
+; X86-SSE2-NEXT:    pcmpeqd %xmm4, %xmm5
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm6[0,0,2,2]
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
+; X86-SSE2-NEXT:    pand %xmm4, %xmm5
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm6[1,1,3,3]
+; X86-SSE2-NEXT:    por %xmm5, %xmm4
+; X86-SSE2-NEXT:    pand %xmm4, %xmm3
+; X86-SSE2-NEXT:    pandn %xmm1, %xmm4
+; X86-SSE2-NEXT:    movdqa %xmm2, %xmm1
+; X86-SSE2-NEXT:    pxor %xmm0, %xmm1
+; X86-SSE2-NEXT:    por %xmm3, %xmm4
+; X86-SSE2-NEXT:    pxor %xmm4, %xmm0
+; X86-SSE2-NEXT:    movdqa %xmm0, %xmm3
+; X86-SSE2-NEXT:    pcmpgtd %xmm1, %xmm3
+; X86-SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[0,0,2,2]
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
+; X86-SSE2-NEXT:    pand %xmm1, %xmm0
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,1,3,3]
+; X86-SSE2-NEXT:    por %xmm0, %xmm1
+; X86-SSE2-NEXT:    pand %xmm1, %xmm4
+; X86-SSE2-NEXT:    pandn %xmm2, %xmm1
+; X86-SSE2-NEXT:    por %xmm4, %xmm1
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,1,1]
+; X86-SSE2-NEXT:    por %xmm0, %xmm1
+; X86-SSE2-NEXT:    movd %xmm1, %eax
+; X86-SSE2-NEXT:    notl %eax
+; X86-SSE2-NEXT:    shrl $31, %eax
+; X86-SSE2-NEXT:    xorl %edx, %edx
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE-LABEL: reduce_umax_v8i64_signbit_not:
+; X64-SSE:       # %bb.0:
+; X64-SSE-NEXT:    movapd (%rdi), %xmm0
+; X64-SSE-NEXT:    movapd 16(%rdi), %xmm1
+; X64-SSE-NEXT:    movapd 32(%rdi), %xmm2
+; X64-SSE-NEXT:    movapd 48(%rdi), %xmm3
+; X64-SSE-NEXT:    andnpd 32(%rsi), %xmm2
+; X64-SSE-NEXT:    andnpd (%rsi), %xmm0
+; X64-SSE-NEXT:    orpd %xmm2, %xmm0
+; X64-SSE-NEXT:    andnpd 48(%rsi), %xmm3
+; X64-SSE-NEXT:    andnpd 16(%rsi), %xmm1
+; X64-SSE-NEXT:    orpd %xmm3, %xmm1
+; X64-SSE-NEXT:    orpd %xmm0, %xmm1
+; X64-SSE-NEXT:    movmskpd %xmm1, %ecx
+; X64-SSE-NEXT:    xorl %eax, %eax
+; X64-SSE-NEXT:    testl %ecx, %ecx
+; X64-SSE-NEXT:    sete %al
+; X64-SSE-NEXT:    retq
+;
+; X86-SSE41-LABEL: reduce_umax_v8i64_signbit_not:
+; X86-SSE41:       # %bb.0:
+; X86-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE41-NEXT:    movdqa 48(%ecx), %xmm1
+; X86-SSE41-NEXT:    movdqa 32(%ecx), %xmm2
+; X86-SSE41-NEXT:    movdqa 16(%ecx), %xmm4
+; X86-SSE41-NEXT:    pandn 16(%eax), %xmm4
+; X86-SSE41-NEXT:    pandn 48(%eax), %xmm1
+; X86-SSE41-NEXT:    movdqa {{.*#+}} xmm3 = [2147483648,2147483648,2147483648,2147483648]
+; X86-SSE41-NEXT:    movdqa %xmm1, %xmm0
+; X86-SSE41-NEXT:    pxor %xmm3, %xmm0
+; X86-SSE41-NEXT:    movdqa %xmm4, %xmm5
+; X86-SSE41-NEXT:    pxor %xmm3, %xmm5
+; X86-SSE41-NEXT:    movdqa %xmm5, %xmm6
+; X86-SSE41-NEXT:    pcmpgtd %xmm0, %xmm6
+; X86-SSE41-NEXT:    pcmpeqd %xmm0, %xmm5
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm6[0,0,2,2]
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm7 = xmm5[1,1,3,3]
+; X86-SSE41-NEXT:    pand %xmm0, %xmm7
+; X86-SSE41-NEXT:    movdqa (%ecx), %xmm5
+; X86-SSE41-NEXT:    pandn (%eax), %xmm5
+; X86-SSE41-NEXT:    pandn 32(%eax), %xmm2
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm6[1,1,3,3]
+; X86-SSE41-NEXT:    por %xmm7, %xmm0
+; X86-SSE41-NEXT:    blendvpd %xmm0, %xmm4, %xmm1
+; X86-SSE41-NEXT:    movdqa %xmm2, %xmm0
+; X86-SSE41-NEXT:    pxor %xmm3, %xmm0
+; X86-SSE41-NEXT:    movdqa %xmm5, %xmm4
+; X86-SSE41-NEXT:    pxor %xmm3, %xmm4
+; X86-SSE41-NEXT:    movdqa %xmm4, %xmm6
+; X86-SSE41-NEXT:    pcmpgtd %xmm0, %xmm6
+; X86-SSE41-NEXT:    pcmpeqd %xmm0, %xmm4
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm6[0,0,2,2]
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
+; X86-SSE41-NEXT:    pand %xmm0, %xmm4
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm6[1,1,3,3]
+; X86-SSE41-NEXT:    por %xmm4, %xmm0
+; X86-SSE41-NEXT:    blendvpd %xmm0, %xmm5, %xmm2
+; X86-SSE41-NEXT:    movapd %xmm1, %xmm0
+; X86-SSE41-NEXT:    xorpd %xmm3, %xmm0
+; X86-SSE41-NEXT:    xorpd %xmm2, %xmm3
+; X86-SSE41-NEXT:    movapd %xmm3, %xmm4
+; X86-SSE41-NEXT:    pcmpgtd %xmm0, %xmm4
+; X86-SSE41-NEXT:    pcmpeqd %xmm0, %xmm3
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm4[0,0,2,2]
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; X86-SSE41-NEXT:    pand %xmm0, %xmm3
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm4[1,1,3,3]
+; X86-SSE41-NEXT:    por %xmm3, %xmm0
+; X86-SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
+; X86-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
+; X86-SSE41-NEXT:    por %xmm1, %xmm0
+; X86-SSE41-NEXT:    pextrd $1, %xmm0, %eax
+; X86-SSE41-NEXT:    notl %eax
+; X86-SSE41-NEXT:    shrl $31, %eax
+; X86-SSE41-NEXT:    xorl %edx, %edx
+; X86-SSE41-NEXT:    retl
+;
+; X86-SSE42-LABEL: reduce_umax_v8i64_signbit_not:
+; X86-SSE42:       # %bb.0:
+; X86-SSE42-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE42-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-SSE42-NEXT:    movdqa 48(%ecx), %xmm2
+; X86-SSE42-NEXT:    movdqa 32(%ecx), %xmm3
+; X86-SSE42-NEXT:    movdqa (%ecx), %xmm4
+; X86-SSE42-NEXT:    movdqa 16(%ecx), %xmm5
+; X86-SSE42-NEXT:    pandn (%eax), %xmm4
+; X86-SSE42-NEXT:    pandn 32(%eax), %xmm3
+; X86-SSE42-NEXT:    pandn 16(%eax), %xmm5
+; X86-SSE42-NEXT:    pandn 48(%eax), %xmm2
+; X86-SSE42-NEXT:    movdqa {{.*#+}} xmm1 = [0,2147483648,0,2147483648]
+; X86-SSE42-NEXT:    movdqa %xmm2, %xmm6
+; X86-SSE42-NEXT:    pxor %xmm1, %xmm6
+; X86-SSE42-NEXT:    movdqa %xmm5, %xmm0
+; X86-SSE42-NEXT:    pxor %xmm1, %xmm0
+; X86-SSE42-NEXT:    pcmpgtq %xmm6, %xmm0
+; X86-SSE42-NEXT:    blendvpd %xmm0, %xmm5, %xmm2
+; X86-SSE42-NEXT:    movapd %xmm2, %xmm5
+; X86-SSE42-NEXT:    xorpd %xmm1, %xmm5
+; X86-SSE42-NEXT:    movdqa %xmm3, %xmm6
+; X86-SSE42-NEXT:    pxor %xmm1, %xmm6
+; X86-SSE42-NEXT:    movdqa %xmm4, %xmm0
+; X86-SSE42-NEXT:    pxor %xmm1, %xmm0
+; X86-SSE42-NEXT:    pcmpgtq %xmm6, %xmm0
+; X86-SSE42-NEXT:    blendvpd %xmm0, %xmm4, %xmm3
+; X86-SSE42-NEXT:    xorpd %xmm3, %xmm1
+; X86-SSE42-NEXT:    pcmpgtq %xmm5, %xmm1
+; X86-SSE42-NEXT:    movdqa %xmm1, %xmm0
+; X86-SSE42-NEXT:    blendvpd %xmm0, %xmm3, %xmm2
+; X86-SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]
+; X86-SSE42-NEXT:    por %xmm2, %xmm0
+; X86-SSE42-NEXT:    pextrd $1, %xmm0, %eax
+; X86-SSE42-NEXT:    notl %eax
+; X86-SSE42-NEXT:    shrl $31, %eax
+; X86-SSE42-NEXT:    xorl %edx, %edx
+; X86-SSE42-NEXT:    retl
+;
+; X86-AVX1-LABEL: reduce_umax_v8i64_signbit_not:
+; X86-AVX1:       # %bb.0:
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX1-NEXT:    vmovaps (%ecx), %ymm0
+; X86-AVX1-NEXT:    vmovaps 32(%ecx), %ymm1
+; X86-AVX1-NEXT:    vandnps (%eax), %ymm0, %ymm0
+; X86-AVX1-NEXT:    vandnps 32(%eax), %ymm1, %ymm1
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; X86-AVX1-NEXT:    vmovddup {{.*#+}} xmm3 = [0,2147483648,0,2147483648]
+; X86-AVX1-NEXT:    # xmm3 = mem[0,0]
+; X86-AVX1-NEXT:    vxorps %xmm3, %xmm2, %xmm4
+; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
+; X86-AVX1-NEXT:    vxorps %xmm3, %xmm5, %xmm6
+; X86-AVX1-NEXT:    vpcmpgtq %xmm4, %xmm6, %xmm4
+; X86-AVX1-NEXT:    vblendvpd %xmm4, %xmm5, %xmm2, %xmm2
+; X86-AVX1-NEXT:    vxorpd %xmm3, %xmm2, %xmm4
+; X86-AVX1-NEXT:    vxorps %xmm3, %xmm1, %xmm5
+; X86-AVX1-NEXT:    vxorps %xmm3, %xmm0, %xmm6
+; X86-AVX1-NEXT:    vpcmpgtq %xmm5, %xmm6, %xmm5
+; X86-AVX1-NEXT:    vblendvpd %xmm5, %xmm0, %xmm1, %xmm0
+; X86-AVX1-NEXT:    vxorpd %xmm3, %xmm0, %xmm1
+; X86-AVX1-NEXT:    vpcmpgtq %xmm4, %xmm1, %xmm1
+; X86-AVX1-NEXT:    vblendvpd %xmm1, %xmm0, %xmm2, %xmm0
+; X86-AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-AVX1-NEXT:    vorpd %xmm0, %xmm1, %xmm0
+; X86-AVX1-NEXT:    vextractps $1, %xmm0, %eax
+; X86-AVX1-NEXT:    notl %eax
+; X86-AVX1-NEXT:    shrl $31, %eax
+; X86-AVX1-NEXT:    xorl %edx, %edx
+; X86-AVX1-NEXT:    vzeroupper
+; X86-AVX1-NEXT:    retl
+;
+; X64-AVX-LABEL: reduce_umax_v8i64_signbit_not:
+; X64-AVX:       # %bb.0:
+; X64-AVX-NEXT:    vmovapd (%rdi), %ymm0
+; X64-AVX-NEXT:    vmovapd 32(%rdi), %ymm1
+; X64-AVX-NEXT:    vandnpd 32(%rsi), %ymm1, %ymm1
+; X64-AVX-NEXT:    vandnpd (%rsi), %ymm0, %ymm0
+; X64-AVX-NEXT:    vorpd %ymm1, %ymm0, %ymm0
+; X64-AVX-NEXT:    xorl %eax, %eax
+; X64-AVX-NEXT:    vtestpd %ymm0, %ymm0
+; X64-AVX-NEXT:    sete %al
+; X64-AVX-NEXT:    vzeroupper
+; X64-AVX-NEXT:    retq
+;
+; X86-AVX2-LABEL: reduce_umax_v8i64_signbit_not:
+; X86-AVX2:       # %bb.0:
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-AVX2-NEXT:    vmovdqa (%ecx), %ymm0
+; X86-AVX2-NEXT:    vmovdqa 32(%ecx), %ymm1
+; X86-AVX2-NEXT:    vpandn (%eax), %ymm0, %ymm0
+; X86-AVX2-NEXT:    vpandn 32(%eax), %ymm1, %ymm1
+; X86-AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm2 = [0,2147483648,0,2147483648,0,2147483648,0,2147483648]
+; X86-AVX2-NEXT:    vpxor %ymm2, %ymm1, %ymm3
+; X86-AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm4
+; X86-AVX2-NEXT:    vpcmpgtq %ymm3, %ymm4, %ymm3
+; X86-AVX2-NEXT:    vblendvpd %ymm3, %ymm0, %ymm1, %ymm0
+; X86-AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; X86-AVX2-NEXT:    vxorpd %xmm2, %xmm1, %xmm3
+; X86-AVX2-NEXT:    vxorpd %xmm2, %xmm0, %xmm2
+; X86-AVX2-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
+; X86-AVX2-NEXT:    vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
+; X86-AVX2-NEXT:    vshufps {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-AVX2-NEXT:    vorpd %xmm0, %xmm1, %xmm0
+; X86-AVX2-NEXT:    vextractps $1, %xmm0, %eax
+; X86-AVX2-NEXT:    notl %eax
+; X86-AVX2-NEXT:    shrl $31, %eax
+; X86-AVX2-NEXT:    xorl %edx, %edx
+; X86-AVX2-NEXT:    vzeroupper
+; X86-AVX2-NEXT:    retl
+;
+; AVX512BW-LABEL: reduce_umax_v8i64_signbit_not:
+; AVX512BW:       # %bb.0:
+; AVX512BW-NEXT:    vmovdqa64 (%rdi), %zmm0
+; AVX512BW-NEXT:    vpandnq (%rsi), %zmm0, %zmm0
+; AVX512BW-NEXT:    vextracti64x4 $1, %zmm0, %ymm1
+; AVX512BW-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; AVX512BW-NEXT:    xorl %eax, %eax
+; AVX512BW-NEXT:    vtestpd %ymm0, %ymm0
+; AVX512BW-NEXT:    sete %al
+; AVX512BW-NEXT:    vzeroupper
+; AVX512BW-NEXT:    retq
+;
+; AVX512BWVL-LABEL: reduce_umax_v8i64_signbit_not:
+; AVX512BWVL:       # %bb.0:
+; AVX512BWVL-NEXT:    vmovapd (%rdi), %zmm0
+; AVX512BWVL-NEXT:    vandnpd (%rsi), %zmm0, %zmm0
+; AVX512BWVL-NEXT:    vextractf64x4 $1, %zmm0, %ymm1
+; AVX512BWVL-NEXT:    vorpd %ymm1, %ymm0, %ymm0
+; AVX512BWVL-NEXT:    xorl %eax, %eax
+; AVX512BWVL-NEXT:    vtestpd %ymm0, %ymm0
+; AVX512BWVL-NEXT:    sete %al
+; AVX512BWVL-NEXT:    vzeroupper
+; AVX512BWVL-NEXT:    retq
+  %a = load <8 x i64>, ptr %pa
+  %b = load <8 x i64>, ptr %pb
+  %a.not = xor <8 x i64> %a, splat (i64 -1)
+  %and = and <8 x i64> %b, %a.not
+  %rdx = call i64 @llvm.vector.reduce.umax.v8i64(<8 x i64> %and)
+  %cmp = icmp sgt i64 %rdx, -1
+  %res = zext i1 %cmp to i64
+  ret i64 %res
+}



More information about the llvm-branch-commits mailing list