Skip to content

Commit 7fa41d8

Browse files
authored
[DFAJumpThreading] Only unfold select coming from directly where it is defined (#70966)
Fixes #64860. When a select instruction comes in by PHINode, the phi's incoming block for it can flow indirectly past other BasicBlock into it. In this case, we cannot unfold select to the phi's BB.
1 parent d97b2b3 commit 7fa41d8

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ static cl::opt<unsigned> MaxPathLength(
100100
cl::desc("Max number of blocks searched to find a threading path"),
101101
cl::Hidden, cl::init(20));
102102

103-
static cl::opt<unsigned> MaxNumPaths(
104-
"dfa-max-num-paths",
105-
cl::desc("Max number of paths enumerated around a switch"),
106-
cl::Hidden, cl::init(200));
103+
static cl::opt<unsigned>
104+
MaxNumPaths("dfa-max-num-paths",
105+
cl::desc("Max number of paths enumerated around a switch"),
106+
cl::Hidden, cl::init(200));
107107

108108
static cl::opt<unsigned>
109109
CostThreshold("dfa-cost-threshold",
@@ -297,6 +297,7 @@ void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
297297
{DominatorTree::Insert, StartBlock, FT}});
298298

299299
// The select is now dead.
300+
assert(SI->use_empty() && "Select must be dead now");
300301
SI->eraseFromParent();
301302
}
302303

@@ -466,8 +467,9 @@ struct MainSwitch {
466467
if (!SITerm || !SITerm->isUnconditional())
467468
return false;
468469

469-
if (isa<PHINode>(SIUse) &&
470-
SIBB->getSingleSuccessor() != cast<Instruction>(SIUse)->getParent())
470+
// Only fold the select coming from directly where it is defined.
471+
PHINode *PHIUser = dyn_cast<PHINode>(SIUse);
472+
if (PHIUser && PHIUser->getIncomingBlock(*SI->use_begin()) != SIBB)
471473
return false;
472474

473475
// If select will not be sunk during unfolding, and it is in the same basic

llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,28 @@ for.inc:
291291
for.end:
292292
ret i32 0
293293
}
294+
295+
define void @select_coming_elsewhere(i1 %cond, i16 %a, i16 %b) {
296+
; CHECK-LABEL: @select_coming_elsewhere(
297+
; CHECK-NEXT: entry:
298+
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[COND:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]
299+
; CHECK-NEXT: br label [[FOR_COND:%.*]]
300+
; CHECK: for.cond:
301+
; CHECK-NEXT: [[E_ADDR_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[DIV]], [[LOR_END:%.*]] ]
302+
; CHECK-NEXT: switch i16 [[E_ADDR_0]], label [[LOR_END]] [
303+
; CHECK-NEXT: ]
304+
; CHECK: lor.end:
305+
; CHECK-NEXT: br label [[FOR_COND]]
306+
;
307+
entry:
308+
%div = select i1 %cond, i16 %a, i16 %b
309+
br label %for.cond
310+
311+
for.cond: ; preds = %lor.end, %entry
312+
%e.addr.0 = phi i16 [ 0, %entry ], [ %div, %lor.end ]
313+
switch i16 %e.addr.0, label %lor.end [
314+
]
315+
316+
lor.end: ; preds = %for.cond
317+
br label %for.cond
318+
}

0 commit comments

Comments
 (0)