Philip Reames 9c89f4441e [LazyValueInfo] Look through Phi nodes when trying to prove a predicate
If asked to prove a predicate about a value produced by a PHI node, LazyValueInfo was unable to do so even if the predicate was known to be true for each input to the PHI. This prevented JumpThreading from eliminating a provably redundant branch.

The problematic test case looks something like this:
ListNode *p = ...;
while (p != null) {
  if (!p) return;
  x = g->x; // unrelated
  p = p->next
}

The null check at the top of the loop is redundant since the value of 'p' is null checked on entry to the loop and before executing the backedge. This resulted in us a) executing an extra null check per iteration and b) not being able to LICM unrelated loads after the check since we couldn't prove they would execute or that their dereferenceability wasn't effected by the null check on the first iteration.

Differential Revision: http://reviews.llvm.org/D12383



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246465 91177308-0d34-0410-b5e6-96231b3b80d8
2015-08-31 18:31:48 +00:00

67 lines
1.6 KiB
LLVM

; RUN: opt -S -jump-threading %s | FileCheck %s
; Value of predicate known on all inputs (trivial case)
; Note: InstCombine/EarlyCSE would also get this case
define void @test(i8* %p, i8** %addr) {
; CHECK-LABEL: @test
entry:
%cmp0 = icmp eq i8* %p, null
br i1 %cmp0, label %exit, label %loop
loop:
; CHECK-LABEL: loop:
; CHECK-NEXT: phi
; CHECK-NEXT: br label %loop
%p1 = phi i8* [%p, %entry], [%p1, %loop]
%cmp1 = icmp eq i8* %p1, null
br i1 %cmp1, label %exit, label %loop
exit:
ret void
}
; Value of predicate known on all inputs (non-trivial)
define void @test2(i8* %p) {
; CHECK-LABEL: @test2
entry:
%cmp0 = icmp eq i8* %p, null
br i1 %cmp0, label %exit, label %loop
loop:
%p1 = phi i8* [%p, %entry], [%p2, %backedge]
%cmp1 = icmp eq i8* %p1, null
br i1 %cmp1, label %exit, label %backedge
backedge:
; CHECK-LABEL: backedge:
; CHECK-NEXT: phi
; CHECK-NEXT: bitcast
; CHECK-NEXT: load
; CHECK-NEXT: cmp
; CHECK-NEXT: br
; CHECK-DAG: label %backedge
%addr = bitcast i8* %p1 to i8**
%p2 = load i8*, i8** %addr
%cmp2 = icmp eq i8* %p2, null
br i1 %cmp2, label %exit, label %loop
exit:
ret void
}
; If the inputs don't branch the same way, we can't rewrite
; Well, we could unroll this loop exactly twice, but that's
; a different transform.
define void @test_mixed(i8* %p) {
; CHECK-LABEL: @test_mixed
entry:
%cmp0 = icmp eq i8* %p, null
br i1 %cmp0, label %exit, label %loop
loop:
; CHECK-LABEL: loop:
; CHECK-NEXT: phi
; CHECK-NEXT: %cmp1 = icmp
; CHECK-NEXT: br i1 %cmp1
%p1 = phi i8* [%p, %entry], [%p1, %loop]
%cmp1 = icmp ne i8* %p1, null
br i1 %cmp1, label %exit, label %loop
exit:
ret void
}