Skip to content

Commit

Permalink
[SimpleLoopUnswitch] Always skip trivial select and set condition.
Browse files Browse the repository at this point in the history
When updating the branch instruction outside the loopduring non-trivial
 unswitching, always skip trivial selects and update the condition.

Otherwise we might create invalid IR, because the trivial select is
inside the loop, while the condition is outside the loop.

Fixes #55697.
  • Loading branch information
fhahn committed May 26, 2022
1 parent e45087f commit f96aa49
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
Expand Up @@ -2232,11 +2232,12 @@ static void unswitchNontrivialInvariants(
BasicBlock *ClonedPH = ClonedPHs.begin()->second;
BI->setSuccessor(ClonedSucc, ClonedPH);
BI->setSuccessor(1 - ClonedSucc, LoopPH);
Value *Cond = skipTrivialSelect(BI->getCondition());
if (InsertFreeze) {
auto Cond = skipTrivialSelect(BI->getCondition());
if (!isGuaranteedNotToBeUndefOrPoison(Cond, &AC, BI, &DT))
BI->setCondition(new FreezeInst(Cond, Cond->getName() + ".fr", BI));
Cond = new FreezeInst(Cond, Cond->getName() + ".fr", BI);
}
BI->setCondition(Cond);
DTUpdates.push_back({DominatorTree::Insert, SplitBB, ClonedPH});
} else {
assert(SI && "Must either be a branch or switch!");
Expand Down
Expand Up @@ -82,3 +82,38 @@ loop.latch:
exit:
ret void
}

; Test case for PR55697.
define i32 @unswitch_trivial_select_cmp_outside(i32 %x) {
; CHECK-LABEL: @unswitch_trivial_select_cmp_outside(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], 100
; CHECK-NEXT: br i1 [[C]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
; CHECK: entry.split.us:
; CHECK-NEXT: br label [[LOOP_US:%.*]]
; CHECK: loop.us:
; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ 35, [[LOOP_US]] ]
; CHECK-NEXT: br label [[LOOP_US]]
; CHECK: entry.split:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ]
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i1 true, i1 false
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[LCSSA:%.*]] = phi i32 [ [[P]], [[LOOP]] ]
; CHECK-NEXT: ret i32 [[LCSSA]]
;
entry:
%c = icmp ult i32 %x, 100
br label %loop

loop:
%p = phi i32 [ 0, %entry ], [ 35, %loop ]
%spec.select = select i1 %c, i1 true, i1 false
br i1 %spec.select, label %loop, label %exit

exit:
%lcssa = phi i32 [ %p, %loop ]
ret i32 %lcssa
}

0 comments on commit f96aa49

Please sign in to comment.