[llvm] [X86] lowerShuffleWithPSHUFB - use getConstVector to create shuffle mask (PR #201122)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 06:41:38 PDT 2026
https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/201122
Avoids wasteful SDValue creation if the shuffle matching fails - and makes it easier to match+merge compatible constant pool entries
>From 4b3994f87278bddfb489e9fb61621b8261ce241a Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 2 Jun 2026 14:15:49 +0100
Subject: [PATCH] [X86] lowerShuffleWithPSHUFB - use getConstVector to create
shuffle mask
Avoids wasteful SDValue creation if the shuffle matching fails - and makes it easier to match+merge compatible constant pool entries
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 21 ++++-----
.../X86/shuffle-strided-with-offset-512.ll | 5 ++-
llvm/test/CodeGen/X86/shuffle-vs-trunc-512.ll | 10 +++--
.../vector-interleaved-load-i8-stride-2.ll | 44 ++++++++++---------
4 files changed, 42 insertions(+), 38 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6c5e682a41542..6bf0e466104fe 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -10982,19 +10982,16 @@ static SDValue lowerShuffleWithPSHUFB(const SDLoc &DL, MVT VT,
(Subtarget.hasAVX2() && VT.is256BitVector()) ||
(Subtarget.hasBWI() && VT.is512BitVector()));
- SmallVector<SDValue, 64> PSHUFBMask(NumBytes);
- // Sign bit set in i8 mask means zero element.
- SDValue ZeroMask = DAG.getConstant(0x80, DL, MVT::i8);
-
+ SmallVector<int, 64> PSHUFBMask(NumBytes, -1);
SDValue V;
for (int i = 0; i < NumBytes; ++i) {
int M = Mask[i / NumEltBytes];
- if (M < 0) {
- PSHUFBMask[i] = DAG.getUNDEF(MVT::i8);
+ if (M < 0)
continue;
- }
+
if (Zeroable[i / NumEltBytes]) {
- PSHUFBMask[i] = ZeroMask;
+ // Sign bit set in i8 mask means zero element.
+ PSHUFBMask[i] = 0x80;
continue;
}
@@ -11011,14 +11008,14 @@ static SDValue lowerShuffleWithPSHUFB(const SDLoc &DL, MVT VT,
M = M % LaneSize;
M = M * NumEltBytes + (i % NumEltBytes);
- PSHUFBMask[i] = DAG.getConstant(M, DL, MVT::i8);
+ PSHUFBMask[i] = M;
}
assert(V && "Failed to find a source input");
MVT I8VT = MVT::getVectorVT(MVT::i8, NumBytes);
- return DAG.getBitcast(
- VT, DAG.getNode(X86ISD::PSHUFB, DL, I8VT, DAG.getBitcast(I8VT, V),
- DAG.getBuildVector(I8VT, DL, PSHUFBMask)));
+ SDValue R = getConstVector(PSHUFBMask, I8VT, DAG, DL, /*IsMask=*/true);
+ R = DAG.getNode(X86ISD::PSHUFB, DL, I8VT, DAG.getBitcast(I8VT, V), R);
+ return DAG.getBitcast(VT, R);
}
/// Return Mask with the necessary casting or extending
diff --git a/llvm/test/CodeGen/X86/shuffle-strided-with-offset-512.ll b/llvm/test/CodeGen/X86/shuffle-strided-with-offset-512.ll
index 571915b47d297..4ba0a8fc5e1ca 100644
--- a/llvm/test/CodeGen/X86/shuffle-strided-with-offset-512.ll
+++ b/llvm/test/CodeGen/X86/shuffle-strided-with-offset-512.ll
@@ -25,8 +25,9 @@ define void @shuffle_v64i8_to_v32i8_1(ptr %L, ptr %S) nounwind {
; AVX512VL-FAST-ALL: # %bb.0:
; AVX512VL-FAST-ALL-NEXT: vmovdqa (%rdi), %ymm0
; AVX512VL-FAST-ALL-NEXT: vmovdqa 32(%rdi), %ymm1
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm1 = ymm1[u,u,u,u,u,u,u,u,1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31]
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31,u,u,u,u,u,u,u,u]
+; AVX512VL-FAST-ALL-NEXT: vpbroadcastq {{.*#+}} ymm2 = [1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15]
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm1, %ymm1
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm0, %ymm0
; AVX512VL-FAST-ALL-NEXT: vpmovsxbq {{.*#+}} ymm2 = [0,2,5,7]
; AVX512VL-FAST-ALL-NEXT: vpermi2q %ymm1, %ymm0, %ymm2
; AVX512VL-FAST-ALL-NEXT: vmovdqa %ymm2, (%rsi)
diff --git a/llvm/test/CodeGen/X86/shuffle-vs-trunc-512.ll b/llvm/test/CodeGen/X86/shuffle-vs-trunc-512.ll
index e27a77ed2293d..440e793f9d521 100644
--- a/llvm/test/CodeGen/X86/shuffle-vs-trunc-512.ll
+++ b/llvm/test/CodeGen/X86/shuffle-vs-trunc-512.ll
@@ -33,8 +33,9 @@ define void @shuffle_v64i8_to_v32i8(ptr %L, ptr %S) nounwind {
; AVX512VL-FAST-ALL: # %bb.0:
; AVX512VL-FAST-ALL-NEXT: vmovdqa (%rdi), %ymm0
; AVX512VL-FAST-ALL-NEXT: vmovdqa 32(%rdi), %ymm1
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm1 = ymm1[u,u,u,u,u,u,u,u,0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30]
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30,u,u,u,u,u,u,u,u]
+; AVX512VL-FAST-ALL-NEXT: vpbroadcastq {{.*#+}} ymm2 = [0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14]
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm1, %ymm1
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm0, %ymm0
; AVX512VL-FAST-ALL-NEXT: vpmovsxbq {{.*#+}} ymm2 = [0,2,5,7]
; AVX512VL-FAST-ALL-NEXT: vpermi2q %ymm1, %ymm0, %ymm2
; AVX512VL-FAST-ALL-NEXT: vmovdqa %ymm2, (%rsi)
@@ -341,8 +342,9 @@ define <32 x i8> @trunc_shuffle_v32i16_v32i8_ofs1(<32 x i16> %a0) {
; AVX512VL-FAST-ALL-LABEL: trunc_shuffle_v32i16_v32i8_ofs1:
; AVX512VL-FAST-ALL: # %bb.0:
; AVX512VL-FAST-ALL-NEXT: vextracti64x4 $1, %zmm0, %ymm1
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm1 = ymm1[u,u,u,u,u,u,u,u,1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31]
-; AVX512VL-FAST-ALL-NEXT: vpshufb {{.*#+}} ymm2 = ymm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31,u,u,u,u,u,u,u,u]
+; AVX512VL-FAST-ALL-NEXT: vpbroadcastq {{.*#+}} ymm2 = [1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15]
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm1, %ymm1
+; AVX512VL-FAST-ALL-NEXT: vpshufb %ymm2, %ymm0, %ymm2
; AVX512VL-FAST-ALL-NEXT: vpmovsxbq {{.*#+}} ymm0 = [0,2,5,7]
; AVX512VL-FAST-ALL-NEXT: vpermi2q %ymm1, %ymm2, %ymm0
; AVX512VL-FAST-ALL-NEXT: retq
diff --git a/llvm/test/CodeGen/X86/vector-interleaved-load-i8-stride-2.ll b/llvm/test/CodeGen/X86/vector-interleaved-load-i8-stride-2.ll
index b609299e5f757..440e0187d69f3 100644
--- a/llvm/test/CodeGen/X86/vector-interleaved-load-i8-stride-2.ll
+++ b/llvm/test/CodeGen/X86/vector-interleaved-load-i8-stride-2.ll
@@ -719,17 +719,19 @@ define void @load_i8_stride2_vf32(ptr %in.vec, ptr %out.vec0, ptr %out.vec1) nou
;
; AVX512-FCP-LABEL: load_i8_stride2_vf32:
; AVX512-FCP: # %bb.0:
-; AVX512-FCP-NEXT: vmovdqa (%rdi), %ymm0
-; AVX512-FCP-NEXT: vmovdqa 32(%rdi), %ymm1
-; AVX512-FCP-NEXT: vpshufb {{.*#+}} ymm2 = ymm1[u,u,u,u,u,u,u,u,0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30]
-; AVX512-FCP-NEXT: vpshufb {{.*#+}} ymm3 = ymm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30,u,u,u,u,u,u,u,u]
+; AVX512-FCP-NEXT: vpbroadcastq {{.*#+}} ymm0 = [0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14]
+; AVX512-FCP-NEXT: vmovdqa (%rdi), %ymm1
+; AVX512-FCP-NEXT: vmovdqa 32(%rdi), %ymm2
+; AVX512-FCP-NEXT: vpshufb %ymm0, %ymm2, %ymm3
+; AVX512-FCP-NEXT: vpshufb %ymm0, %ymm1, %ymm0
; AVX512-FCP-NEXT: vpmovsxbq {{.*#+}} ymm4 = [0,2,5,7]
-; AVX512-FCP-NEXT: vpermt2q %ymm2, %ymm4, %ymm3
-; AVX512-FCP-NEXT: vpshufb {{.*#+}} ymm1 = ymm1[u,u,u,u,u,u,u,u,1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31]
-; AVX512-FCP-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31,u,u,u,u,u,u,u,u]
-; AVX512-FCP-NEXT: vpermt2q %ymm1, %ymm4, %ymm0
-; AVX512-FCP-NEXT: vmovdqa %ymm3, (%rsi)
-; AVX512-FCP-NEXT: vmovdqa %ymm0, (%rdx)
+; AVX512-FCP-NEXT: vpermt2q %ymm3, %ymm4, %ymm0
+; AVX512-FCP-NEXT: vpbroadcastq {{.*#+}} ymm3 = [1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15]
+; AVX512-FCP-NEXT: vpshufb %ymm3, %ymm2, %ymm2
+; AVX512-FCP-NEXT: vpshufb %ymm3, %ymm1, %ymm1
+; AVX512-FCP-NEXT: vpermt2q %ymm2, %ymm4, %ymm1
+; AVX512-FCP-NEXT: vmovdqa %ymm0, (%rsi)
+; AVX512-FCP-NEXT: vmovdqa %ymm1, (%rdx)
; AVX512-FCP-NEXT: vzeroupper
; AVX512-FCP-NEXT: retq
;
@@ -754,17 +756,19 @@ define void @load_i8_stride2_vf32(ptr %in.vec, ptr %out.vec0, ptr %out.vec1) nou
;
; AVX512DQ-FCP-LABEL: load_i8_stride2_vf32:
; AVX512DQ-FCP: # %bb.0:
-; AVX512DQ-FCP-NEXT: vmovdqa (%rdi), %ymm0
-; AVX512DQ-FCP-NEXT: vmovdqa 32(%rdi), %ymm1
-; AVX512DQ-FCP-NEXT: vpshufb {{.*#+}} ymm2 = ymm1[u,u,u,u,u,u,u,u,0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30]
-; AVX512DQ-FCP-NEXT: vpshufb {{.*#+}} ymm3 = ymm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u,16,18,20,22,24,26,28,30,u,u,u,u,u,u,u,u]
+; AVX512DQ-FCP-NEXT: vpbroadcastq {{.*#+}} ymm0 = [0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14]
+; AVX512DQ-FCP-NEXT: vmovdqa (%rdi), %ymm1
+; AVX512DQ-FCP-NEXT: vmovdqa 32(%rdi), %ymm2
+; AVX512DQ-FCP-NEXT: vpshufb %ymm0, %ymm2, %ymm3
+; AVX512DQ-FCP-NEXT: vpshufb %ymm0, %ymm1, %ymm0
; AVX512DQ-FCP-NEXT: vpmovsxbq {{.*#+}} ymm4 = [0,2,5,7]
-; AVX512DQ-FCP-NEXT: vpermt2q %ymm2, %ymm4, %ymm3
-; AVX512DQ-FCP-NEXT: vpshufb {{.*#+}} ymm1 = ymm1[u,u,u,u,u,u,u,u,1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31]
-; AVX512DQ-FCP-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u,17,19,21,23,25,27,29,31,u,u,u,u,u,u,u,u]
-; AVX512DQ-FCP-NEXT: vpermt2q %ymm1, %ymm4, %ymm0
-; AVX512DQ-FCP-NEXT: vmovdqa %ymm3, (%rsi)
-; AVX512DQ-FCP-NEXT: vmovdqa %ymm0, (%rdx)
+; AVX512DQ-FCP-NEXT: vpermt2q %ymm3, %ymm4, %ymm0
+; AVX512DQ-FCP-NEXT: vpbroadcastq {{.*#+}} ymm3 = [1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15]
+; AVX512DQ-FCP-NEXT: vpshufb %ymm3, %ymm2, %ymm2
+; AVX512DQ-FCP-NEXT: vpshufb %ymm3, %ymm1, %ymm1
+; AVX512DQ-FCP-NEXT: vpermt2q %ymm2, %ymm4, %ymm1
+; AVX512DQ-FCP-NEXT: vmovdqa %ymm0, (%rsi)
+; AVX512DQ-FCP-NEXT: vmovdqa %ymm1, (%rdx)
; AVX512DQ-FCP-NEXT: vzeroupper
; AVX512DQ-FCP-NEXT: retq
;
More information about the llvm-commits
mailing list