forked from OSchip/llvm-project
[SCCP] Only handle unknown lattice values in resolvedUndefsIn()
This is a minor refinement of resolvedUndefsIn(), mostly for clarity. If the value of an instruction is undef, then that's already a legal final result -- we can safely rauw such an instruction with undef. We only need to mark unknown values as overdefined, as that's the result we get for an instruction that has not been processed because it has an undef operand. Differential Revision: https://reviews.llvm.org/D128251
This commit is contained in:
parent
4a78225212
commit
9b994593cc
|
@ -1456,7 +1456,7 @@ void SCCPInstVisitor::solve() {
|
|||
/// However, if the operand remains undef when the solver returns, we do need
|
||||
/// to assign some result to the instruction (otherwise we would treat it as
|
||||
/// unreachable). For simplicity, we mark any instructions that are still
|
||||
/// unknown/undef as overdefined.
|
||||
/// unknown as overdefined.
|
||||
bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
|
||||
bool MadeChange = false;
|
||||
for (BasicBlock &BB : F) {
|
||||
|
@ -1485,7 +1485,7 @@ bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
|
|||
// more precise than this but it isn't worth bothering.
|
||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||
ValueLatticeElement &LV = getStructValueState(&I, i);
|
||||
if (LV.isUnknownOrUndef()) {
|
||||
if (LV.isUnknown()) {
|
||||
markOverdefined(LV, &I);
|
||||
MadeChange = true;
|
||||
}
|
||||
|
@ -1494,7 +1494,7 @@ bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
|
|||
}
|
||||
|
||||
ValueLatticeElement &LV = getValueState(&I);
|
||||
if (!LV.isUnknownOrUndef())
|
||||
if (!LV.isUnknown())
|
||||
continue;
|
||||
|
||||
// There are two reasons a call can have an undef result
|
||||
|
|
|
@ -11,8 +11,7 @@ define void @fn2(i32* %P) {
|
|||
; CHECK: for.cond1:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* undef, align 4
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 undef)
|
||||
; CHECK-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
;
|
||||
|
@ -34,8 +33,8 @@ define internal i32 @fn1(i32 %p1) {
|
|||
; CHECK-LABEL: define {{[^@]+}}@fn1
|
||||
; CHECK-SAME: (i32 [[P1:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 undef, 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 undef, i32 undef
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
entry:
|
||||
|
@ -52,8 +51,7 @@ define void @fn_no_null_opt(i32* %P) #0 {
|
|||
; CHECK: for.cond1:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* undef, align 4
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 undef)
|
||||
; CHECK-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
;
|
||||
|
@ -75,8 +73,8 @@ define internal i32 @fn0(i32 %p1) {
|
|||
; CHECK-LABEL: define {{[^@]+}}@fn0
|
||||
; CHECK-SAME: (i32 [[P1:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 undef, 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 undef, i32 undef
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -5,17 +5,13 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
define void @test() {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label %Flow5.pre
|
||||
; CHECK-NEXT: br label [[FLOW5_PRE:%.*]]
|
||||
; CHECK: Flow6:
|
||||
; CHECK-NEXT: br i1 undef, label %end1, label %end2
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: Flow5.pre:
|
||||
; CHECK-NEXT: br label %Flow5
|
||||
; CHECK-NEXT: br label [[FLOW5:%.*]]
|
||||
; CHECK: Flow5:
|
||||
; CHECK-NEXT: br label %Flow6
|
||||
; CHECK: end1:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: end2:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK-NEXT: br label [[FLOW6:%.*]]
|
||||
;
|
||||
entry:
|
||||
br i1 true, label %Flow5.pre, label %Flow5.pre.unreachable
|
||||
|
|
Loading…
Reference in New Issue