Currently global SRA uses the GEP structure to determine how to split the global. This patch instead analyses the loads and stores that are performed on the global, and collects which types are used at which offset, and then splits the global according to those. This is both more general, and works fine with opaque pointers. This is also closer to how ordinary SROA is performed. Differential Revision: https://reviews.llvm.org/D117223
28 lines
861 B
LLVM
28 lines
861 B
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -globalopt < %s | FileCheck %s
|
|
|
|
; Make sure we don't recursively SRA if there are aggregate load/stores with
|
|
; the same type as the global.
|
|
|
|
@g = internal global { i32, i32 } undef
|
|
|
|
define void @test() {
|
|
; CHECK-LABEL: @test(
|
|
; CHECK-NEXT: store { i32, i32 } zeroinitializer, { i32, i32 }* @g, align 4
|
|
; CHECK-NEXT: store { i32, i32 } { i32 0, i32 1 }, { i32, i32 }* @g, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
store { i32, i32 } zeroinitializer, { i32, i32 }* @g
|
|
store { i32, i32 } { i32 0, i32 1 }, { i32, i32 }* @g
|
|
ret void
|
|
}
|
|
|
|
define { i32, i32 } @load() {
|
|
; CHECK-LABEL: @load(
|
|
; CHECK-NEXT: [[V:%.*]] = load { i32, i32 }, { i32, i32 }* @g, align 4
|
|
; CHECK-NEXT: ret { i32, i32 } [[V]]
|
|
;
|
|
%v = load { i32, i32 }, { i32, i32 }* @g
|
|
ret { i32, i32 } %v
|
|
}
|