Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions llvm/lib/IR/BasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,14 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
if (NumPreds == 1)
continue;

// Try to replace the PHI node with a constant value.
if (Value *PhiConstant = Phi.hasConstantValue()) {
// Try to replace the PHI node with a constant value, but make sure that
// this value isn't using the PHI node. (Except it's a PHI node itself. PHI
// nodes are allowed to reference themselves.)
if (Value *PhiConstant = Phi.hasConstantValue();
PhiConstant &&
(!isa<Instruction>(PhiConstant) || isa<PHINode>(PhiConstant) ||
llvm::all_of(Phi.users(),
[PhiConstant](User *U) { return U != PhiConstant; }))) {
Phi.replaceAllUsesWith(PhiConstant);
Phi.eraseFromParent();
}
Expand Down
60 changes: 60 additions & 0 deletions llvm/test/Transforms/JumpThreading/unreachable-loops.ll
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,64 @@ cleanup2343.loopexit4: ; preds = %cleanup1491
unreachable
}

; This segfaults due to recursion in %C4. Reason: %L6 is identified to be a
; "partially redundant load" and is replaced by a PHI node. The PHI node is then
; simplified to be constant and is removed. This leads to %L6 being replaced by
; %C4, which makes %C4 invalid since it uses %L6.
; The test case has been generated by the AMD Fuzzing project and simplified
; manually and by llvm-reduce.

define i32 @constant_phi_leads_to_self_reference() {
; CHECK-LABEL: @constant_phi_leads_to_self_reference(
; CHECK-NEXT: [[A9:%.*]] = alloca i1, align 1
; CHECK-NEXT: br label [[F6:%.*]]
; CHECK: T3:
; CHECK-NEXT: [[L6:%.*]] = phi i1 [ [[C4:%.*]], [[BB6:%.*]] ]
; CHECK-NEXT: br label [[BB5:%.*]]
; CHECK: BB5:
; CHECK-NEXT: [[L10:%.*]] = load i1, ptr [[A9]], align 1
; CHECK-NEXT: br i1 [[L10]], label [[BB6]], label [[F6]]
; CHECK: BB6:
; CHECK-NEXT: [[LGV3:%.*]] = load i1, ptr null, align 1
; CHECK-NEXT: [[C4]] = icmp sle i1 [[L6]], true
; CHECK-NEXT: store i1 [[C4]], ptr null, align 1
; CHECK-NEXT: br i1 [[L6]], label [[F6]], label [[T3:%.*]]
; CHECK: F6:
; CHECK-NEXT: ret i32 0
; CHECK: F7:
; CHECK-NEXT: br label [[BB5]]
;
%A9 = alloca i1, align 1
br i1 false, label %BB4, label %F6

BB4: ; preds = %0
br i1 false, label %F6, label %F1

F1: ; preds = %BB4
br i1 false, label %T4, label %T3

T3: ; preds = %T4, %BB6, %F1
%L6 = load i1, ptr null, align 1
br label %BB5

BB5: ; preds = %F7, %T3
%L10 = load i1, ptr %A9, align 1
br i1 %L10, label %BB6, label %F6

BB6: ; preds = %BB5
%LGV3 = load i1, ptr null, align 1
%C4 = icmp sle i1 %L6, true
store i1 %C4, ptr null, align 1
br i1 %L6, label %F6, label %T3

T4: ; preds = %F1
br label %T3

F6: ; preds = %BB6, %BB5, %BB4, %0
ret i32 0

F7: ; No predecessors!
br label %BB5
}

!0 = !{!"branch_weights", i32 2146410443, i32 1073205}