Skip to content

Commit

Permalink
[IR][LoopRotate] avoid leaving phi with no operands (PR48296)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rotateright committed Nov 30, 2020
1 parent 234a529 commit bfd2c21
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
6 changes: 3 additions & 3 deletions llvm/include/llvm/IR/BasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
/// 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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/BasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/Transforms/LoopRotate/phi-empty.ll
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit bfd2c21

Please sign in to comment.