[llvm] [X86] vector-extract-last-active.ll - add x86-64/x86-64-v2/x86-64-v3/x86-64-v4 test coverage (PR #214180)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 5 03:10:48 PDT 2026


https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/214180

None

>From e8df15dc25cebe413410d3afc39827a5ced2e48b Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Wed, 5 Aug 2026 11:10:07 +0100
Subject: [PATCH] [X86] vector-extract-last-active.ll - add
 x86-64/x86-64-v2/x86-64-v3/x86-64-v4 test coverage

---
 .../CodeGen/X86/vector-extract-last-active.ll | 930 ++++++++++++++----
 1 file changed, 721 insertions(+), 209 deletions(-)

diff --git a/llvm/test/CodeGen/X86/vector-extract-last-active.ll b/llvm/test/CodeGen/X86/vector-extract-last-active.ll
index d3469d561184f..bd6f35df29490 100644
--- a/llvm/test/CodeGen/X86/vector-extract-last-active.ll
+++ b/llvm/test/CodeGen/X86/vector-extract-last-active.ll
@@ -1,196 +1,611 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
-; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64    | FileCheck %s --check-prefixes=CHECK,SSE2
+; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE42
+; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX512
 
 ; This test verifies that the experimental.vector.extract.last.active intrinsic
 ; doesn't cause an infinite loop during legalization when the step vector type
 ; needs widening (e.g., v4i8 -> v16i8 on X86).
 
-define i32 @extract_last_active_v4i32(<4 x i32> %a, <4 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v4i32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    pslld $31, %xmm1
-; CHECK-NEXT:    movmskps %xmm1, %ecx
-; CHECK-NEXT:    psrad $31, %xmm1
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648,2147483648,2147483648]
-; CHECK-NEXT:    movdqa %xmm1, %xmm2
-; CHECK-NEXT:    por %xmm0, %xmm2
-; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3]
-; CHECK-NEXT:    por %xmm3, %xmm0
-; CHECK-NEXT:    pcmpgtd %xmm0, %xmm2
-; CHECK-NEXT:    pand %xmm2, %xmm1
-; CHECK-NEXT:    pandn %xmm3, %xmm2
-; CHECK-NEXT:    por %xmm1, %xmm2
-; CHECK-NEXT:    movd %xmm2, %eax
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]
-; CHECK-NEXT:    movd %xmm0, %edx
-; CHECK-NEXT:    cmpl %edx, %eax
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    andl $3, %edx
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $1, %ecx
-; CHECK-NEXT:    sbbl %eax, %eax
-; CHECK-NEXT:    orl -24(%rsp,%rdx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v4i32(<4 x i32> %a, <4 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v4i32:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pslld $31, %xmm1
+; SSE2-NEXT:    movmskps %xmm1, %ecx
+; SSE2-NEXT:    psrad $31, %xmm1
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
+; SSE2-NEXT:    movdqa %xmm1, %xmm3
+; SSE2-NEXT:    por %xmm2, %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3]
+; SSE2-NEXT:    por %xmm4, %xmm2
+; SSE2-NEXT:    pcmpgtd %xmm2, %xmm3
+; SSE2-NEXT:    pand %xmm3, %xmm1
+; SSE2-NEXT:    pandn %xmm4, %xmm3
+; SSE2-NEXT:    por %xmm1, %xmm3
+; SSE2-NEXT:    movd %xmm3, %eax
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,1,1,1]
+; SSE2-NEXT:    movd %xmm1, %edx
+; SSE2-NEXT:    cmpl %edx, %eax
+; SSE2-NEXT:    cmoval %eax, %edx
+; SSE2-NEXT:    andl $3, %edx
+; SSE2-NEXT:    xorl %eax, %eax
+; SSE2-NEXT:    cmpl $1, %ecx
+; SSE2-NEXT:    sbbl %eax, %eax
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    orl -24(%rsp,%rdx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v4i32:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    pslld $31, %xmm1
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movmskps %xmm1, %ecx
+; SSE42-NEXT:    xorl %eax, %eax
+; SSE42-NEXT:    cmpl $1, %ecx
+; SSE42-NEXT:    sbbl %eax, %eax
+; SSE42-NEXT:    psrad $31, %xmm1
+; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
+; SSE42-NEXT:    pmaxud %xmm0, %xmm1
+; SSE42-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,1,1]
+; SSE42-NEXT:    pmaxud %xmm0, %xmm1
+; SSE42-NEXT:    movd %xmm1, %ecx
+; SSE42-NEXT:    andl $3, %ecx
+; SSE42-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v4i32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpslld $31, %xmm1, %xmm1
+; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
+; AVX2-NEXT:    vpsrad $31, %xmm1, %xmm0
+; AVX2-NEXT:    vmovmskps %xmm1, %ecx
+; AVX2-NEXT:    xorl %eax, %eax
+; AVX2-NEXT:    cmpl $1, %ecx
+; AVX2-NEXT:    sbbl %eax, %eax
+; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpmaxud %xmm0, %xmm1, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %ecx
+; AVX2-NEXT:    andl $3, %ecx
+; AVX2-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v4i32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpslld $31, %xmm1, %xmm1
+; AVX512-NEXT:    vpmovd2m %xmm1, %k1
+; AVX512-NEXT:    vmovdqa %xmm0, -{{[0-9]+}}(%rsp)
+; AVX512-NEXT:    kortestb %k1, %k1
+; AVX512-NEXT:    movl $-1, %eax
+; AVX512-NEXT:    je .LBB0_2
+; AVX512-NEXT:  # %bb.1:
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,253,252,u,u,u,u,u,u,u,u,u,u,u,u]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $3, %eax
+; AVX512-NEXT:    movl -24(%rsp,%rax,4), %eax
+; AVX512-NEXT:  .LBB0_2:
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v4i32(<4 x i32> %a, <4 x i1> %c, i32 -1)
   ret i32 %res
 }
 
-define i32 @extract_last_active_v4i32_no_default(<4 x i32> %a, <4 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v4i32_no_default:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    pslld $31, %xmm1
-; CHECK-NEXT:    psrad $31, %xmm1
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648,2147483648,2147483648]
-; CHECK-NEXT:    movdqa %xmm1, %xmm2
-; CHECK-NEXT:    por %xmm0, %xmm2
-; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3]
-; CHECK-NEXT:    por %xmm3, %xmm0
-; CHECK-NEXT:    pcmpgtd %xmm0, %xmm2
-; CHECK-NEXT:    pand %xmm2, %xmm1
-; CHECK-NEXT:    pandn %xmm3, %xmm2
-; CHECK-NEXT:    por %xmm1, %xmm2
-; CHECK-NEXT:    movd %xmm2, %eax
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]
-; CHECK-NEXT:    movd %xmm0, %ecx
-; CHECK-NEXT:    cmpl %ecx, %eax
-; CHECK-NEXT:    cmoval %eax, %ecx
-; CHECK-NEXT:    andl $3, %ecx
-; CHECK-NEXT:    movl -24(%rsp,%rcx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v4i32_no_default(<4 x i32> %a, <4 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v4i32_no_default:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pslld $31, %xmm1
+; SSE2-NEXT:    psrad $31, %xmm1
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
+; SSE2-NEXT:    movdqa %xmm1, %xmm3
+; SSE2-NEXT:    por %xmm2, %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3]
+; SSE2-NEXT:    por %xmm4, %xmm2
+; SSE2-NEXT:    pcmpgtd %xmm2, %xmm3
+; SSE2-NEXT:    pand %xmm3, %xmm1
+; SSE2-NEXT:    pandn %xmm4, %xmm3
+; SSE2-NEXT:    por %xmm1, %xmm3
+; SSE2-NEXT:    movd %xmm3, %eax
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,1,1,1]
+; SSE2-NEXT:    movd %xmm1, %ecx
+; SSE2-NEXT:    cmpl %ecx, %eax
+; SSE2-NEXT:    cmoval %eax, %ecx
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    andl $3, %ecx
+; SSE2-NEXT:    movl -24(%rsp,%rcx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v4i32_no_default:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    pslld $31, %xmm1
+; SSE42-NEXT:    psrad $31, %xmm1
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
+; SSE42-NEXT:    pmaxud %xmm0, %xmm1
+; SSE42-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,1,1]
+; SSE42-NEXT:    pmaxud %xmm0, %xmm1
+; SSE42-NEXT:    movd %xmm1, %eax
+; SSE42-NEXT:    andl $3, %eax
+; SSE42-NEXT:    movl -24(%rsp,%rax,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v4i32_no_default:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpslld $31, %xmm1, %xmm1
+; AVX2-NEXT:    vpsrad $31, %xmm1, %xmm1
+; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
+; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpmaxud %xmm0, %xmm1, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    andl $3, %eax
+; AVX2-NEXT:    movl -24(%rsp,%rax,4), %eax
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v4i32_no_default:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpslld $31, %xmm1, %xmm1
+; AVX512-NEXT:    vmovdqa %xmm0, -{{[0-9]+}}(%rsp)
+; AVX512-NEXT:    vpmovd2m %xmm1, %k1
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,253,252,u,u,u,u,u,u,u,u,u,u,u,u]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $3, %eax
+; AVX512-NEXT:    movl -24(%rsp,%rax,4), %eax
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v4i32(<4 x i32> %a, <4 x i1> %c, i32 poison)
   ret i32 %res
 }
 
 ; Test v2i32 - smaller vector.
-define i32 @extract_last_active_v2i32(<2 x i32> %a, <2 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v2i32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    psllq $63, %xmm1
-; CHECK-NEXT:    movmskpd %xmm1, %ecx
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $1, %ecx
-; CHECK-NEXT:    sbbl %eax, %eax
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]
-; CHECK-NEXT:    psrld $31, %xmm0
-; CHECK-NEXT:    movq %xmm0, %rcx
-; CHECK-NEXT:    movl %ecx, %ecx
-; CHECK-NEXT:    orl -24(%rsp,%rcx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v2i32(<2 x i32> %a, <2 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v2i32:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    psllq $63, %xmm1
+; SSE2-NEXT:    movmskpd %xmm1, %ecx
+; SSE2-NEXT:    xorl %eax, %eax
+; SSE2-NEXT:    cmpl $1, %ecx
+; SSE2-NEXT:    sbbl %eax, %eax
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]
+; SSE2-NEXT:    psrld $31, %xmm0
+; SSE2-NEXT:    movq %xmm0, %rcx
+; SSE2-NEXT:    movl %ecx, %ecx
+; SSE2-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v2i32:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    pxor %xmm2, %xmm2
+; SSE42-NEXT:    psllq $63, %xmm1
+; SSE42-NEXT:    pcmpgtq %xmm1, %xmm2
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movmskpd %xmm1, %ecx
+; SSE42-NEXT:    xorl %eax, %eax
+; SSE42-NEXT:    cmpl $1, %ecx
+; SSE42-NEXT:    sbbl %eax, %eax
+; SSE42-NEXT:    pextrq $1, %xmm2, %rcx
+; SSE42-NEXT:    andl $1, %ecx
+; SSE42-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v2i32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vpsllq $63, %xmm1, %xmm1
+; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
+; AVX2-NEXT:    vpcmpgtq %xmm1, %xmm2, %xmm0
+; AVX2-NEXT:    vmovmskpd %xmm1, %ecx
+; AVX2-NEXT:    xorl %eax, %eax
+; AVX2-NEXT:    cmpl $1, %ecx
+; AVX2-NEXT:    sbbl %eax, %eax
+; AVX2-NEXT:    vpextrq $1, %xmm0, %rcx
+; AVX2-NEXT:    andl $1, %ecx
+; AVX2-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v2i32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpsllq $63, %xmm1, %xmm1
+; AVX512-NEXT:    vpmovq2m %xmm1, %k1
+; AVX512-NEXT:    vmovdqa %xmm0, -{{[0-9]+}}(%rsp)
+; AVX512-NEXT:    kortestb %k1, %k1
+; AVX512-NEXT:    movl $-1, %eax
+; AVX512-NEXT:    je .LBB2_2
+; AVX512-NEXT:  # %bb.1:
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,u,u,u,u,u,u,u,u,u,u,u,u,u,u]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $3, %eax
+; AVX512-NEXT:    movl -24(%rsp,%rax,4), %eax
+; AVX512-NEXT:  .LBB2_2:
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v2i32(<2 x i32> %a, <2 x i1> %c, i32 -1)
   ret i32 %res
 }
 
 ; Test v3i32 - non-power-of-2 element count that requires mask widening
 ; (v3i1 -> v4i1) via WidenVecOp_VECTOR_FIND_LAST_ACTIVE.
-define i32 @extract_last_active_v3i32(<3 x i32> %a, <3 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v3i32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movd %esi, %xmm1
-; CHECK-NEXT:    movd %edi, %xmm2
-; CHECK-NEXT:    movdqa %xmm2, %xmm4
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; CHECK-NEXT:    movd %edx, %xmm3
-; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm3[0]
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    pslld $31, %xmm4
-; CHECK-NEXT:    psrad $31, %xmm4
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
-; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648,2147483648,2147483648]
-; CHECK-NEXT:    movdqa %xmm4, %xmm5
-; CHECK-NEXT:    por %xmm0, %xmm5
-; CHECK-NEXT:    pshufd {{.*#+}} xmm6 = xmm4[2,3,2,3]
-; CHECK-NEXT:    por %xmm6, %xmm0
-; CHECK-NEXT:    pcmpgtd %xmm0, %xmm5
-; CHECK-NEXT:    pand %xmm5, %xmm4
-; CHECK-NEXT:    pandn %xmm6, %xmm5
-; CHECK-NEXT:    por %xmm4, %xmm5
-; CHECK-NEXT:    movd %xmm5, %eax
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm5[1,1,1,1]
-; CHECK-NEXT:    movd %xmm0, %ecx
-; CHECK-NEXT:    cmpl %ecx, %eax
-; CHECK-NEXT:    cmoval %eax, %ecx
-; CHECK-NEXT:    andl $3, %ecx
-; CHECK-NEXT:    por %xmm3, %xmm2
-; CHECK-NEXT:    por %xmm1, %xmm2
-; CHECK-NEXT:    movd %xmm2, %edx
-; CHECK-NEXT:    andb $1, %dl
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpb $1, %dl
-; CHECK-NEXT:    sbbl %eax, %eax
-; CHECK-NEXT:    orl -24(%rsp,%rcx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v3i32(<3 x i32> %a, <3 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v3i32:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movd %esi, %xmm1
+; SSE2-NEXT:    movd %edi, %xmm2
+; SSE2-NEXT:    movdqa %xmm2, %xmm4
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; SSE2-NEXT:    movd %edx, %xmm3
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm3[0]
+; SSE2-NEXT:    pslld $31, %xmm4
+; SSE2-NEXT:    psrad $31, %xmm4
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
+; SSE2-NEXT:    movdqa {{.*#+}} xmm5 = [2147483648,2147483648,2147483648,2147483648]
+; SSE2-NEXT:    movdqa %xmm4, %xmm6
+; SSE2-NEXT:    por %xmm5, %xmm6
+; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm4[2,3,2,3]
+; SSE2-NEXT:    por %xmm7, %xmm5
+; SSE2-NEXT:    pcmpgtd %xmm5, %xmm6
+; SSE2-NEXT:    pand %xmm6, %xmm4
+; SSE2-NEXT:    pandn %xmm7, %xmm6
+; SSE2-NEXT:    por %xmm4, %xmm6
+; SSE2-NEXT:    movd %xmm6, %eax
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm6[1,1,1,1]
+; SSE2-NEXT:    movd %xmm4, %ecx
+; SSE2-NEXT:    cmpl %ecx, %eax
+; SSE2-NEXT:    cmoval %eax, %ecx
+; SSE2-NEXT:    andl $3, %ecx
+; SSE2-NEXT:    por %xmm3, %xmm2
+; SSE2-NEXT:    por %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %edx
+; SSE2-NEXT:    andb $1, %dl
+; SSE2-NEXT:    xorl %eax, %eax
+; SSE2-NEXT:    cmpb $1, %dl
+; SSE2-NEXT:    sbbl %eax, %eax
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v3i32:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    movd %edi, %xmm1
+; SSE42-NEXT:    movd %edx, %xmm2
+; SSE42-NEXT:    por %xmm1, %xmm2
+; SSE42-NEXT:    pinsrd $1, %esi, %xmm1
+; SSE42-NEXT:    pinsrd $2, %edx, %xmm1
+; SSE42-NEXT:    pxor %xmm3, %xmm3
+; SSE42-NEXT:    pblendw {{.*#+}} xmm3 = xmm1[0,1,2,3,4,5],xmm3[6,7]
+; SSE42-NEXT:    pslld $31, %xmm3
+; SSE42-NEXT:    psrad $31, %xmm3
+; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
+; SSE42-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[2,3,2,3]
+; SSE42-NEXT:    pmaxud %xmm1, %xmm3
+; SSE42-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,1,1]
+; SSE42-NEXT:    pmaxud %xmm1, %xmm3
+; SSE42-NEXT:    movd %xmm3, %ecx
+; SSE42-NEXT:    andl $3, %ecx
+; SSE42-NEXT:    movd %esi, %xmm1
+; SSE42-NEXT:    por %xmm2, %xmm1
+; SSE42-NEXT:    movd %xmm1, %edx
+; SSE42-NEXT:    andb $1, %dl
+; SSE42-NEXT:    xorl %eax, %eax
+; SSE42-NEXT:    cmpb $1, %dl
+; SSE42-NEXT:    sbbl %eax, %eax
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v3i32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vmovd %edi, %xmm1
+; AVX2-NEXT:    vpinsrd $1, %esi, %xmm1, %xmm2
+; AVX2-NEXT:    vpinsrd $2, %edx, %xmm2, %xmm2
+; AVX2-NEXT:    vmovdqa %xmm0, -{{[0-9]+}}(%rsp)
+; AVX2-NEXT:    vpxor %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3]
+; AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm0
+; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpmaxud %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpmaxud %xmm0, %xmm2, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %ecx
+; AVX2-NEXT:    andl $3, %ecx
+; AVX2-NEXT:    vmovd %edx, %xmm0
+; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
+; AVX2-NEXT:    vmovd %esi, %xmm1
+; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %edx
+; AVX2-NEXT:    andb $1, %dl
+; AVX2-NEXT:    xorl %eax, %eax
+; AVX2-NEXT:    cmpb $1, %dl
+; AVX2-NEXT:    sbbl %eax, %eax
+; AVX2-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v3i32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vmovdqa %xmm0, -{{[0-9]+}}(%rsp)
+; AVX512-NEXT:    vpxor %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vpinsrb $1, %esi, %xmm0, %xmm0
+; AVX512-NEXT:    vpinsrb $2, %edx, %xmm0, %xmm0
+; AVX512-NEXT:    kmovd %edx, %k0
+; AVX512-NEXT:    kmovd %edi, %k1
+; AVX512-NEXT:    korw %k0, %k1, %k0
+; AVX512-NEXT:    kmovd %esi, %k1
+; AVX512-NEXT:    korw %k1, %k0, %k0
+; AVX512-NEXT:    kmovd %k0, %ecx
+; AVX512-NEXT:    andb $1, %cl
+; AVX512-NEXT:    xorl %eax, %eax
+; AVX512-NEXT:    cmpb $1, %cl
+; AVX512-NEXT:    sbbl %eax, %eax
+; AVX512-NEXT:    vpmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
+; AVX512-NEXT:    vptestmd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %k1
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,253,252,u,u,u,u,u,u,u,u,u,u,u,u]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %ecx
+; AVX512-NEXT:    notb %cl
+; AVX512-NEXT:    movzbl %cl, %ecx
+; AVX512-NEXT:    andl $3, %ecx
+; AVX512-NEXT:    orl -24(%rsp,%rcx,4), %eax
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v3i32(<3 x i32> %a, <3 x i1> %c, i32 -1)
   ret i32 %res
 }
 
 ; Test v8i32 - larger vector where step vector type doesn't need widening.
-define i32 @extract_last_active_v8i32(<8 x i32> %a, <8 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v8i32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    psllw $15, %xmm2
-; CHECK-NEXT:    movdqa %xmm2, %xmm0
-; CHECK-NEXT:    psraw $15, %xmm0
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; CHECK-NEXT:    psubusw %xmm0, %xmm1
-; CHECK-NEXT:    paddw %xmm0, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
-; CHECK-NEXT:    psubusw %xmm1, %xmm0
-; CHECK-NEXT:    paddw %xmm1, %xmm0
-; CHECK-NEXT:    pextrw $1, %xmm0, %ecx
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    cmpw %cx, %ax
-; CHECK-NEXT:    cmoval %eax, %ecx
-; CHECK-NEXT:    andl $7, %ecx
-; CHECK-NEXT:    packsswb %xmm2, %xmm2
-; CHECK-NEXT:    pmovmskb %xmm2, %edx
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpb $1, %dl
-; CHECK-NEXT:    sbbl %eax, %eax
-; CHECK-NEXT:    orl -40(%rsp,%rcx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v8i32(<8 x i32> %a, <8 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v8i32:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    psllw $15, %xmm2
+; SSE2-NEXT:    movdqa %xmm2, %xmm3
+; SSE2-NEXT:    psraw $15, %xmm3
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm3[2,3,2,3]
+; SSE2-NEXT:    psubusw %xmm3, %xmm4
+; SSE2-NEXT:    paddw %xmm3, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,1,1]
+; SSE2-NEXT:    psubusw %xmm4, %xmm3
+; SSE2-NEXT:    paddw %xmm4, %xmm3
+; SSE2-NEXT:    pextrw $1, %xmm3, %ecx
+; SSE2-NEXT:    movd %xmm3, %eax
+; SSE2-NEXT:    cmpw %cx, %ax
+; SSE2-NEXT:    cmoval %eax, %ecx
+; SSE2-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    andl $7, %ecx
+; SSE2-NEXT:    packsswb %xmm2, %xmm2
+; SSE2-NEXT:    pmovmskb %xmm2, %edx
+; SSE2-NEXT:    xorl %eax, %eax
+; SSE2-NEXT:    cmpb $1, %dl
+; SSE2-NEXT:    sbbl %eax, %eax
+; SSE2-NEXT:    movdqa %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    orl -40(%rsp,%rcx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v8i32:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    psllw $15, %xmm2
+; SSE42-NEXT:    movdqa %xmm2, %xmm0
+; SSE42-NEXT:    packsswb %xmm0, %xmm0
+; SSE42-NEXT:    pmovmskb %xmm0, %ecx
+; SSE42-NEXT:    xorl %eax, %eax
+; SSE42-NEXT:    cmpb $1, %cl
+; SSE42-NEXT:    sbbl %eax, %eax
+; SSE42-NEXT:    psraw $15, %xmm2
+; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE42-NEXT:    pcmpeqd %xmm0, %xmm0
+; SSE42-NEXT:    pxor %xmm2, %xmm0
+; SSE42-NEXT:    phminposuw %xmm0, %xmm0
+; SSE42-NEXT:    movd %xmm0, %ecx
+; SSE42-NEXT:    notl %ecx
+; SSE42-NEXT:    andl $7, %ecx
+; SSE42-NEXT:    orl -40(%rsp,%rcx,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v8i32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    pushq %rbp
+; AVX2-NEXT:    movq %rsp, %rbp
+; AVX2-NEXT:    andq $-32, %rsp
+; AVX2-NEXT:    subq $64, %rsp
+; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
+; AVX2-NEXT:    vpsllw $15, %xmm1, %xmm0
+; AVX2-NEXT:    vpacksswb %xmm0, %xmm0, %xmm1
+; AVX2-NEXT:    vpmovmskb %xmm1, %ecx
+; AVX2-NEXT:    xorl %eax, %eax
+; AVX2-NEXT:    cmpb $1, %cl
+; AVX2-NEXT:    sbbl %eax, %eax
+; AVX2-NEXT:    vpsraw $15, %xmm0, %xmm0
+; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX2-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %ecx
+; AVX2-NEXT:    notl %ecx
+; AVX2-NEXT:    andl $7, %ecx
+; AVX2-NEXT:    orl (%rsp,%rcx,4), %eax
+; AVX2-NEXT:    movq %rbp, %rsp
+; AVX2-NEXT:    popq %rbp
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v8i32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    pushq %rbp
+; AVX512-NEXT:    movq %rsp, %rbp
+; AVX512-NEXT:    andq $-32, %rsp
+; AVX512-NEXT:    subq $64, %rsp
+; AVX512-NEXT:    vpsllw $15, %xmm1, %xmm1
+; AVX512-NEXT:    vpmovw2m %xmm1, %k1
+; AVX512-NEXT:    vmovdqa %ymm0, (%rsp)
+; AVX512-NEXT:    kortestb %k1, %k1
+; AVX512-NEXT:    movl $-1, %eax
+; AVX512-NEXT:    je .LBB4_2
+; AVX512-NEXT:  # %bb.1:
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,253,252,251,250,249,248,u,u,u,u,u,u,u,u]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $7, %eax
+; AVX512-NEXT:    movl (%rsp,%rax,4), %eax
+; AVX512-NEXT:  .LBB4_2:
+; AVX512-NEXT:    movq %rbp, %rsp
+; AVX512-NEXT:    popq %rbp
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v8i32(<8 x i32> %a, <8 x i1> %c, i32 -1)
   ret i32 %res
 }
 
 ; Test v16i32 - even larger vector.
-define i32 @extract_last_active_v16i32(<16 x i32> %a, <16 x i1> %c) {
-; CHECK-LABEL: extract_last_active_v16i32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    pxor %xmm5, %xmm5
-; CHECK-NEXT:    psllw $7, %xmm4
-; CHECK-NEXT:    pcmpgtb %xmm4, %xmm5
-; CHECK-NEXT:    movaps %xmm3, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movaps %xmm2, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm5
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3]
-; CHECK-NEXT:    pmaxub %xmm5, %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; CHECK-NEXT:    pmaxub %xmm0, %xmm1
-; CHECK-NEXT:    movdqa %xmm1, %xmm0
-; CHECK-NEXT:    psrld $16, %xmm0
-; CHECK-NEXT:    pmaxub %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $8, %xmm1
-; CHECK-NEXT:    pmaxub %xmm0, %xmm1
-; CHECK-NEXT:    movd %xmm1, %ecx
-; CHECK-NEXT:    andl $15, %ecx
-; CHECK-NEXT:    pmovmskb %xmm4, %edx
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $1, %edx
-; CHECK-NEXT:    sbbl %eax, %eax
-; CHECK-NEXT:    orl -72(%rsp,%rcx,4), %eax
-; CHECK-NEXT:    retq
+define i32 @extract_last_active_v16i32(<16 x i32> %a, <16 x i1> %c) nounwind {
+; SSE2-LABEL: extract_last_active_v16i32:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pxor %xmm5, %xmm5
+; SSE2-NEXT:    psllw $7, %xmm4
+; SSE2-NEXT:    pcmpgtb %xmm4, %xmm5
+; SSE2-NEXT:    movaps %xmm3, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    movaps %xmm2, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[2,3,2,3]
+; SSE2-NEXT:    pmaxub %xmm5, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,1,1]
+; SSE2-NEXT:    pmaxub %xmm1, %xmm2
+; SSE2-NEXT:    movdqa %xmm2, %xmm1
+; SSE2-NEXT:    psrld $16, %xmm1
+; SSE2-NEXT:    pmaxub %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm2
+; SSE2-NEXT:    psrlw $8, %xmm2
+; SSE2-NEXT:    pmaxub %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %ecx
+; SSE2-NEXT:    andl $15, %ecx
+; SSE2-NEXT:    pmovmskb %xmm4, %edx
+; SSE2-NEXT:    xorl %eax, %eax
+; SSE2-NEXT:    cmpl $1, %edx
+; SSE2-NEXT:    sbbl %eax, %eax
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    orl -72(%rsp,%rcx,4), %eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_v16i32:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    pxor %xmm5, %xmm5
+; SSE42-NEXT:    psllw $7, %xmm4
+; SSE42-NEXT:    pcmpgtb %xmm4, %xmm5
+; SSE42-NEXT:    movaps %xmm3, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movaps %xmm2, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm5
+; SSE42-NEXT:    movdqa %xmm1, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    pcmpeqd %xmm1, %xmm1
+; SSE42-NEXT:    pxor %xmm5, %xmm1
+; SSE42-NEXT:    movdqa %xmm1, %xmm2
+; SSE42-NEXT:    psrlw $8, %xmm2
+; SSE42-NEXT:    pminub %xmm1, %xmm2
+; SSE42-NEXT:    phminposuw %xmm2, %xmm1
+; SSE42-NEXT:    movd %xmm1, %eax
+; SSE42-NEXT:    notb %al
+; SSE42-NEXT:    movzbl %al, %ecx
+; SSE42-NEXT:    andl $15, %ecx
+; SSE42-NEXT:    pmovmskb %xmm4, %edx
+; SSE42-NEXT:    xorl %eax, %eax
+; SSE42-NEXT:    cmpl $1, %edx
+; SSE42-NEXT:    sbbl %eax, %eax
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    orl -72(%rsp,%rcx,4), %eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_v16i32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    pushq %rbp
+; AVX2-NEXT:    movq %rsp, %rbp
+; AVX2-NEXT:    andq $-32, %rsp
+; AVX2-NEXT:    subq $96, %rsp
+; AVX2-NEXT:    vpxor %xmm3, %xmm3, %xmm3
+; AVX2-NEXT:    vpsllw $7, %xmm2, %xmm2
+; AVX2-NEXT:    vpcmpgtb %xmm2, %xmm3, %xmm3
+; AVX2-NEXT:    vmovdqa %ymm1, {{[0-9]+}}(%rsp)
+; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
+; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3, %xmm0
+; AVX2-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX2-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    notb %al
+; AVX2-NEXT:    movzbl %al, %ecx
+; AVX2-NEXT:    andl $15, %ecx
+; AVX2-NEXT:    vpmovmskb %xmm2, %edx
+; AVX2-NEXT:    xorl %eax, %eax
+; AVX2-NEXT:    cmpl $1, %edx
+; AVX2-NEXT:    sbbl %eax, %eax
+; AVX2-NEXT:    orl (%rsp,%rcx,4), %eax
+; AVX2-NEXT:    movq %rbp, %rsp
+; AVX2-NEXT:    popq %rbp
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_v16i32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    pushq %rbp
+; AVX512-NEXT:    movq %rsp, %rbp
+; AVX512-NEXT:    andq $-64, %rsp
+; AVX512-NEXT:    subq $128, %rsp
+; AVX512-NEXT:    vpsllw $7, %xmm1, %xmm1
+; AVX512-NEXT:    vpmovb2m %xmm1, %k1
+; AVX512-NEXT:    vmovdqa64 %zmm0, (%rsp)
+; AVX512-NEXT:    kortestw %k1, %k1
+; AVX512-NEXT:    movl $-1, %eax
+; AVX512-NEXT:    je .LBB5_2
+; AVX512-NEXT:  # %bb.1:
+; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm0 {%k1} = [255,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240]
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm1
+; AVX512-NEXT:    vpminub %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $15, %eax
+; AVX512-NEXT:    movl (%rsp,%rax,4), %eax
+; AVX512-NEXT:  .LBB5_2:
+; AVX512-NEXT:    movq %rbp, %rsp
+; AVX512-NEXT:    popq %rbp
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
   %res = call i32 @llvm.experimental.vector.extract.last.active.v16i32(<16 x i32> %a, <16 x i1> %c, i32 -1)
   ret i32 %res
 }
@@ -216,53 +631,150 @@ define i32 @extract_last_active_v4i32_penryn(<4 x i32> %a, <4 x i1> %c) "target-
   ret i32 %res
 }
 
-define i8 @extract_last_active_split(<32 x i8> %data, <32 x i8> %mask, i8 %passthru) {
-; CHECK-LABEL: extract_last_active_split:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    pxor %xmm4, %xmm4
-; CHECK-NEXT:    movdqa %xmm2, %xmm5
-; CHECK-NEXT:    por %xmm3, %xmm2
-; CHECK-NEXT:    pcmpeqb %xmm4, %xmm3
-; CHECK-NEXT:    pcmpeqb %xmm4, %xmm5
-; CHECK-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
-; CHECK-NEXT:    pandn %xmm0, %xmm5
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[2,3,2,3]
-; CHECK-NEXT:    pmaxub %xmm5, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm5 = xmm1[1,1,1,1]
-; CHECK-NEXT:    pmaxub %xmm1, %xmm5
-; CHECK-NEXT:    movdqa %xmm5, %xmm1
-; CHECK-NEXT:    psrld $16, %xmm1
-; CHECK-NEXT:    pmaxub %xmm5, %xmm1
-; CHECK-NEXT:    movdqa %xmm1, %xmm5
-; CHECK-NEXT:    psrlw $8, %xmm5
-; CHECK-NEXT:    pmaxub %xmm1, %xmm5
-; CHECK-NEXT:    movd %xmm5, %eax
-; CHECK-NEXT:    pmovmskb %xmm3, %ecx
-; CHECK-NEXT:    pandn %xmm0, %xmm3
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3]
-; CHECK-NEXT:    pmaxub %xmm3, %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; CHECK-NEXT:    pmaxub %xmm0, %xmm1
-; CHECK-NEXT:    movdqa %xmm1, %xmm0
-; CHECK-NEXT:    psrld $16, %xmm0
-; CHECK-NEXT:    pmaxub %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $8, %xmm1
-; CHECK-NEXT:    pmaxub %xmm0, %xmm1
-; CHECK-NEXT:    movd %xmm1, %edx
-; CHECK-NEXT:    addl $16, %edx
-; CHECK-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
-; CHECK-NEXT:    cmoveq %rax, %rdx
-; CHECK-NEXT:    andl $31, %edx
-; CHECK-NEXT:    movzbl -40(%rsp,%rdx), %eax
-; CHECK-NEXT:    pcmpeqb %xmm4, %xmm2
-; CHECK-NEXT:    pmovmskb %xmm2, %ecx
-; CHECK-NEXT:    xorl $65535, %ecx # imm = 0xFFFF
-; CHECK-NEXT:    cmovel %edi, %eax
-; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    retq
+define i8 @extract_last_active_split(<32 x i8> %data, <32 x i8> %mask, i8 %passthru) nounwind {
+; SSE2-LABEL: extract_last_active_split:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pxor %xmm4, %xmm4
+; SSE2-NEXT:    movdqa %xmm2, %xmm5
+; SSE2-NEXT:    por %xmm3, %xmm2
+; SSE2-NEXT:    pcmpeqb %xmm4, %xmm3
+; SSE2-NEXT:    pcmpeqb %xmm4, %xmm5
+; SSE2-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
+; SSE2-NEXT:    pandn %xmm0, %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[2,3,2,3]
+; SSE2-NEXT:    pmaxub %xmm5, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm1[1,1,1,1]
+; SSE2-NEXT:    pmaxub %xmm1, %xmm5
+; SSE2-NEXT:    movdqa %xmm5, %xmm1
+; SSE2-NEXT:    psrld $16, %xmm1
+; SSE2-NEXT:    pmaxub %xmm5, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm5
+; SSE2-NEXT:    psrlw $8, %xmm5
+; SSE2-NEXT:    pmaxub %xmm1, %xmm5
+; SSE2-NEXT:    movd %xmm5, %eax
+; SSE2-NEXT:    pmovmskb %xmm3, %ecx
+; SSE2-NEXT:    pandn %xmm0, %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3]
+; SSE2-NEXT:    pmaxub %xmm3, %xmm0
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; SSE2-NEXT:    pmaxub %xmm0, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:    psrld $16, %xmm0
+; SSE2-NEXT:    pmaxub %xmm1, %xmm0
+; SSE2-NEXT:    movdqa %xmm0, %xmm1
+; SSE2-NEXT:    psrlw $8, %xmm1
+; SSE2-NEXT:    pmaxub %xmm0, %xmm1
+; SSE2-NEXT:    movd %xmm1, %edx
+; SSE2-NEXT:    addl $16, %edx
+; SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
+; SSE2-NEXT:    cmoveq %rax, %rdx
+; SSE2-NEXT:    andl $31, %edx
+; SSE2-NEXT:    movzbl -40(%rsp,%rdx), %eax
+; SSE2-NEXT:    pcmpeqb %xmm4, %xmm2
+; SSE2-NEXT:    pmovmskb %xmm2, %ecx
+; SSE2-NEXT:    xorl $65535, %ecx # imm = 0xFFFF
+; SSE2-NEXT:    cmovel %edi, %eax
+; SSE2-NEXT:    # kill: def $al killed $al killed $eax
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: extract_last_active_split:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    pxor %xmm4, %xmm4
+; SSE42-NEXT:    movdqa %xmm2, %xmm5
+; SSE42-NEXT:    pcmpeqb %xmm4, %xmm5
+; SSE42-NEXT:    pcmpeqb %xmm3, %xmm4
+; SSE42-NEXT:    pcmpeqd %xmm6, %xmm6
+; SSE42-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; SSE42-NEXT:    movdqa {{.*#+}} xmm0 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
+; SSE42-NEXT:    pandn %xmm0, %xmm4
+; SSE42-NEXT:    pxor %xmm6, %xmm4
+; SSE42-NEXT:    movdqa %xmm4, %xmm1
+; SSE42-NEXT:    psrlw $8, %xmm1
+; SSE42-NEXT:    pminub %xmm4, %xmm1
+; SSE42-NEXT:    phminposuw %xmm1, %xmm1
+; SSE42-NEXT:    movd %xmm1, %eax
+; SSE42-NEXT:    notb %al
+; SSE42-NEXT:    movzbl %al, %eax
+; SSE42-NEXT:    addl $16, %eax
+; SSE42-NEXT:    pandn %xmm0, %xmm5
+; SSE42-NEXT:    pxor %xmm6, %xmm5
+; SSE42-NEXT:    movdqa %xmm5, %xmm0
+; SSE42-NEXT:    psrlw $8, %xmm0
+; SSE42-NEXT:    pminub %xmm5, %xmm0
+; SSE42-NEXT:    phminposuw %xmm0, %xmm0
+; SSE42-NEXT:    movd %xmm0, %ecx
+; SSE42-NEXT:    notb %cl
+; SSE42-NEXT:    movzbl %cl, %ecx
+; SSE42-NEXT:    ptest %xmm3, %xmm3
+; SSE42-NEXT:    cmovneq %rax, %rcx
+; SSE42-NEXT:    andl $31, %ecx
+; SSE42-NEXT:    por %xmm3, %xmm2
+; SSE42-NEXT:    ptest %xmm2, %xmm2
+; SSE42-NEXT:    movzbl -40(%rsp,%rcx), %eax
+; SSE42-NEXT:    cmovel %edi, %eax
+; SSE42-NEXT:    # kill: def $al killed $al killed $eax
+; SSE42-NEXT:    retq
+;
+; AVX2-LABEL: extract_last_active_split:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    pushq %rbp
+; AVX2-NEXT:    movq %rsp, %rbp
+; AVX2-NEXT:    andq $-32, %rsp
+; AVX2-NEXT:    subq $64, %rsp
+; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vpcmpeqb %ymm2, %ymm1, %ymm2
+; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
+; AVX2-NEXT:    vpandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm2, %ymm0
+; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
+; AVX2-NEXT:    vpmaxub %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrlw $8, %xmm0, %xmm2
+; AVX2-NEXT:    vpminub %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    notb %al
+; AVX2-NEXT:    movzbl %al, %eax
+; AVX2-NEXT:    andl $31, %eax
+; AVX2-NEXT:    movzbl (%rsp,%rax), %eax
+; AVX2-NEXT:    vptest %ymm1, %ymm1
+; AVX2-NEXT:    cmovel %edi, %eax
+; AVX2-NEXT:    # kill: def $al killed $al killed $eax
+; AVX2-NEXT:    movq %rbp, %rsp
+; AVX2-NEXT:    popq %rbp
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: extract_last_active_split:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    pushq %rbp
+; AVX512-NEXT:    movq %rsp, %rbp
+; AVX512-NEXT:    andq $-32, %rsp
+; AVX512-NEXT:    subq $64, %rsp
+; AVX512-NEXT:    vptestmb %ymm1, %ymm1, %k1
+; AVX512-NEXT:    vmovaps %ymm0, (%rsp)
+; AVX512-NEXT:    vmovdqu8 {{.*#+}} ymm0 {%k1} {z} = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
+; AVX512-NEXT:    vextracti128 $1, %ymm0, %xmm2
+; AVX512-NEXT:    vpmaxub %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    vpternlogq {{.*#+}} xmm0 = ~xmm0
+; AVX512-NEXT:    vpsrlw $8, %xmm0, %xmm2
+; AVX512-NEXT:    vpminub %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    vphminposuw %xmm0, %xmm0
+; AVX512-NEXT:    vmovd %xmm0, %eax
+; AVX512-NEXT:    notb %al
+; AVX512-NEXT:    movzbl %al, %eax
+; AVX512-NEXT:    andl $31, %eax
+; AVX512-NEXT:    movzbl (%rsp,%rax), %eax
+; AVX512-NEXT:    vptest %ymm1, %ymm1
+; AVX512-NEXT:    cmovel %edi, %eax
+; AVX512-NEXT:    # kill: def $al killed $al killed $eax
+; AVX512-NEXT:    movq %rbp, %rsp
+; AVX512-NEXT:    popq %rbp
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
   %notzero = icmp ne <32 x i8> %mask, zeroinitializer
   %res = call i8 @llvm.experimental.vector.extract.last.active.v16i8(<32 x i8> %data, <32 x i1> %notzero, i8 %passthru)
   ret i8 %res



More information about the llvm-commits mailing list