[llvm] [VPlan] Avoid replacing non-dominated uses in cse (PR #187548)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 07:30:26 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/187548
>From 63300775e52fe1eeb4ef747004834b9bd0c8bb48 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 19 Mar 2026 17:42:11 +0000
Subject: [PATCH] [VPlan] Avoid replacing non-dominated uses in cse
There could be potential cse crashes arising from outdated hash values
unless we forbid replacements in successor phis in blocks that are not
dominated by the def. It is unfortunately impossible to write a test
case showing a crash at present, but crashes do occur when attempting to
cse DerivedIV recipes.
Fixes #187499.
---
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 6 ++++++
.../Transforms/LoopVectorize/cse-replicate-regions.ll | 10 ++++++++--
.../LoopVectorize/single-early-exit-interleave-only.ll | 3 ++-
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index f779aa92a3aa7..81d5586e5e8b3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2636,6 +2636,12 @@ void VPlanTransforms::cse(VPlan &Plan) {
auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
if (!Def || !VPCSEDenseMapInfo::canHandle(Def))
continue;
+ // The def must dominates all uses, an invariant which could be broken
+ // when the use is in a non-dominated sucessor-phi.
+ if (any_of(Def->users(), [&VPDT, &VPBB](VPUser *U) {
+ return !VPDT.dominates(VPBB, cast<VPRecipeBase>(U)->getParent());
+ }))
+ continue;
if (VPSingleDefRecipe *V = CSEMap.lookup(Def)) {
// V must dominate Def for a valid replacement.
if (!VPDT.dominates(V->getParent(), VPBB))
diff --git a/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll b/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll
index 7952745c1c703..fa7d9212e573c 100644
--- a/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll
+++ b/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll
@@ -18,18 +18,24 @@ define void @multiple_vppredinstphi_with_same_predicate(ptr %A, i32 %d) {
; CHECK: [[PRED_SDIV_IF]]:
; CHECK-NEXT: [[TMP3:%.*]] = sdiv i32 -10, [[D]]
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[TMP3]], i32 0
+; CHECK-NEXT: [[TMP9:%.*]] = sdiv i32 -10, [[D]]
+; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> poison, i32 [[TMP9]], i32 0
; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE]]
; CHECK: [[PRED_SDIV_CONTINUE]]:
; CHECK-NEXT: [[TMP5:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP4]], %[[PRED_SDIV_IF]] ]
+; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP16]], %[[PRED_SDIV_IF]] ]
; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP1]], i32 1
; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_SDIV_IF1:.*]], label %[[PRED_SDIV_CONTINUE2]]
; CHECK: [[PRED_SDIV_IF1]]:
; CHECK-NEXT: [[TMP7:%.*]] = sdiv i32 -10, [[D]]
; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP7]], i32 1
+; CHECK-NEXT: [[TMP12:%.*]] = sdiv i32 -10, [[D]]
+; CHECK-NEXT: [[TMP13:%.*]] = insertelement <2 x i32> [[TMP17]], i32 [[TMP12]], i32 1
; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE2]]
; CHECK: [[PRED_SDIV_CONTINUE2]]:
-; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ [[TMP5]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP8]], %[[PRED_SDIV_IF1]] ]
-; CHECK-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP9]], [[TMP9]]
+; CHECK-NEXT: [[TMP14:%.*]] = phi <2 x i32> [ [[TMP5]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP8]], %[[PRED_SDIV_IF1]] ]
+; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP17]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP13]], %[[PRED_SDIV_IF1]] ]
+; CHECK-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP15]], [[TMP14]]
; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[TMP10]], <2 x i32> zeroinitializer
; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP0]], align 4
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
diff --git a/llvm/test/Transforms/LoopVectorize/single-early-exit-interleave-only.ll b/llvm/test/Transforms/LoopVectorize/single-early-exit-interleave-only.ll
index da87c78179fff..a29e716140261 100644
--- a/llvm/test/Transforms/LoopVectorize/single-early-exit-interleave-only.ll
+++ b/llvm/test/Transforms/LoopVectorize/single-early-exit-interleave-only.ll
@@ -110,10 +110,11 @@ define i32 @iv_used_in_exit_with_loads(ptr align 4 dereferenceable(128) %src) {
; CHECK-NEXT: [[TMP27:%.*]] = select i1 [[TMP26]], i64 [[TMP25]], i64 [[TMP22]]
; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
; CHECK-NEXT: [[TMP29:%.*]] = add i32 [[INDEX]], [[TMP28]]
+; CHECK-NEXT: [[TMP30:%.*]] = add i32 [[INDEX]], [[TMP28]]
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[RES_IV1:%.*]] = phi i32 [ 32, %[[MIDDLE_BLOCK]] ], [ [[TMP29]], %[[VECTOR_EARLY_EXIT]] ]
-; CHECK-NEXT: [[RES_IV2:%.*]] = phi i32 [ 0, %[[MIDDLE_BLOCK]] ], [ [[TMP29]], %[[VECTOR_EARLY_EXIT]] ]
+; CHECK-NEXT: [[RES_IV2:%.*]] = phi i32 [ 0, %[[MIDDLE_BLOCK]] ], [ [[TMP30]], %[[VECTOR_EARLY_EXIT]] ]
; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES_IV1]], [[RES_IV2]]
; CHECK-NEXT: ret i32 [[RES]]
;
More information about the llvm-commits
mailing list