mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-11 17:08:42 +00:00
[IR][LoopRotate] avoid leaving phi with no operands (PR48296)
https://llvm.org/PR48296 shows an example where we delete all of the operands of a phi without actually deleting the phi, and that is currently considered invalid IR. The reduced test included here would crash for that reason. A suggested follow-up is to loosen the assert to allow 0-operand phis in unreachable blocks. Differential Revision: https://reviews.llvm.org/D92247
This commit is contained in:
parent
234a5297aa
commit
bfd2c216ea
@ -387,9 +387,9 @@ public:
|
||||
/// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
|
||||
/// Note that this function does not actually remove the predecessor.
|
||||
///
|
||||
/// If \p KeepOneInputPHIs is true then don't remove PHIs that are left with
|
||||
/// zero or one incoming values, and don't simplify PHIs with all incoming
|
||||
/// values the same.
|
||||
/// If \p KeepOneInputPHIs is true, then don't remove PHIs that are left with
|
||||
/// one incoming value and don't simplify PHIs with all incoming values the
|
||||
/// same.
|
||||
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false);
|
||||
|
||||
bool canSplitPredecessors() const;
|
||||
|
@ -330,7 +330,7 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
|
||||
|
||||
unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
|
||||
for (PHINode &Phi : make_early_inc_range(phis())) {
|
||||
Phi.removeIncomingValue(Pred, !KeepOneInputPHIs);
|
||||
Phi.removeIncomingValue(Pred);
|
||||
if (KeepOneInputPHIs)
|
||||
continue;
|
||||
// If we have a single predecessor, removeIncomingValue erased the PHI
|
||||
|
34
llvm/test/Transforms/LoopRotate/phi-empty.ll
Normal file
34
llvm/test/Transforms/LoopRotate/phi-empty.ll
Normal file
@ -0,0 +1,34 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -lcssa -loop-rotate < %s | FileCheck %s
|
||||
|
||||
define void @PR48296(i1 %cond) {
|
||||
; CHECK-LABEL: @PR48296(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC:%.*]], label [[LOOP_BACKEDGE:%.*]]
|
||||
; CHECK: loop.backedge:
|
||||
; CHECK-NEXT: br label [[LOOP]]
|
||||
; CHECK: dead:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: inc:
|
||||
; CHECK-NEXT: br label [[LOOP_BACKEDGE]]
|
||||
; CHECK: return:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
br i1 %cond, label %inc, label %loop
|
||||
|
||||
dead: ; No predecessors!
|
||||
br i1 %cond, label %inc, label %return
|
||||
|
||||
inc:
|
||||
br label %loop
|
||||
|
||||
return:
|
||||
%r = phi i32 [ undef, %dead ]
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user