summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/IPO/GlobalOpt.cpp4
-rw-r--r--llvm/test/Transforms/GlobalOpt/GSROA-section.ll30
-rw-r--r--llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/SROA-section.ll27
4 files changed, 89 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 6c115ac375b..d8fa4dfaef4 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -499,6 +499,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
GV->getThreadLocalMode(),
GV->getType()->getAddressSpace());
NGV->setExternallyInitialized(GV->isExternallyInitialized());
+ NGV->copyAttributesFrom(GV);
Globals.push_back(NGV);
NewGlobals.push_back(NGV);
@@ -533,6 +534,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
GV->getThreadLocalMode(),
GV->getType()->getAddressSpace());
NGV->setExternallyInitialized(GV->isExternallyInitialized());
+ NGV->copyAttributesFrom(GV);
Globals.push_back(NGV);
NewGlobals.push_back(NGV);
@@ -1291,6 +1293,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI,
*GV->getParent(), PFieldTy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(PFieldTy), GV->getName() + ".f" + Twine(FieldNo),
nullptr, GV->getThreadLocalMode());
+ NGV->copyAttributesFrom(GV);
FieldGlobals.push_back(NGV);
unsigned TypeSize = DL.getTypeAllocSize(FieldTy);
@@ -1610,6 +1613,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
GV->getName()+".b",
GV->getThreadLocalMode(),
GV->getType()->getAddressSpace());
+ NewGV->copyAttributesFrom(GV);
GV->getParent()->getGlobalList().insert(GV->getIterator(), NewGV);
Constant *InitVal = GV->getInitializer();
diff --git a/llvm/test/Transforms/GlobalOpt/GSROA-section.ll b/llvm/test/Transforms/GlobalOpt/GSROA-section.ll
new file mode 100644
index 00000000000..a439fa0797d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/GSROA-section.ll
@@ -0,0 +1,30 @@
+; This test lets globalopt split the global struct and array into different
+; values. The pass needs to preserve section attribute.
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; Check that the new global values still have their section assignment.
+; CHECK: @struct
+; CHECK: section ".foo"
+; CHECK: @array
+; CHECK-NOT: section ".foo"
+
+@struct = internal global { i32, i32 } zeroinitializer, section ".foo"
+@array = internal global [ 2 x i32 ] zeroinitializer
+
+define i32 @foo() {
+ %A = load i32, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
+ %B = load i32, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
+ ; Use the loaded values, so they won't get removed completely
+ %R = add i32 %A, %B
+ ret i32 %R
+}
+
+; We put stores in a different function, so that the global variables won't get
+; optimized away completely.
+define void @bar(i32 %R) {
+ store i32 %R, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
+ store i32 %R, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
+ ret void
+}
+
+
diff --git a/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll b/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll
new file mode 100644
index 00000000000..75b3cfec137
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll
@@ -0,0 +1,28 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+; CHECK: @Y.f0
+; CHECK: section ".foo"
+; CHECK: @Y.f1
+; CHECK: section ".foo"
+
+%struct.xyz = type { double, i32 }
+
+@Y = internal global %struct.xyz* null ,section ".foo" ; <%struct.xyz**> [#uses=2]
+@numf2s = external global i32 ; <i32*> [#uses=1]
+
+define void @init_net() {
+entry:
+ %0 = load i32, i32* @numf2s, align 4 ; <i32> [#uses=1]
+ %mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
+ %malloccall3 = tail call i8* @malloc(i32 %mallocsize2) ; <i8*> [#uses=1]
+ %1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
+ store %struct.xyz* %1, %struct.xyz** @Y, align 8
+ ret void
+}
+
+define void @load_train() {
+entry:
+ %0 = load %struct.xyz*, %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
diff --git a/llvm/test/Transforms/GlobalOpt/SROA-section.ll b/llvm/test/Transforms/GlobalOpt/SROA-section.ll
new file mode 100644
index 00000000000..1589608a67a
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/SROA-section.ll
@@ -0,0 +1,27 @@
+; Verify that section assignment is copied during SROA
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: @G.0
+; CHECK: section ".foo"
+; CHECK: @G.1
+; CHECK: section ".foo"
+; CHECK: @G.2
+; CHECK: section ".foo"
+
+%T = type { double, double, double }
+@G = internal global %T zeroinitializer, align 16, section ".foo"
+
+define void @test() {
+ store double 1.0, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ store double 2.0, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ store double 3.0, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ ret void
+}
+
+define double @test2() {
+ %V1 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ %V2 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ %V3 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ %R = fadd double %V1, %V2
+ %R2 = fadd double %R, %V3
+ ret double %R2
+}
OpenPOWER on IntegriCloud