diff options
author | Chris Lattner <sabre@nondot.org> | 2009-01-31 02:28:54 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-01-31 02:28:54 +0000 |
commit | 2e0d5f84325303fa95997cd66485811bd0a6ef70 (patch) | |
tree | 6db9e4d4395caa4478b250af41b8ec2365baae50 /test/Transforms/ScalarRepl | |
parent | 66978ee97773aa76c3f15bee2fc77e5905aaf068 (diff) | |
download | external_llvm-2e0d5f84325303fa95997cd66485811bd0a6ef70.zip external_llvm-2e0d5f84325303fa95997cd66485811bd0a6ef70.tar.gz external_llvm-2e0d5f84325303fa95997cd66485811bd0a6ef70.tar.bz2 |
Simplify and generalize the SROA "convert to scalar" transformation to
be able to handle *ANY* alloca that is poked by loads and stores of
bitcasts and GEPs with constant offsets. Before the code had a number
of annoying limitations and caused it to miss cases such as storing into
holes in structs and complex casts (as in bitfield-sroa) where we had
unions of bitfields etc. This also handles a number of important cases
that are exposed due to the ABI lowering stuff we do to pass stuff by
value.
One case that is pretty great is that we compile
2006-11-07-InvalidArrayPromote.ll into:
define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind {
%tmp10 = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %v1)
%tmp105 = bitcast <4 x i32> %tmp10 to i128
%tmp1056 = zext i128 %tmp105 to i256
%tmp.upgrd.43 = lshr i256 %tmp1056, 96
%tmp.upgrd.44 = trunc i256 %tmp.upgrd.43 to i32
ret i32 %tmp.upgrd.44
}
which turns into:
_func:
subl $28, %esp
cvttps2dq %xmm1, %xmm0
movaps %xmm0, (%esp)
movl 12(%esp), %eax
addl $28, %esp
ret
Which is pretty good code all things considering :).
One effect of this is that SROA will start generating arbitrary bitwidth
integers that are a multiple of 8 bits. In the case above, we got a
256 bit integer, but the codegen guys assure me that it can handle the
simple and/or/shift/zext stuff that we're doing on these operations.
This addresses rdar://6532315
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63469 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/ScalarRepl')
-rw-r--r-- | test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll | 7 | ||||
-rw-r--r-- | test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll | 5 | ||||
-rw-r--r-- | test/Transforms/ScalarRepl/badarray.ll | 2 | ||||
-rw-r--r-- | test/Transforms/ScalarRepl/bitfield-sroa.ll | 16 |
4 files changed, 22 insertions, 8 deletions
diff --git a/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll b/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll index adfa5f8..4b7d622 100644 --- a/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll +++ b/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll @@ -1,9 +1,8 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \ -; RUN: grep alloca | grep {4 x} +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {ret i32 undef} -; Test that an array is not incorrectly deconstructed... +; Test that an array is not incorrectly deconstructed. -define i32 @test() { +define i32 @test() nounwind { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] %Y = getelementptr [4 x i32]* %X, i64 0, i64 0 ; <i32*> [#uses=1] ; Must preserve arrayness! diff --git a/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll b/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll index 1f3df49..f0253b7 100644 --- a/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll +++ b/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll @@ -1,7 +1,6 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \ -; RUN: grep -F {alloca \[2 x <4 x i32>\]} +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca -define i32 @func(<4 x float> %v0, <4 x float> %v1) { +define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind { %vsiidx = alloca [2 x <4 x i32>], align 16 ; <[2 x <4 x i32>]*> [#uses=3] %tmp = call <4 x i32> @llvm.x86.sse2.cvttps2dq( <4 x float> %v0 ) ; <<4 x i32>> [#uses=2] %tmp.upgrd.1 = bitcast <4 x i32> %tmp to <2 x i64> ; <<2 x i64>> [#uses=0] diff --git a/test/Transforms/ScalarRepl/badarray.ll b/test/Transforms/ScalarRepl/badarray.ll index 1e4714e..56ae04c 100644 --- a/test/Transforms/ScalarRepl/badarray.ll +++ b/test/Transforms/ScalarRepl/badarray.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -scalarrepl -mem2reg | llvm-dis | grep alloca +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 0} define i32 @test() { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] diff --git a/test/Transforms/ScalarRepl/bitfield-sroa.ll b/test/Transforms/ScalarRepl/bitfield-sroa.ll new file mode 100644 index 0000000..34dd120 --- /dev/null +++ b/test/Transforms/ScalarRepl/bitfield-sroa.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca +; rdar://6532315 +%t = type { { i32, i16, i8, i8 } } + +define i8 @foo(i64 %A) { + %ALL = alloca %t, align 8 + %tmp59172 = bitcast %t* %ALL to i64* + store i64 %A, i64* %tmp59172, align 8 + %C = getelementptr %t* %ALL, i32 0, i32 0, i32 1 + %D = bitcast i16* %C to i32* + %E = load i32* %D, align 4 + %F = bitcast %t* %ALL to i8* + %G = load i8* %F, align 8 + ret i8 %G +} + |