mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 10:04:33 +00:00
1cff5e8007
When GlobalOpt splits an internal, global variable with an aggregate type, it should propagate the externally_initialized flag to the newly created globals. This makes the pass safe for our downstream use of this flag, while still allowing some useful optimisations (such as removing dead parts of the split aggregate) to be performed. Differential Revision: http://reviews.llvm.org/D13382 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252490 91177308-0d34-0410-b5e6-96231b3b80d8
51 lines
2.1 KiB
LLVM
51 lines
2.1 KiB
LLVM
; RUN: opt < %s -S -globalopt | FileCheck %s
|
|
|
|
; This global is externally_initialized, so if we split it into scalars we
|
|
; should keep that flag set on all of the new globals. This will prevent the
|
|
; store to @a[0] from being constant propagated to the load in @foo, but will not
|
|
; prevent @a[1] from being removed since it is dead.
|
|
; CHECK: @a.0 = internal unnamed_addr externally_initialized global i32 undef
|
|
; CHECK-NOT @a.1
|
|
@a = internal externally_initialized global [2 x i32] undef, align 4
|
|
; This is the same, but a struct rather than an array.
|
|
; CHECK: @b.0 = internal unnamed_addr externally_initialized global i32 undef
|
|
; CHECK-NOT @b.1
|
|
@b = internal externally_initialized global {i32, i32} undef, align 4
|
|
|
|
define i32 @foo() {
|
|
; CHECK-LABEL: define i32 @foo
|
|
entry:
|
|
; This load uses the split global, but cannot be constant-propagated away.
|
|
; CHECK: %0 = load i32, i32* @a.0
|
|
%0 = load i32, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 0), align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define i32 @bar() {
|
|
; CHECK-LABEL: define i32 @bar
|
|
entry:
|
|
; This load uses the split global, but cannot be constant-propagated away.
|
|
; CHECK: %0 = load i32, i32* @b.0
|
|
%0 = load i32, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 0), align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define void @init() {
|
|
; CHECK-LABEL: define void @init
|
|
entry:
|
|
; This store uses the split global, but cannot be constant-propagated away.
|
|
; CHECK: store i32 1, i32* @a.0
|
|
store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 0), align 4
|
|
; This store can be removed, because the second element of @a is never read.
|
|
; CHECK-NOT: store i32 2, i32* @a.1
|
|
store i32 2, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 1), align 4
|
|
|
|
; This store uses the split global, but cannot be constant-propagated away.
|
|
; CHECK: store i32 3, i32* @b.0
|
|
store i32 3, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 0), align 4
|
|
; This store can be removed, because the second element of @b is never read.
|
|
; CHECK-NOT: store i32 4, i32* @b.1
|
|
store i32 4, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 1), align 4
|
|
ret void
|
|
}
|