diff options
author | Hal Finkel <hfinkel@anl.gov> | 2013-07-16 17:10:55 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2013-07-16 17:10:55 +0000 |
commit | 5a5ebb7f9fa7fa82c0c466a36a90e5c18bb13073 (patch) | |
tree | a78ba9387b19f55633afbc1fee33bae754514e0a /test/Transforms/Inline | |
parent | 95779b65cf7b7d7c22bf2d22d03c661c8130cbe2 (diff) | |
download | external_llvm-5a5ebb7f9fa7fa82c0c466a36a90e5c18bb13073.zip external_llvm-5a5ebb7f9fa7fa82c0c466a36a90e5c18bb13073.tar.gz external_llvm-5a5ebb7f9fa7fa82c0c466a36a90e5c18bb13073.tar.bz2 |
When the inliner merges allocas, it must keep the larger alignment
For safety, the inliner cannot decrease the allignment on an alloca when
merging it with another.
I've included two variants of the test case for this: one with DataLayout
available, and one without. When DataLayout is not available, if only one of
the allocas uses the default alignment (getAlignment() == 0), then they cannot
be safely merged.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/Inline')
-rw-r--r-- | test/Transforms/Inline/alloca-merge-align-nodl.ll | 93 | ||||
-rw-r--r-- | test/Transforms/Inline/alloca-merge-align.ll | 94 |
2 files changed, 187 insertions, 0 deletions
diff --git a/test/Transforms/Inline/alloca-merge-align-nodl.ll b/test/Transforms/Inline/alloca-merge-align-nodl.ll new file mode 100644 index 0000000..203f52b --- /dev/null +++ b/test/Transforms/Inline/alloca-merge-align-nodl.ll @@ -0,0 +1,93 @@ +; RUN: opt < %s -inline -S | FileCheck %s +; This variant of the test has no data layout information. +target triple = "powerpc64-unknown-linux-gnu" + +%struct.s = type { i32, i32 } + +define void @foo(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32], align 4 + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 4, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +define void @foo0(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32] + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 4, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +declare void @bar(i32*) #1 + +define void @goo(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32], align 32 + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 32, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +; CHECK-LABEL: @main +; CHECK: alloca [2 x i32], align 32 +; CHECK-NOT: alloca [2 x i32] +; CHECK: ret i32 0 + +define signext i32 @main() { +entry: + %a = alloca i64, align 8 + %tmpcast = bitcast i64* %a to %struct.s* + store i64 0, i64* %a, align 8 + %a1 = bitcast i64* %a to i32* + store i32 1, i32* %a1, align 8, !tbaa !0 + call void @foo(%struct.s* byval %tmpcast) + store i32 2, i32* %a1, align 8, !tbaa !0 + call void @goo(%struct.s* byval %tmpcast) + ret i32 0 +} + +; CHECK-LABEL: @test0 +; CHECK: alloca [2 x i32], align 32 +; CHECK: alloca [2 x i32] +; CHECK: ret i32 0 + +define signext i32 @test0() { +entry: + %a = alloca i64, align 8 + %tmpcast = bitcast i64* %a to %struct.s* + store i64 0, i64* %a, align 8 + %a1 = bitcast i64* %a to i32* + store i32 1, i32* %a1, align 8, !tbaa !0 + call void @foo0(%struct.s* byval %tmpcast) + store i32 2, i32* %a1, align 8, !tbaa !0 + call void @goo(%struct.s* byval %tmpcast) + ret i32 0 +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} + diff --git a/test/Transforms/Inline/alloca-merge-align.ll b/test/Transforms/Inline/alloca-merge-align.ll new file mode 100644 index 0000000..de4707d --- /dev/null +++ b/test/Transforms/Inline/alloca-merge-align.ll @@ -0,0 +1,94 @@ +; RUN: opt < %s -inline -S | FileCheck %s + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +%struct.s = type { i32, i32 } + +define void @foo(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32], align 4 + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 4, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +define void @foo0(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32] + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 4, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +declare void @bar(i32*) #1 + +define void @goo(%struct.s* byval nocapture readonly %a) { +entry: + %x = alloca [2 x i32], align 32 + %a1 = getelementptr inbounds %struct.s* %a, i64 0, i32 0 + %0 = load i32* %a1, align 4, !tbaa !0 + %arrayidx = getelementptr inbounds [2 x i32]* %x, i64 0, i64 0 + store i32 %0, i32* %arrayidx, align 32, !tbaa !0 + %b = getelementptr inbounds %struct.s* %a, i64 0, i32 1 + %1 = load i32* %b, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1 + store i32 %1, i32* %arrayidx2, align 4, !tbaa !0 + call void @bar(i32* %arrayidx) #2 + ret void +} + +; CHECK-LABEL: @main +; CHECK: alloca [2 x i32], align 32 +; CHECK-NOT: alloca [2 x i32] +; CHECK: ret i32 0 + +define signext i32 @main() { +entry: + %a = alloca i64, align 8 + %tmpcast = bitcast i64* %a to %struct.s* + store i64 0, i64* %a, align 8 + %a1 = bitcast i64* %a to i32* + store i32 1, i32* %a1, align 8, !tbaa !0 + call void @foo(%struct.s* byval %tmpcast) + store i32 2, i32* %a1, align 8, !tbaa !0 + call void @goo(%struct.s* byval %tmpcast) + ret i32 0 +} + +; CHECK-LABEL: @test0 +; CHECK: alloca [2 x i32], align 32 +; CHECK-NOT: alloca [2 x i32] +; CHECK: ret i32 0 + +define signext i32 @test0() { +entry: + %a = alloca i64, align 8 + %tmpcast = bitcast i64* %a to %struct.s* + store i64 0, i64* %a, align 8 + %a1 = bitcast i64* %a to i32* + store i32 1, i32* %a1, align 8, !tbaa !0 + call void @foo0(%struct.s* byval %tmpcast) + store i32 2, i32* %a1, align 8, !tbaa !0 + call void @goo(%struct.s* byval %tmpcast) + ret i32 0 +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} + |