[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