[SimpleLoopUnswitch] Always skip trivial select and set condition.

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.
This commit is contained in:
Florian Hahn 2022-05-26 09:46:23 +01:00
parent e45087fd53
commit f96aa493f0
No known key found for this signature in database
GPG Key ID: CF59919C6547A668
2 changed files with 38 additions and 2 deletions

View File

@ -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!");

View File

@ -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
}