mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
8c47d7364a
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 llvm-svn: 246465
67 lines
1.6 KiB
LLVM
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
|
|
}
|
|
|