1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/test/Transforms/MergeFunc/merge-block-address.ll
JF Bastien 940c24167e Remove Merge Functions pointer comparisons
Summary:
This patch removes two remaining places where pointer value comparisons
are used to order functions: comparing range annotation metadata, and comparing
block address constants. (These are both rare cases, and so no actual
non-determinism was observed from either case).

The fix for range metadata is simple: the annotation always consists of a pair
of integers, so we just order by those integers.

The fix for block addresses is more subtle. Two constants are the same if they
are the same basic block in the same function, or if they refer to corresponding
basic blocks in each respective function. Note that in the first case, merging
is trivially correct. In the second, the correctness of merging relies on the
fact that the the values of block addresses cannot be compared. This change is
actually an enhancement, as these functions could not previously be merged (see
merge-block-address.ll).

There is still a problem with cross function block addresses, in that constants
pointing to a basic block in a merged function is not updated.

This also more robustly compares floating point constants by all fields of their
semantics, and fixes a dyn_cast/cast mixup.

Author: jrkoenig
Reviewers: dschuff, nlewycky, jfb
Subscribers llvm-commits
Differential revision: http://reviews.llvm.org/D12376

llvm-svn: 246305
2015-08-28 16:49:09 +00:00

92 lines
2.3 KiB
LLVM

; RUN: opt -S -mergefunc < %s | FileCheck %s
; These two functions are identical. The basic block labels are the same, and
; induce the same CFG. We are testing that block addresses within different
; functions are compared by their value, and not based on order. Both functions
; come from the same C-code, but in the first the two val_0/val_1 basic blocks
; are in a different order (they were manually switched post-compilation).
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i32 @_Z1fi(i32 %i) #0 {
entry:
%i.addr = alloca i32, align 4
%ret = alloca i32, align 4
%l = alloca i8*, align 8
store i32 %i, i32* %i.addr, align 4
store i32 0, i32* %ret, align 4
store i8* blockaddress(@_Z1fi, %val_0), i8** %l, align 8
%0 = load i32, i32* %i.addr, align 4
%and = and i32 %0, 256
%cmp = icmp eq i32 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then:
store i8* blockaddress(@_Z1fi, %val_1), i8** %l, align 8
br label %if.end
if.end:
%1 = load i8*, i8** %l, align 8
br label %indirectgoto
val_1:
store i32 42, i32* %ret, align 4
br label %end
val_0:
store i32 12, i32* %ret, align 4
br label %end
end:
%2 = load i32, i32* %ret, align 4
ret i32 %2
indirectgoto:
%indirect.goto.dest = phi i8* [ %1, %if.end ]
indirectbr i8* %indirect.goto.dest, [label %val_0, label %val_1]
}
define i32 @_Z1gi(i32 %i) #0 {
; CHECK-LABEL: define i32 @_Z1gi
; CHECK-NEXT: tail call i32 @_Z1fi
; CHECK-NEXT: ret
entry:
%i.addr = alloca i32, align 4
%ret = alloca i32, align 4
%l = alloca i8*, align 8
store i32 %i, i32* %i.addr, align 4
store i32 0, i32* %ret, align 4
store i8* blockaddress(@_Z1gi, %val_0), i8** %l, align 8
%0 = load i32, i32* %i.addr, align 4
%and = and i32 %0, 256
%cmp = icmp eq i32 %and, 0
br i1 %cmp, label %if.then, label %if.end
if.then:
store i8* blockaddress(@_Z1gi, %val_1), i8** %l, align 8
br label %if.end
if.end:
%1 = load i8*, i8** %l, align 8
br label %indirectgoto
val_0:
store i32 12, i32* %ret, align 4
br label %end
val_1:
store i32 42, i32* %ret, align 4
br label %end
end:
%2 = load i32, i32* %ret, align 4
ret i32 %2
indirectgoto:
%indirect.goto.dest = phi i8* [ %1, %if.end ]
indirectbr i8* %indirect.goto.dest, [label %val_0, label %val_1]
}