[llvm-branch-commits] [llvm] [SLP]Add AShr as a main opcode for copyables (PR #207841)
Alexey Bataev via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jul 7 10:57:19 PDT 2026
https://github.com/alexey-bataev updated https://github.com/llvm/llvm-project/pull/207841
>From 61b2337aa121e1fbf2e80645fe3aba32bdeab9a4 Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Mon, 6 Jul 2026 14:05:08 -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 | 18 ++++++-----
.../RISCV/reordered-buildvector-scalars.ll | 30 ++++++++++---------
.../commutative-copyable-external-phi-use.ll | 4 +--
...yable-operand-non-scheduled-parent-node.ll | 2 +-
.../SLPVectorizer/X86/trunc-node-reused.ll | 13 +++++++-
5 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ea97a18403dc8..68e39290f0212 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11893,12 +11893,13 @@ class InstructionsCompatibilityAnalysis {
/// elements.
static bool isSupportedOpcode(const unsigned Opcode) {
return Opcode == Instruction::Add || Opcode == Instruction::Sub ||
- Opcode == Instruction::Mul || Opcode == Instruction::LShr ||
- Opcode == Instruction::Shl || Opcode == Instruction::SDiv ||
- Opcode == Instruction::UDiv || Opcode == Instruction::And ||
- Opcode == Instruction::Or || Opcode == Instruction::Xor ||
- Opcode == Instruction::FAdd || Opcode == Instruction::FSub ||
- Opcode == Instruction::FMul || Opcode == Instruction::FDiv;
+ Opcode == Instruction::Mul || Opcode == Instruction::AShr ||
+ Opcode == Instruction::LShr || Opcode == Instruction::Shl ||
+ Opcode == Instruction::SDiv || Opcode == Instruction::UDiv ||
+ Opcode == Instruction::And || Opcode == Instruction::Or ||
+ Opcode == Instruction::Xor || Opcode == Instruction::FAdd ||
+ Opcode == Instruction::FSub || Opcode == Instruction::FMul ||
+ Opcode == Instruction::FDiv;
}
/// Identifies the best candidate value, which represents main opcode
@@ -12521,6 +12522,7 @@ class InstructionsCompatibilityAnalysis {
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
+ case Instruction::AShr:
case Instruction::LShr:
case Instruction::Shl:
case Instruction::SDiv:
@@ -27197,9 +27199,11 @@ bool BoUpSLP::collectValuesToDemote(
return all_of(E.Scalars, [&](Value *V) {
if (isa<PoisonValue>(V))
return true;
+ unsigned ShiftedBits = OrigBitWidth - BitWidth;
+ if (E.isCopyableElement(V))
+ return ShiftedBits < ComputeNumSignBits(V, *DL, AC, nullptr, DT);
auto *I = cast<Instruction>(V);
KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL);
- unsigned ShiftedBits = OrigBitWidth - BitWidth;
return AmtKnownBits.getMaxValue().ult(BitWidth) &&
ShiftedBits <
ComputeNumSignBits(I->getOperand(0), *DL, AC, nullptr, DT);
diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/reordered-buildvector-scalars.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/reordered-buildvector-scalars.ll
index d7ae587833d2d..6c09ce4bc73fe 100644
--- a/llvm/test/Transforms/SLPVectorizer/RISCV/reordered-buildvector-scalars.ll
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/reordered-buildvector-scalars.ll
@@ -11,17 +11,17 @@ define fastcc i32 @test(i32 %0, i32 %add111.i.i, <4 x i32> %PredPel.i.sroa.86.72
; CHECK-LABEL: define fastcc i32 @test(
; CHECK-SAME: i32 [[TMP0:%.*]], i32 [[ADD111_I_I:%.*]], <4 x i32> [[PREDPEL_I_SROA_86_72_VEC_EXTRACT:%.*]], <4 x i32> [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[LOOPARRAY_SROA_24_0_I_I3:%.*]] = ashr i32 [[TMP0]], 1
-; CHECK-NEXT: [[SHR143_5_I_I9:%.*]] = ashr i32 [[TMP0]], 1
-; CHECK-NEXT: [[ADD1392_I:%.*]] = add i32 [[TMP0]], 1
; CHECK-NEXT: [[MUL1445_I:%.*]] = shl i32 [[TMP0]], 1
; CHECK-NEXT: [[ADD2235_I17:%.*]] = or i32 [[TMP0]], 1
; CHECK-NEXT: [[ADD2323_I1:%.*]] = add i32 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = insertelement <3 x i32> poison, i32 [[ADD111_I_I]], i32 0
-; CHECK-NEXT: [[TMP3:%.*]] = insertelement <3 x i32> [[TMP2]], i32 [[LOOPARRAY_SROA_24_0_I_I3]], i32 1
-; CHECK-NEXT: [[TMP4:%.*]] = insertelement <3 x i32> [[TMP3]], i32 [[ADD2323_I1]], i32 2
; CHECK-NEXT: [[TMP5:%.*]] = insertelement <3 x i32> poison, i32 [[TMP0]], i32 0
; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <3 x i32> [[TMP5]], <3 x i32> poison, <3 x i32> zeroinitializer
+; CHECK-NEXT: [[ADD1392_I:%.*]] = add i32 [[TMP0]], 1
+; CHECK-NEXT: [[SHR143_5_I_I9:%.*]] = ashr i32 [[TMP0]], 1
+; CHECK-NEXT: [[LOOPARRAY_SROA_24_0_I_I3:%.*]] = ashr i32 [[TMP0]], 1
+; CHECK-NEXT: [[TMP10:%.*]] = insertelement <3 x i32> [[TMP2]], i32 [[LOOPARRAY_SROA_24_0_I_I3]], i32 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertelement <3 x i32> [[TMP10]], i32 [[ADD2323_I1]], i32 2
; CHECK-NEXT: [[TMP7:%.*]] = or <3 x i32> [[TMP4]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <4 x i32> [[PREDPEL_I_SROA_86_72_VEC_EXTRACT]], <4 x i32> [[TMP1]], <8 x i32> <i32 0, i32 poison, i32 poison, i32 4, i32 poison, i32 poison, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP9:%.*]] = insertelement <8 x i32> [[TMP8]], i32 [[TMP0]], i32 4
@@ -53,17 +53,20 @@ define fastcc i32 @test(i32 %0, i32 %add111.i.i, <4 x i32> %PredPel.i.sroa.86.72
; THRESH-LABEL: define fastcc i32 @test(
; THRESH-SAME: i32 [[TMP0:%.*]], i32 [[ADD111_I_I:%.*]], <4 x i32> [[PREDPEL_I_SROA_86_72_VEC_EXTRACT:%.*]], <4 x i32> [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
; THRESH-NEXT: [[ENTRY:.*:]]
-; THRESH-NEXT: [[LOOPARRAY_SROA_24_0_I_I3:%.*]] = ashr i32 [[TMP0]], 1
-; THRESH-NEXT: [[SHR143_5_I_I9:%.*]] = ashr i32 [[TMP0]], 1
-; THRESH-NEXT: [[ADD1392_I:%.*]] = add i32 [[TMP0]], 1
; THRESH-NEXT: [[MUL1445_I:%.*]] = shl i32 [[TMP0]], 1
; THRESH-NEXT: [[ADD2235_I16:%.*]] = or i32 [[TMP0]], 1
; THRESH-NEXT: [[ADD2323_I:%.*]] = add i32 [[TMP0]], 1
+; THRESH-NEXT: [[TMP30:%.*]] = insertelement <2 x i32> poison, i32 [[TMP0]], i32 0
+; THRESH-NEXT: [[TMP31:%.*]] = shufflevector <2 x i32> [[TMP30]], <2 x i32> poison, <2 x i32> zeroinitializer
+; THRESH-NEXT: [[TMP32:%.*]] = add <2 x i32> [[TMP31]], <i32 0, i32 1>
+; THRESH-NEXT: [[TMP5:%.*]] = shufflevector <2 x i32> [[TMP32]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 0>
+; THRESH-NEXT: [[TMP21:%.*]] = ashr <4 x i32> [[TMP5]], <i32 1, i32 0, i32 0, i32 1>
; THRESH-NEXT: [[TMP2:%.*]] = insertelement <3 x i32> poison, i32 [[ADD111_I_I]], i32 0
-; THRESH-NEXT: [[TMP3:%.*]] = insertelement <3 x i32> [[TMP2]], i32 [[LOOPARRAY_SROA_24_0_I_I3]], i32 1
+; THRESH-NEXT: [[TMP33:%.*]] = shufflevector <4 x i32> [[TMP21]], <4 x i32> poison, <3 x i32> <i32 0, i32 poison, i32 poison>
+; THRESH-NEXT: [[TMP34:%.*]] = shufflevector <3 x i32> [[TMP2]], <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
+; THRESH-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[TMP34]], <4 x i32> [[TMP21]], <3 x i32> <i32 0, i32 4, i32 poison>
; THRESH-NEXT: [[TMP4:%.*]] = insertelement <3 x i32> [[TMP3]], i32 [[ADD2323_I]], i32 2
-; THRESH-NEXT: [[TMP5:%.*]] = insertelement <3 x i32> poison, i32 [[TMP0]], i32 0
-; THRESH-NEXT: [[TMP6:%.*]] = shufflevector <3 x i32> [[TMP5]], <3 x i32> poison, <3 x i32> zeroinitializer
+; THRESH-NEXT: [[TMP6:%.*]] = shufflevector <2 x i32> [[TMP31]], <2 x i32> poison, <3 x i32> zeroinitializer
; THRESH-NEXT: [[TMP7:%.*]] = or <3 x i32> [[TMP4]], [[TMP6]]
; THRESH-NEXT: [[TMP8:%.*]] = shufflevector <4 x i32> [[PREDPEL_I_SROA_86_72_VEC_EXTRACT]], <4 x i32> [[TMP1]], <8 x i32> <i32 0, i32 poison, i32 poison, i32 4, i32 poison, i32 poison, i32 poison, i32 poison>
; THRESH-NEXT: [[TMP9:%.*]] = shufflevector <3 x i32> [[TMP4]], <3 x i32> poison, <8 x i32> <i32 poison, i32 poison, i32 1, i32 poison, i32 poison, i32 poison, i32 0, i32 poison>
@@ -71,14 +74,13 @@ define fastcc i32 @test(i32 %0, i32 %add111.i.i, <4 x i32> %PredPel.i.sroa.86.72
; THRESH-NEXT: [[TMP11:%.*]] = insertelement <8 x i32> [[TMP10]], i32 [[TMP0]], i32 4
; THRESH-NEXT: [[TMP12:%.*]] = insertelement <8 x i32> [[TMP11]], i32 [[ADD2235_I16]], i32 1
; THRESH-NEXT: [[TMP13:%.*]] = insertelement <8 x i32> [[TMP12]], i32 [[MUL1445_I]], i32 5
-; THRESH-NEXT: [[TMP14:%.*]] = insertelement <8 x i32> [[TMP13]], i32 [[SHR143_5_I_I9]], i32 7
+; THRESH-NEXT: [[TMP20:%.*]] = shufflevector <4 x i32> [[TMP21]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; THRESH-NEXT: [[TMP14:%.*]] = shufflevector <8 x i32> [[TMP13]], <8 x i32> [[TMP20]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
; THRESH-NEXT: [[TMP15:%.*]] = add <8 x i32> [[TMP14]], <i32 1, i32 1, i32 1, i32 1, i32 1, i32 2, i32 1, i32 1>
; THRESH-NEXT: [[TMP16:%.*]] = shufflevector <8 x i32> [[TMP15]], <8 x i32> poison, <11 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison>
; THRESH-NEXT: [[TMP17:%.*]] = shufflevector <3 x i32> [[TMP7]], <3 x i32> poison, <11 x i32> <i32 0, i32 1, i32 2, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
; THRESH-NEXT: [[TMP18:%.*]] = shufflevector <11 x i32> [[TMP16]], <11 x i32> [[TMP17]], <11 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 11, i32 12, i32 13>
; THRESH-NEXT: [[TMP19:%.*]] = lshr <11 x i32> [[TMP18]], <i32 1, i32 1, i32 1, i32 1, i32 1, i32 2, i32 1, i32 1, i32 1, i32 1, i32 1>
-; THRESH-NEXT: [[TMP20:%.*]] = shufflevector <8 x i32> [[TMP14]], <8 x i32> poison, <4 x i32> <i32 2, i32 poison, i32 4, i32 7>
-; THRESH-NEXT: [[TMP21:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[ADD1392_I]], i32 1
; THRESH-NEXT: [[TMP22:%.*]] = or <4 x i32> [[TMP21]], splat (i32 1)
; THRESH-NEXT: [[TMP23:%.*]] = shufflevector <8 x i32> [[TMP14]], <8 x i32> poison, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
; THRESH-NEXT: [[TMP24:%.*]] = add <4 x i32> [[TMP22]], [[TMP23]]
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/commutative-copyable-external-phi-use.ll b/llvm/test/Transforms/SLPVectorizer/X86/commutative-copyable-external-phi-use.ll
index 263fff4c64fa9..aa00686d399ff 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/commutative-copyable-external-phi-use.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/commutative-copyable-external-phi-use.ll
@@ -4,7 +4,7 @@
define void @test(i32 %arg) {
; CHECK-LABEL: define void @test(
; CHECK-SAME: i32 [[ARG:%.*]]) {
-; CHECK-NEXT: [[BB:.*]]:
+; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[ARG]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> zeroinitializer, [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i32> zeroinitializer, [[TMP0]]
@@ -25,7 +25,7 @@ define void @test(i32 %arg) {
; CHECK-NEXT: [[TMP11:%.*]] = lshr <2 x i32> [[TMP10]], zeroinitializer
; CHECK-NEXT: [[TMP12:%.*]] = or <2 x i32> [[TMP10]], zeroinitializer
; CHECK-NEXT: [[TMP13:%.*]] = shufflevector <2 x i32> [[TMP11]], <2 x i32> [[TMP12]], <2 x i32> <i32 0, i32 3>
-; CHECK-NEXT: [[TMP14]] = or <2 x i32> [[TMP13]], zeroinitializer
+; CHECK-NEXT: [[TMP14]] = ashr <2 x i32> [[TMP13]], zeroinitializer
; CHECK-NEXT: br label %[[BB2]]
;
bb:
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/copyable-operand-non-scheduled-parent-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/copyable-operand-non-scheduled-parent-node.ll
index 7c25d04d9112d..cdd7e64d4a3cb 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/copyable-operand-non-scheduled-parent-node.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/copyable-operand-non-scheduled-parent-node.ll
@@ -18,7 +18,7 @@ define void @test(i32 %arg) {
; CHECK-NEXT: [[TMP6:%.*]] = lshr <2 x i32> [[TMP5]], zeroinitializer
; CHECK-NEXT: [[TMP7:%.*]] = or <2 x i32> [[TMP5]], zeroinitializer
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <2 x i32> [[TMP6]], <2 x i32> [[TMP7]], <2 x i32> <i32 2, i32 1>
-; CHECK-NEXT: [[TMP9:%.*]] = add <2 x i32> [[TMP8]], zeroinitializer
+; CHECK-NEXT: [[TMP9:%.*]] = ashr <2 x i32> [[TMP8]], zeroinitializer
; CHECK-NEXT: br label %[[BB5:.*]]
; CHECK: [[BB5]]:
; CHECK-NEXT: [[TMP10:%.*]] = phi <2 x i32> [ [[TMP9]], %[[BB4]] ]
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/trunc-node-reused.ll b/llvm/test/Transforms/SLPVectorizer/X86/trunc-node-reused.ll
index 8eec4142f2a2f..e1da5c147dcbf 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/trunc-node-reused.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/trunc-node-reused.ll
@@ -4,7 +4,18 @@
define i16 @test() {
; CHECK-LABEL: define i16 @test() {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: ret i16 0
+; CHECK-NEXT: [[TMP0:%.*]] = or <4 x i1> zeroinitializer, zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = shl <4 x i1> [[TMP0]], zeroinitializer
+; CHECK-NEXT: [[TMP2:%.*]] = ashr <4 x i1> [[TMP1]], zeroinitializer
+; CHECK-NEXT: [[TMP3:%.*]] = xor <4 x i1> [[TMP2]], zeroinitializer
+; CHECK-NEXT: [[TMP4:%.*]] = xor <4 x i1> zeroinitializer, [[TMP3]]
+; CHECK-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP4]], zeroinitializer
+; CHECK-NEXT: [[TMP6:%.*]] = icmp slt <4 x i1> [[TMP5]], zeroinitializer
+; CHECK-NEXT: [[TMP7:%.*]] = or <4 x i1> zeroinitializer, [[TMP3]]
+; CHECK-NEXT: [[TMP8:%.*]] = select <4 x i1> [[TMP6]], <4 x i1> zeroinitializer, <4 x i1> [[TMP7]]
+; CHECK-NEXT: [[TMP9:%.*]] = sext <4 x i1> [[TMP8]] to <4 x i16>
+; CHECK-NEXT: [[TMP10:%.*]] = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> [[TMP9]])
+; CHECK-NEXT: ret i16 [[TMP10]]
;
entry:
%conv73 = xor i64 0, 0
More information about the llvm-branch-commits
mailing list