Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
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
2 changes: 2 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7824,6 +7824,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
unsigned Num = PN->getNumIncomingValues();
bool IsWellDefined = true;
for (unsigned i = 0; i < Num; ++i) {
if (PN == PN->getIncomingValue(i))
continue;
auto *TI = PN->getIncomingBlock(i)->getTerminator();
if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
DT, Depth + 1, Kind)) {
Expand Down
85 changes: 85 additions & 0 deletions llvm/test/Analysis/ValueTracking/phi-self.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=instsimplify < %s | FileCheck %s

; Test `%r` can be replaced by `%nonpoison`.

define i32 @other_noundef() {
; CHECK-LABEL: define i32 @other_noundef() {
; CHECK-NEXT: [[START:.*]]:
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[NONPOISON:%.*]] = phi i32 [ 0, %[[START]] ], [ [[NONPOISON]], %[[BB0:.*]] ], [ 1, %[[BB1:.*]] ]
; CHECK-NEXT: [[I:%.*]] = call i32 @opaque()
; CHECK-NEXT: switch i32 [[I]], label %[[EXIT:.*]] [
; CHECK-NEXT: i32 0, label %[[BB0]]
; CHECK-NEXT: i32 1, label %[[BB1]]
; CHECK-NEXT: ]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret i32 [[NONPOISON]]
; CHECK: [[BB0]]:
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[BB1]]:
; CHECK-NEXT: br label %[[LOOP]]
;
start:
br label %loop

loop:
%nonpoison = phi i32 [ 0, %start ], [ %nonpoison, %bb0 ], [ 1, %bb1 ]
%i = call i32 @opaque()
switch i32 %i, label %exit [
i32 0, label %bb0
i32 1, label %bb1
]

exit:
%r = freeze i32 %nonpoison
ret i32 %r

bb0:
br label %loop

bb1:
br label %loop
}

define i32 @other_poison() {
; CHECK-LABEL: define i32 @other_poison() {
; CHECK-NEXT: [[START:.*:]]
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[I:%.*]] = call i32 @opaque()
; CHECK-NEXT: switch i32 [[I]], label %[[EXIT:.*]] [
; CHECK-NEXT: i32 0, label %[[BB0:.*]]
; CHECK-NEXT: i32 1, label %[[BB1:.*]]
; CHECK-NEXT: ]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret i32 0
; CHECK: [[BB0]]:
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[BB1]]:
; CHECK-NEXT: br label %[[LOOP]]
;
start:
br label %loop

loop:
%maypoison = phi i32 [ 0, %start ], [ %maypoison, %bb0 ], [ poison, %bb1 ]
%i = call i32 @opaque()
switch i32 %i, label %exit [
i32 0, label %bb0
i32 1, label %bb1
]

exit:
%r = freeze i32 %maypoison
ret i32 %r

bb0:
br label %loop

bb1:
br label %loop
}

declare i32 @opaque()
Loading