Skip to content

Commit 32d6ef3

Browse files
committed
[SimpleLoopUnswitch] Skip trivial selects during trivial unswitching.
Update the remaining places in unswitchTrivialBranch to properly skip trivial selects. Fixes #55526.
1 parent d14f2a6 commit 32d6ef3

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,12 @@ static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT,
460460
// some input conditions to the branch.
461461
bool FullUnswitch = false;
462462

463-
if (L.isLoopInvariant(BI.getCondition())) {
464-
Invariants.push_back(BI.getCondition());
463+
Value *Cond = skipTrivialSelect(BI.getCondition());
464+
if (L.isLoopInvariant(Cond)) {
465+
Invariants.push_back(Cond);
465466
FullUnswitch = true;
466467
} else {
467-
if (auto *CondInst =
468-
dyn_cast<Instruction>(skipTrivialSelect(BI.getCondition())))
468+
if (auto *CondInst = dyn_cast<Instruction>(Cond))
469469
Invariants = collectHomogenousInstGraphLoopInvariants(L, *CondInst, LI);
470470
if (Invariants.empty()) {
471471
LLVM_DEBUG(dbgs() << " Couldn't find invariant inputs!\n");
@@ -499,7 +499,6 @@ static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT,
499499
// is a graph of `or` operations, or the exit block is along the false edge
500500
// and the condition is a graph of `and` operations.
501501
if (!FullUnswitch) {
502-
Value *Cond = skipTrivialSelect(BI.getCondition());
503502
if (ExitDirection ? !match(Cond, m_LogicalOr())
504503
: !match(Cond, m_LogicalAnd())) {
505504
LLVM_DEBUG(dbgs() << " Branch condition is in improper form for "
@@ -566,6 +565,7 @@ static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT,
566565
// its successors.
567566
OldPH->getInstList().splice(OldPH->end(), BI.getParent()->getInstList(),
568567
BI);
568+
BI.setCondition(Cond);
569569
if (MSSAU) {
570570
// Temporarily clone the terminator, to make MSSA update cheaper by
571571
// separating "insert edge" updates from "remove edge" ones.
@@ -1040,7 +1040,8 @@ static bool unswitchAllTrivialConditions(Loop &L, DominatorTree &DT,
10401040
// Don't bother trying to unswitch past an unconditional branch or a branch
10411041
// with a constant value. These should be removed by simplifycfg prior to
10421042
// running this pass.
1043-
if (!BI->isConditional() || isa<Constant>(BI->getCondition()))
1043+
if (!BI->isConditional() ||
1044+
isa<Constant>(skipTrivialSelect(BI->getCondition())))
10441045
return Changed;
10451046

10461047
// Found a trivial condition candidate: non-foldable conditional branch. If

llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,29 @@ do_something:
248248
loop_exit:
249249
ret i32 0
250250
}
251+
252+
; Test case for PR55526.
253+
define void @test_pr55526(i16 %a) {
254+
; CHECK-LABEL: @test_pr55526(
255+
; CHECK-NEXT: entry:
256+
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i16 [[A:%.*]], 0
257+
; CHECK-NEXT: br i1 [[TOBOOL]], label [[ENTRY_SPLIT:%.*]], label [[EXIT:%.*]]
258+
; CHECK: entry.split:
259+
; CHECK-NEXT: br label [[LOOP:%.*]]
260+
; CHECK: loop:
261+
; CHECK-NEXT: [[SEL:%.*]] = select i1 true, i1 true, i1 false
262+
; CHECK-NEXT: br label [[LOOP]]
263+
; CHECK: exit:
264+
; CHECK-NEXT: ret void
265+
;
266+
entry:
267+
%tobool = icmp ne i16 %a, 0
268+
br label %loop
269+
270+
loop:
271+
%sel = select i1 %tobool, i1 true, i1 false
272+
br i1 %sel, label %loop, label %exit
273+
274+
exit:
275+
ret void
276+
}

0 commit comments

Comments
 (0)