[llvm] 3deeb01 - [SLP]Fix dep accounting when cancelling a bundle with repeated copyable users
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 04:42:50 PDT 2026
Author: Alexey Bataev
Date: 2026-09-13T07:42:46-04:00
New Revision: 3deeb018ed1d1c61ad9e1798161128e0202e7920
URL: https://github.com/llvm/llvm-project/commit/3deeb018ed1d1c61ad9e1798161128e0202e7920
DIFF: https://github.com/llvm/llvm-project/commit/3deeb018ed1d1c61ad9e1798161128e0202e7920.diff
LOG: [SLP]Fix dep accounting when cancelling a bundle with repeated copyable users
Skip duplicate users instead of stopping at the first one when walking
the operand lanes; an early stop misses a trailing self-use lane, the
displaced parent-edge copyable data is never restored, and scheduling
asserts.
Fixes #223225
Reviewers:
Pull Request: https://github.com/llvm/llvm-project/pull/223236
Added:
llvm/test/Transforms/SLPVectorizer/X86/cancelled-copyable-self-use-deps-2.ll
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index d7c96346feca0..4feedf5febff3 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -26184,7 +26184,7 @@ BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *> VL, BoUpSLP *SLP,
auto *In = cast<Instruction>(EI.UserTE->Scalars[Lane]);
if (!Visited.insert(In).second) {
It = find(make_range(std::next(It), Op.end()), I);
- break;
+ continue;
}
HadSelfUse |= In == I;
ScheduleCopyableDataMapByInstUser
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/cancelled-copyable-self-use-deps-2.ll b/llvm/test/Transforms/SLPVectorizer/X86/cancelled-copyable-self-use-deps-2.ll
new file mode 100644
index 0000000000000..994639ee9e422
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/cancelled-copyable-self-use-deps-2.ll
@@ -0,0 +1,180 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s
+
+define i32 @test(ptr %0, ptr %1, ptr %2, i8 %3, i32 %4, i32 %5) {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]], i8 [[TMP3:%.*]], i32 [[TMP4:%.*]], i32 [[TMP5:%.*]]) {
+; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP7]] to i32
+; CHECK-NEXT: [[TMP9:%.*]] = shl i32 [[TMP8]], 1
+; CHECK-NEXT: [[TMP10:%.*]] = zext i8 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP11:%.*]] = shl i32 [[TMP10]], 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP13:%.*]] = shl i32 [[TMP12]], 1
+; CHECK-NEXT: [[TMP14:%.*]] = add i32 [[TMP4]], [[TMP9]]
+; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP14]], 1
+; CHECK-NEXT: [[TMP16:%.*]] = lshr i32 [[TMP15]], 1
+; CHECK-NEXT: [[TMP17:%.*]] = trunc i32 [[TMP16]] to i8
+; CHECK-NEXT: store i8 [[TMP17]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP18:%.*]] = add i32 [[TMP11]], [[TMP4]]
+; CHECK-NEXT: [[TMP19:%.*]] = add i32 [[TMP18]], 1
+; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP19]], 1
+; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i8
+; CHECK-NEXT: store i8 [[TMP21]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP22:%.*]] = add i32 [[TMP13]], [[TMP4]]
+; CHECK-NEXT: [[TMP23:%.*]] = add i32 [[TMP22]], 1
+; CHECK-NEXT: [[TMP24:%.*]] = lshr i32 [[TMP23]], 1
+; CHECK-NEXT: [[TMP25:%.*]] = trunc i32 [[TMP24]] to i8
+; CHECK-NEXT: store i8 [[TMP25]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP26:%.*]] = zext i8 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP27:%.*]] = shl i32 [[TMP26]], 1
+; CHECK-NEXT: [[TMP28:%.*]] = add i32 [[TMP27]], [[TMP4]]
+; CHECK-NEXT: [[TMP29:%.*]] = add i32 [[TMP28]], 1
+; CHECK-NEXT: [[TMP30:%.*]] = lshr i32 [[TMP29]], 1
+; CHECK-NEXT: store i32 [[TMP30]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP31:%.*]] = zext i8 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP32:%.*]] = shl i32 [[TMP31]], 1
+; CHECK-NEXT: [[TMP33:%.*]] = or i32 [[TMP32]], [[TMP4]]
+; CHECK-NEXT: [[TMP34:%.*]] = or i32 [[TMP33]], [[TMP5]]
+; CHECK-NEXT: [[TMP35:%.*]] = lshr i32 [[TMP34]], 1
+; CHECK-NEXT: [[TMP36:%.*]] = trunc i32 [[TMP35]] to i8
+; CHECK-NEXT: store i8 [[TMP36]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP37:%.*]] = add i32 [[TMP27]], [[TMP4]]
+; CHECK-NEXT: [[TMP38:%.*]] = add i32 [[TMP37]], 1
+; CHECK-NEXT: [[TMP39:%.*]] = lshr i32 [[TMP38]], 1
+; CHECK-NEXT: [[TMP40:%.*]] = trunc i32 [[TMP39]] to i8
+; CHECK-NEXT: store i8 [[TMP40]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP41:%.*]] = or i32 [[TMP26]], 1
+; CHECK-NEXT: [[TMP42:%.*]] = add i32 [[TMP41]], 1
+; CHECK-NEXT: [[TMP43:%.*]] = lshr i32 [[TMP42]], 1
+; CHECK-NEXT: [[TMP44:%.*]] = trunc i32 [[TMP43]] to i8
+; CHECK-NEXT: store i8 [[TMP44]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP45:%.*]] = or i32 [[TMP4]], [[TMP8]]
+; CHECK-NEXT: [[TMP46:%.*]] = or i32 [[TMP45]], [[TMP5]]
+; CHECK-NEXT: [[TMP47:%.*]] = lshr i32 [[TMP46]], 1
+; CHECK-NEXT: [[TMP48:%.*]] = trunc i32 [[TMP47]] to i8
+; CHECK-NEXT: store i8 [[TMP48]], ptr [[TMP2]], align 1
+; CHECK-NEXT: [[TMP49:%.*]] = add i32 [[TMP11]], [[TMP4]]
+; CHECK-NEXT: [[TMP50:%.*]] = add i32 [[TMP49]], 1
+; CHECK-NEXT: [[TMP51:%.*]] = lshr i32 [[TMP50]], 1
+; CHECK-NEXT: [[TMP52:%.*]] = trunc i32 [[TMP51]] to i8
+; CHECK-NEXT: store i8 [[TMP52]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP53:%.*]] = add i32 [[TMP8]], 1
+; CHECK-NEXT: [[TMP54:%.*]] = lshr i32 [[TMP53]], 1
+; CHECK-NEXT: [[TMP55:%.*]] = trunc i32 [[TMP54]] to i8
+; CHECK-NEXT: store i8 [[TMP55]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP56:%.*]] = add i32 [[TMP8]], 1
+; CHECK-NEXT: [[TMP57:%.*]] = or i32 [[TMP56]], [[TMP4]]
+; CHECK-NEXT: [[TMP58:%.*]] = lshr i32 [[TMP57]], 1
+; CHECK-NEXT: [[TMP59:%.*]] = trunc i32 [[TMP58]] to i8
+; CHECK-NEXT: store i8 [[TMP59]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP60:%.*]] = add i32 [[TMP10]], 1
+; CHECK-NEXT: [[TMP61:%.*]] = lshr i32 [[TMP60]], 1
+; CHECK-NEXT: [[TMP62:%.*]] = trunc i32 [[TMP61]] to i8
+; CHECK-NEXT: store i8 [[TMP62]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP63:%.*]] = zext i8 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP64:%.*]] = add i32 [[TMP63]], 1
+; CHECK-NEXT: [[TMP65:%.*]] = lshr i32 [[TMP64]], 1
+; CHECK-NEXT: [[TMP66:%.*]] = trunc i32 [[TMP65]] to i8
+; CHECK-NEXT: store i8 [[TMP66]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP67:%.*]] = add i32 [[TMP13]], [[TMP4]]
+; CHECK-NEXT: [[TMP68:%.*]] = add i32 [[TMP67]], 1
+; CHECK-NEXT: [[TMP69:%.*]] = lshr i32 [[TMP68]], 1
+; CHECK-NEXT: [[TMP70:%.*]] = trunc i32 [[TMP69]] to i8
+; CHECK-NEXT: store i8 [[TMP70]], ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP71:%.*]] = add i32 [[TMP63]], 1
+; CHECK-NEXT: [[TMP72:%.*]] = add i32 [[TMP71]], [[TMP4]]
+; CHECK-NEXT: [[TMP73:%.*]] = lshr i32 [[TMP72]], 1
+; CHECK-NEXT: [[TMP74:%.*]] = trunc i32 [[TMP73]] to i8
+; CHECK-NEXT: store i8 [[TMP74]], ptr [[TMP0]], align 1
+; CHECK-NEXT: [[TMP75:%.*]] = or i32 [[TMP4]], [[TMP63]]
+; CHECK-NEXT: [[TMP76:%.*]] = lshr i32 [[TMP75]], 1
+; CHECK-NEXT: ret i32 [[TMP76]]
+;
+ %7 = load i8, ptr %0, align 1
+ %8 = zext i8 %7 to i32
+ %9 = shl i32 %8, 1
+ %10 = zext i8 %3 to i32
+ %11 = shl i32 %10, 1
+ %12 = zext i8 %3 to i32
+ %13 = shl i32 %12, 1
+ %14 = add i32 %4, %9
+ %15 = add i32 %14, 1
+ %16 = lshr i32 %15, 1
+ %17 = trunc i32 %16 to i8
+ store i8 %17, ptr %0, align 1
+ %18 = add i32 %11, %4
+ %19 = add i32 %18, 1
+ %20 = lshr i32 %19, 1
+ %21 = trunc i32 %20 to i8
+ store i8 %21, ptr %1, align 1
+ %22 = add i32 %13, %4
+ %23 = add i32 %22, 1
+ %24 = lshr i32 %23, 1
+ %25 = trunc i32 %24 to i8
+ store i8 %25, ptr %0, align 1
+ %26 = zext i8 %3 to i32
+ %27 = shl i32 %26, 1
+ %28 = add i32 %27, %4
+ %29 = add i32 %28, 1
+ %30 = lshr i32 %29, 1
+ store i32 %30, ptr %0, align 1
+ %31 = zext i8 %3 to i32
+ %32 = shl i32 %31, 1
+ %33 = or i32 %32, %4
+ %34 = or i32 %33, %5
+ %35 = lshr i32 %34, 1
+ %36 = trunc i32 %35 to i8
+ store i8 %36, ptr %1, align 1
+ %37 = add i32 %27, %4
+ %38 = add i32 %37, 1
+ %39 = lshr i32 %38, 1
+ %40 = trunc i32 %39 to i8
+ store i8 %40, ptr %0, align 1
+ %41 = or i32 %26, 1
+ %42 = add i32 %41, 1
+ %43 = lshr i32 %42, 1
+ %44 = trunc i32 %43 to i8
+ store i8 %44, ptr %1, align 1
+ %45 = or i32 %4, %8
+ %46 = or i32 %45, %5
+ %47 = lshr i32 %46, 1
+ %48 = trunc i32 %47 to i8
+ store i8 %48, ptr %2, align 1
+ %49 = add i32 %11, %4
+ %50 = add i32 %49, 1
+ %51 = lshr i32 %50, 1
+ %52 = trunc i32 %51 to i8
+ store i8 %52, ptr %0, align 1
+ %53 = add i32 %8, 1
+ %54 = lshr i32 %53, 1
+ %55 = trunc i32 %54 to i8
+ store i8 %55, ptr %1, align 1
+ %56 = add i32 %8, 1
+ %57 = or i32 %56, %4
+ %58 = lshr i32 %57, 1
+ %59 = trunc i32 %58 to i8
+ store i8 %59, ptr %0, align 1
+ %60 = add i32 %10, 1
+ %61 = lshr i32 %60, 1
+ %62 = trunc i32 %61 to i8
+ store i8 %62, ptr %1, align 1
+ %63 = zext i8 %3 to i32
+ %64 = add i32 %63, 1
+ %65 = lshr i32 %64, 1
+ %66 = trunc i32 %65 to i8
+ store i8 %66, ptr %0, align 1
+ %67 = add i32 %13, %4
+ %68 = add i32 %67, 1
+ %69 = lshr i32 %68, 1
+ %70 = trunc i32 %69 to i8
+ store i8 %70, ptr %1, align 1
+ %71 = add i32 %63, 1
+ %72 = add i32 %71, %4
+ %73 = lshr i32 %72, 1
+ %74 = trunc i32 %73 to i8
+ store i8 %74, ptr %0, align 1
+ %75 = or i32 %4, %63
+ %76 = lshr i32 %75, 1
+ ret i32 %76
+}
More information about the llvm-commits
mailing list