[llvm] [SLP]Keep originals when uniques do not reduce register uses (PR #218294)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 23 15:13:25 PDT 2026
https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/218294
When the vector of unqiues occupies the same register width as the
original (counting a sub-register vector as a full one), packing only
adds the reshuffle cost; keep the original vector. Loads are excluded
since packing may instead enable a wider contiguous load.
>From c8eb2a1354f153252428907092f48ab6d763829e Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sun, 23 Aug 2026 15:13:12 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
.../Transforms/Vectorize/SLPVectorizer.cpp | 19 ++++++++++++++++++-
.../X86/shl-to-add-transformation5.ll | 10 +++++-----
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 8d49f8b9fda9d..476ea4e3b2ee2 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -10981,8 +10981,25 @@ static bool tryToFindDuplicates(SmallVectorImpl<Value *> &VL,
/*Extract=*/false, CostKind,
AreAllValuesNonConst, UniqueValues);
UniquesCost += ReusesCost;
- if (UniquesCost <= InsertsCost)
+ if (UniquesCost <= InsertsCost) {
+ // Packing to a vector that occupies the same register width as the
+ // original only adds the reshuffle cost; keep the originals. Loads may
+ // instead benefit from a wider contiguous load.
+ if (S && S.getOpcode() != Instruction::Load) {
+ unsigned EltBits = S.getMainOp()
+ ->getDataLayout()
+ .getTypeSizeInBits(ScalarTy)
+ .getFixedValue();
+ unsigned MinVF = R.getMinVF(EltBits);
+ auto RegWidth = [&](unsigned N) {
+ return std::max(getFullVectorNumberOfElements(TTI, ScalarTy, N),
+ MinVF);
+ };
+ if (RegWidth(NumUniqueScalarValues) >= RegWidth(VL.size()))
+ return std::make_pair(true, true);
+ }
return std::make_pair(true, false);
+ }
InstructionCost CostDiff = UniquesCost - InsertsCost;
if (CostDiff < TTI::TCC_Expensive ||
(R.getTreeSize() == 0 && R.isReductionTree() &&
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll b/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
index 597fed290b9b0..6d9ef6f338af5 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
@@ -20,11 +20,11 @@ define i32 @test(i32 %0, i32 %1) {
; CHECK-NEXT: [[TMP10:%.*]] = insertelement <8 x i32> [[TMP9]], i32 [[TMP0]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = insertelement <8 x i32> [[TMP10]], i32 [[SUB120_3]], i64 5
; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <8 x i32> [[TMP11]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 2, i32 5, i32 6, i32 7>
-; CHECK-NEXT: [[TMP13:%.*]] = shufflevector <8 x i32> [[TMP11]], <8 x i32> poison, <5 x i32> <i32 2, i32 poison, i32 poison, i32 5, i32 poison>
-; CHECK-NEXT: [[TMP14:%.*]] = insertelement <5 x i32> [[TMP13]], i32 [[DOTNEG_NEG]], i64 1
-; CHECK-NEXT: [[TMP15:%.*]] = shufflevector <2 x i32> [[TMP7]], <2 x i32> poison, <5 x i32> <i32 0, i32 poison, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <5 x i32> [[TMP14]], <5 x i32> [[TMP15]], <5 x i32> <i32 0, i32 1, i32 5, i32 3, i32 7>
-; CHECK-NEXT: [[TMP17:%.*]] = shufflevector <5 x i32> [[TMP16]], <5 x i32> poison, <8 x i32> <i32 0, i32 1, i32 0, i32 2, i32 0, i32 3, i32 4, i32 2>
+; CHECK-NEXT: [[TMP13:%.*]] = shufflevector <8 x i32> [[TMP11]], <8 x i32> poison, <8 x i32> <i32 2, i32 poison, i32 2, i32 poison, i32 2, i32 5, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP14:%.*]] = insertelement <8 x i32> [[TMP13]], i32 [[DOTNEG_NEG]], i64 1
+; CHECK-NEXT: [[TMP15:%.*]] = shufflevector <2 x i32> [[TMP7]], <2 x i32> poison, <8 x i32> <i32 0, i32 poison, i32 poison, i32 1, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <8 x i32> [[TMP14]], <8 x i32> [[TMP15]], <8 x i32> <i32 0, i32 1, i32 2, i32 8, i32 4, i32 5, i32 11, i32 7>
+; CHECK-NEXT: [[TMP17:%.*]] = shufflevector <8 x i32> [[TMP16]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 3>
; CHECK-NEXT: [[TMP18:%.*]] = sub <8 x i32> [[TMP12]], [[TMP17]]
; CHECK-NEXT: [[TMP19:%.*]] = add <8 x i32> [[TMP12]], [[TMP17]]
; CHECK-NEXT: [[TMP20:%.*]] = shufflevector <8 x i32> [[TMP18]], <8 x i32> [[TMP19]], <8 x i32> <i32 0, i32 9, i32 10, i32 3, i32 12, i32 13, i32 6, i32 7>
More information about the llvm-commits
mailing list