mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
333795bf71
If solveBlockValue() needs results from predecessors that are not already computed, it returns false with the intention of resuming when the dependencies have been resolved. However, the computation would never be resumed since an 'overdefined' result had been placed in the cache, preventing any further computation. The point of placing the 'overdefined' result in the cache seems to have been to break cycles, but we can check for that when inserting work items in the BlockValue stack instead. This makes the "stop and resume" mechanism of solveBlockValue() work as intended, unlocking more analysis. Using this patch shaves 120 KB off a 64-bit Chromium build on Linux. I benchmarked compiling bzip2.c at -O2 but couldn't measure any difference in compile time. Tests by Jiangning Liu from r215343 / PR21238, Pete Cooper, and me. Differential Revision: http://reviews.llvm.org/D6397 llvm-svn: 222768
59 lines
1.3 KiB
LLVM
59 lines
1.3 KiB
LLVM
; RUN: opt -jump-threading -S %s | FileCheck %s
|
|
|
|
; Check that we thread arg2neg -> checkpos -> end.
|
|
;
|
|
; LazyValueInfo would previously fail to analyze the value of %arg in arg2neg
|
|
; because its predecessing blocks (checkneg) hadn't been processed yet (PR21238)
|
|
|
|
; CHECK-LABEL: @test_jump_threading
|
|
; CHECK: arg2neg:
|
|
; CHECK-NEXT: br i1 %arg1, label %end, label %checkpos.thread
|
|
; CHECK: checkpos.thread:
|
|
; CHECK-NEXT: br label %end
|
|
|
|
define i32 @test_jump_threading(i1 %arg1, i32 %arg2) {
|
|
checkneg:
|
|
%cmp = icmp slt i32 %arg2, 0
|
|
br i1 %cmp, label %arg2neg, label %checkpos
|
|
|
|
arg2neg:
|
|
br i1 %arg1, label %end, label %checkpos
|
|
|
|
checkpos:
|
|
%cmp2 = icmp sgt i32 %arg2, 0
|
|
br i1 %cmp2, label %arg2pos, label %end
|
|
|
|
arg2pos:
|
|
br label %end
|
|
|
|
end:
|
|
%0 = phi i32 [ 1, %arg2neg ], [ 2, %checkpos ], [ 3, %arg2pos ]
|
|
ret i32 %0
|
|
}
|
|
|
|
|
|
; arg2neg has an edge back to itself. If LazyValueInfo is not careful when
|
|
; visiting predecessors, it could get into an infinite loop.
|
|
|
|
; CHECK-LABEL: test_infinite_loop
|
|
|
|
define i32 @test_infinite_loop(i1 %arg1, i32 %arg2) {
|
|
checkneg:
|
|
%cmp = icmp slt i32 %arg2, 0
|
|
br i1 %cmp, label %arg2neg, label %checkpos
|
|
|
|
arg2neg:
|
|
br i1 %arg1, label %arg2neg, label %checkpos
|
|
|
|
checkpos:
|
|
%cmp2 = icmp sgt i32 %arg2, 0
|
|
br i1 %cmp2, label %arg2pos, label %end
|
|
|
|
arg2pos:
|
|
br label %end
|
|
|
|
end:
|
|
%0 = phi i32 [ 2, %checkpos ], [ 3, %arg2pos ]
|
|
ret i32 %0
|
|
}
|