[llvm] [SimplifyCFG] Do not redirect potential poison values from predecessors (PR #189966)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 07:13:33 PDT 2026
https://github.com/spaits created https://github.com/llvm/llvm-project/pull/189966
to PHI
My attempt to fix #189526 .
I have did some debugging in SimplifyCFG and found that the things may go wrong when redirecting values from predecessors to the PHI node: https://alive2.llvm.org/ce/z/MRGLNx .
The issue is caused by replacing a `undef` with a potential poison value.
Here is the code generated after the patch for the code snippet in the issue: https://alive2.llvm.org/ce/z/p5Hv_y .
This PR may cause some regressions while fixing the issue!
>From fb3e11c4b71565086040ce04819c049bebac238b Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gabor.spaits at hightec-rt.com>
Date: Wed, 1 Apr 2026 16:06:41 +0200
Subject: [PATCH] [SimplifyCFG] Do not redirect potential poison values from
predecessors to PHI
My attempt to fix #189526 .
I have did some debugging in SimplifyCFG and found that the things may
go wrong when redirecting values from predecessors to the PHI node: https://alive2.llvm.org/ce/z/MRGLNx .
The issue is caused by replacing a `undef` with a potential poison
value.
Here is the code generated after the patch for the code snippet in the
issue: https://alive2.llvm.org/ce/z/p5Hv_y .
This PR may cause some regressions while fixing the issue!
---
llvm/lib/Transforms/Utils/Local.cpp | 26 ++++++++++-
.../ForwardSwitchConditionToPHI.ll | 43 +++++++++++++++++--
2 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 84c0989a7fe07..854e5d179f309 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1084,7 +1084,7 @@ static bool introduceTooManyPhiEntries(BasicBlock *BB, BasicBlock *Succ) {
/// \param BBPreds The predecessors of BB.
/// \param PN The phi that we are updating.
/// \param CommonPred The common predecessor of BB and PN's BasicBlock
-static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
+static bool redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
const PredBlockVector &BBPreds,
PHINode *PN,
BasicBlock *CommonPred) {
@@ -1124,6 +1124,16 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Value *Selected =
selectIncomingValueForBlock(PredVal, PredBB, IncomingValues);
+ // It can cause an issue if there was a 'undef' assigned for the block
+ // before and we replace that block with a value that might be poison.
+ int BlockIdx = PN->getBasicBlockIndex(PredBB);
+ if (BlockIdx > 0 && isa<UndefValue>(PN->getIncomingValue(BlockIdx)) &&
+ (!isa<Constant>(Selected) ||
+ !isGuaranteedNotToBeUndefOrPoison(Selected))) {
+ PN->addIncoming(OldVal, BB);
+ return false;
+ }
+
// And add a new incoming value for this predecessor for the
// newly retargeted branch.
PN->addIncoming(Selected, PredBB);
@@ -1141,6 +1151,16 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Value *Selected =
selectIncomingValueForBlock(OldVal, PredBB, IncomingValues);
+ // It can cause an issue if there was a 'undef' assigned for the block
+ // before and we replace that block with a value that might be poison.
+ int BlockIdx = PN->getBasicBlockIndex(PredBB);
+ if (BlockIdx > 0 && isa<UndefValue>(PN->getIncomingValue(BlockIdx)) &&
+ (!isa<Constant>(Selected) ||
+ !isGuaranteedNotToBeUndefOrPoison(Selected))) {
+ PN->addIncoming(OldVal, BB);
+ return false;
+ }
+
// And add a new incoming value for this predecessor for the
// newly retargeted branch.
PN->addIncoming(Selected, PredBB);
@@ -1150,6 +1170,7 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
}
replaceUndefValuesInPhi(PN, IncomingValues);
+ return true;
}
bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
@@ -1327,7 +1348,8 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
// Loop over all of the PHI nodes in the successor of BB.
for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
- redirectValuesFromPredecessorsToPhi(BB, BBPreds, PN, CommonPred);
+ if (!redirectValuesFromPredecessorsToPhi(BB, BBPreds, PN, CommonPred))
+ return false;
}
}
diff --git a/llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll b/llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
index ea81e0e4fa48c..df4b44aa941a6 100644
--- a/llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
+++ b/llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
@@ -206,15 +206,19 @@ define { i64, i64 } @PR95919(i64 noundef %arg, i64 noundef %arg1) {
;
; FWD-LABEL: @PR95919(
; FWD-NEXT: bb:
-; FWD-NEXT: [[SWITCH:%.*]] = icmp ult i64 [[ARG1:%.*]], 2
-; FWD-NEXT: br i1 [[SWITCH]], label [[BB5:%.*]], label [[BB3:%.*]]
+; FWD-NEXT: switch i64 [[ARG1:%.*]], label [[BB3:%.*]] [
+; FWD-NEXT: i64 0, label [[BB5:%.*]]
+; FWD-NEXT: i64 1, label [[BB2:%.*]]
+; FWD-NEXT: ]
+; FWD: bb2:
+; FWD-NEXT: br label [[BB5]]
; FWD: bb3:
; FWD-NEXT: [[I:%.*]] = udiv i64 [[ARG:%.*]], [[ARG1]]
; FWD-NEXT: [[I4:%.*]] = shl nuw i64 [[I]], 1
; FWD-NEXT: br label [[BB5]]
; FWD: bb5:
-; FWD-NEXT: [[I6:%.*]] = phi i64 [ [[I4]], [[BB3]] ], [ [[ARG]], [[BB:%.*]] ]
-; FWD-NEXT: [[I7:%.*]] = phi i64 [ 1, [[BB3]] ], [ [[ARG1]], [[BB]] ]
+; FWD-NEXT: [[I6:%.*]] = phi i64 [ [[I4]], [[BB3]] ], [ undef, [[BB:%.*]] ], [ [[ARG]], [[BB2]] ]
+; FWD-NEXT: [[I7:%.*]] = phi i64 [ 1, [[BB3]] ], [ [[ARG1]], [[BB2]] ], [ [[ARG1]], [[BB]] ]
; FWD-NEXT: [[I8:%.*]] = insertvalue { i64, i64 } poison, i64 [[I7]], 0
; FWD-NEXT: [[I9:%.*]] = insertvalue { i64, i64 } [[I8]], i64 [[I6]], 1
; FWD-NEXT: ret { i64, i64 } [[I9]]
@@ -240,3 +244,34 @@ bb5: ; preds = %bb3, %bb2, %bb
%i9 = insertvalue { i64, i64 } %i8, i64 %i6, 1
ret { i64, i64 } %i9
}
+
+define i32 @NotPropagatingPoisonToUndef(i8 %cond, i32 %x) {
+; NO_FWD-LABEL: @NotPropagatingPoisonToUndef(
+; NO_FWD-NEXT: D:
+; NO_FWD-NEXT: [[COND1:%.*]] = icmp eq i8 [[COND:%.*]], 0
+; NO_FWD-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND1]], i32 [[X:%.*]], i32 0
+; NO_FWD-NEXT: ret i32 [[SPEC_SELECT]]
+;
+; FWD-LABEL: @NotPropagatingPoisonToUndef(
+; FWD-NEXT: D:
+; FWD-NEXT: [[COND1:%.*]] = icmp eq i8 [[COND:%.*]], 0
+; FWD-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND1]], i32 [[X:%.*]], i32 0
+; FWD-NEXT: ret i32 [[SPEC_SELECT]]
+;
+ switch i8 %cond, label %A [
+ i8 0, label %B
+ i8 1, label %C
+ ]
+A:
+ br label %D
+B:
+ br label %D
+C:
+ br label %D
+D:
+ %y = phi i32 [ undef, %A ], [ %x, %B ], [ 0, %C ]
+ ret i32 %y
+}
+
+
+
More information about the llvm-commits
mailing list