mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
91f6300e91
Summary: Merge functions previously relied on unsigned comparisons of pointer values to order functions. This caused observable non-determinism in the compiler for large bitcode programs. Basically, opt -mergefuncs program.bc | md5sum produces different hashes when run repeatedly on the same machine. Differing output was observed on three large bitcodes, but it was less frequent on the smallest file. It is possible that this only manifests on the large inputs, hence remaining undetected until now. This patch fixes this by removing (almost, see below) all places where comparisons between pointers are used to order functions. Most of these changes are local, but the comparison of global values requires assigning an identifier to each local in the order it is visited. This is very similar to the way the comparison function identifies Value*'s defined within a function. Because the order of visiting the functions and their subparts is deterministic, the identifiers assigned to the globals will be as well, and the order of functions will be deterministic. With these changes, there is no more observed non-determinism. There is also only minor slowdowns (negligible to 4%) compared to the baseline, which is likely a result of the fact that global comparisons involve hash lookups and not just pointer comparisons. The one caveat so far is that programs containing BlockAddress constants can still be non-deterministic. It is not clear what the right solution is here. In particular, even if the global numbers are used to order by function, we still need a way to order the BasicBlock*'s. Unfortunately, we cannot just bail out and fail to order the functions or consider them equal, because we require a total order over functions. Note that programs with BlockAddress constants are relatively rare, so the impact of leaving this in is minor as long as this pass is opt-in. Author: jrkoenig Reviewers: nlewycky, jfb, dschuff Subscribers: jevinskie, llvm-commits, chapuni Differential revision: http://reviews.llvm.org/D12168 llvm-svn: 245762
43 lines
1.1 KiB
LLVM
43 lines
1.1 KiB
LLVM
; RUN: opt -S -mergefunc < %s | FileCheck %s
|
|
|
|
; RUN: opt -S -mergefunc < %s | FileCheck -check-prefix=NOPLUS %s
|
|
|
|
; This makes sure that zeros in constants don't cause problems with string based
|
|
; memory comparisons
|
|
define internal i32 @sum(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @sum
|
|
%sum = add i32 %x, %y
|
|
%1 = extractvalue [3 x i32] [ i32 3, i32 0, i32 2 ], 2
|
|
%sum2 = add i32 %sum, %1
|
|
%sum3 = add i32 %sum2, %y
|
|
ret i32 %sum3
|
|
}
|
|
|
|
define internal i32 @add(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @add
|
|
%sum = add i32 %x, %y
|
|
%1 = extractvalue [3 x i32] [ i32 3, i32 0, i32 1 ], 2
|
|
%sum2 = add i32 %sum, %1
|
|
%sum3 = add i32 %sum2, %y
|
|
ret i32 %sum3
|
|
}
|
|
|
|
define internal i32 @plus(i32 %x, i32 %y) {
|
|
; NOPLUS-NOT: @plus
|
|
%sum = add i32 %x, %y
|
|
%1 = extractvalue [3 x i32] [ i32 3, i32 0, i32 5 ], 2
|
|
%sum2 = add i32 %sum, %1
|
|
%sum3 = add i32 %sum2, %y
|
|
ret i32 %sum3
|
|
}
|
|
|
|
define internal i32 @next(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @next
|
|
%sum = add i32 %x, %y
|
|
%1 = extractvalue [3 x i32] [ i32 3, i32 0, i32 5 ], 2
|
|
%sum2 = add i32 %sum, %1
|
|
%sum3 = add i32 %sum2, %y
|
|
ret i32 %sum3
|
|
}
|
|
|