diff options
author | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
commit | e264f62ca09a8f65c87a46d562a4d0f9ec5d457e (patch) | |
tree | 59e3d57ef656cef79afa708ae0a3daf25cd91fcf /test/Transforms/DeadArgElim | |
download | external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.zip external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.gz external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.bz2 |
Check in LLVM r95781.
Diffstat (limited to 'test/Transforms/DeadArgElim')
-rw-r--r-- | test/Transforms/DeadArgElim/2006-06-27-struct-ret.ll | 11 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2007-02-07-FuncRename.ll | 11 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2007-10-18-VarargsReturn.ll | 12 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll | 20 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2008-01-16-VarargsParamAttrs.ll | 31 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2008-06-23-DeadAfterLive.ll | 23 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll | 26 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/basictest.ll | 36 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/canon.ll | 24 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/dead_vaargs.ll | 12 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/deadretval.ll | 18 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/deadretval2.ll | 59 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/dg.exp | 3 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/keepalive.ll | 30 | ||||
-rw-r--r-- | test/Transforms/DeadArgElim/multdeadretval.ll | 68 |
15 files changed, 384 insertions, 0 deletions
diff --git a/test/Transforms/DeadArgElim/2006-06-27-struct-ret.ll b/test/Transforms/DeadArgElim/2006-06-27-struct-ret.ll new file mode 100644 index 0000000..fac6dd2 --- /dev/null +++ b/test/Transforms/DeadArgElim/2006-06-27-struct-ret.ll @@ -0,0 +1,11 @@ +; RUN: opt < %s -deadargelim -disable-output + +define internal void @build_delaunay({ i32 }* sret %agg.result) { + ret void +} + +define void @test() { + call void @build_delaunay( { i32 }* sret null ) + ret void +} + diff --git a/test/Transforms/DeadArgElim/2007-02-07-FuncRename.ll b/test/Transforms/DeadArgElim/2007-02-07-FuncRename.ll new file mode 100644 index 0000000..d5bd6c4 --- /dev/null +++ b/test/Transforms/DeadArgElim/2007-02-07-FuncRename.ll @@ -0,0 +1,11 @@ +; RUN: opt < %s -deadargelim -S | grep {@test(} +; RUN: opt < %s -deadargelim -S | not grep dead + +define internal i32 @test(i32 %X, i32 %dead) { + ret i32 %X +} + +define i32 @caller() { + %A = call i32 @test(i32 123, i32 456) + ret i32 %A +} diff --git a/test/Transforms/DeadArgElim/2007-10-18-VarargsReturn.ll b/test/Transforms/DeadArgElim/2007-10-18-VarargsReturn.ll new file mode 100644 index 0000000..d4edce9 --- /dev/null +++ b/test/Transforms/DeadArgElim/2007-10-18-VarargsReturn.ll @@ -0,0 +1,12 @@ +; RUN: opt < %s -deadargelim -S | not grep {ret i32 0} +; PR1735 + +define internal i32 @test(i32 %A, ...) { + ret i32 %A +} + +define i32 @foo() { + %A = call i32(i32, ...)* @test(i32 1) + ret i32 %A +} + diff --git a/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll b/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll new file mode 100644 index 0000000..0e9c4f7 --- /dev/null +++ b/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -deadargelim -S > %t +; RUN: cat %t | grep nounwind | count 2 +; RUN: cat %t | grep signext | count 2 +; RUN: cat %t | not grep inreg +; RUN: cat %t | not grep zeroext +; RUN: cat %t | not grep byval + + %struct = type { } + +@g = global i8 0 + +define internal i8 @foo(i8* inreg %p, i8 signext %y, ... ) zeroext nounwind { + store i8 %y, i8* @g + ret i8 0 +} + +define i32 @bar() { + %A = call i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, %struct* byval null ) zeroext nounwind + ret i32 0 +} diff --git a/test/Transforms/DeadArgElim/2008-01-16-VarargsParamAttrs.ll b/test/Transforms/DeadArgElim/2008-01-16-VarargsParamAttrs.ll new file mode 100644 index 0000000..93282f7 --- /dev/null +++ b/test/Transforms/DeadArgElim/2008-01-16-VarargsParamAttrs.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -deadargelim -S | grep byval + + %struct.point = type { double, double } +@pts = global [4 x %struct.point] [ %struct.point { double 1.000000e+00, double 2.000000e+00 }, %struct.point { double 3.000000e+00, double 4.000000e+00 }, %struct.point { double 5.000000e+00, double 6.000000e+00 }, %struct.point { double 7.000000e+00, double 8.000000e+00 } ], align 32 ; <[4 x %struct.point]*> [#uses=1] + +define internal i32 @va1(i32 %nargs, ...) { +entry: + %pi = alloca %struct.point ; <%struct.point*> [#uses=0] + %args = alloca i8* ; <i8**> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + %args1 = bitcast i8** %args to i8* ; <i8*> [#uses=1] + call void @llvm.va_start( i8* %args1 ) + %args41 = bitcast i8** %args to i8* ; <i8*> [#uses=1] + call void @llvm.va_end( i8* %args41 ) + ret i32 undef +} + +declare void @llvm.va_start(i8*) nounwind + +declare void @llvm.va_end(i8*) nounwind + +define i32 @main() { +entry: + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + %tmp = getelementptr [4 x %struct.point]* @pts, i32 0, i32 0 ; <%struct.point*> [#uses=1] + %tmp1 = call i32 (i32, ...)* @va1( i32 1, %struct.point* byval %tmp ) nounwind ; <i32> [#uses=0] + call void @exit( i32 0 ) noreturn nounwind + unreachable +} + +declare void @exit(i32) noreturn nounwind diff --git a/test/Transforms/DeadArgElim/2008-06-23-DeadAfterLive.ll b/test/Transforms/DeadArgElim/2008-06-23-DeadAfterLive.ll new file mode 100644 index 0000000..adfd019 --- /dev/null +++ b/test/Transforms/DeadArgElim/2008-06-23-DeadAfterLive.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -deadargelim -die -S > %t +; RUN: cat %t | grep 123 + +; This test tries to catch wrongful removal of return values for a specific case +; that was break llvm-gcc builds. + +; This function has a live return value, it is used by @alive. +define internal i32 @test5() { + ret i32 123 +} + +; This function doesn't use the return value @test5 and tries to lure DAE into +; marking @test5's return value dead because only this call is unused. +define i32 @dead() { + %DEAD = call i32 @test5() + ret i32 0 +} + +; This function ensures the retval of @test5 is live. +define i32 @alive() { + %LIVE = call i32 @test5() + ret i32 %LIVE +} diff --git a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll new file mode 100644 index 0000000..f251d6c --- /dev/null +++ b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -deadargelim | llvm-dis +; PR3807 + +define internal { i32, i32 } @foo() { + ret {i32,i32} {i32 42, i32 4} +} + +define i32 @bar() { + %x = invoke {i32,i32} @foo() to label %T unwind label %T2 +T: + %y = extractvalue {i32,i32} %x, 1 + ret i32 %y +T2: + unreachable +} + +define i32 @bar2() { +entry: + %x = invoke {i32,i32} @foo() to label %T unwind label %T2 +T: + %PN = phi i32 [0, %entry] + %y = extractvalue {i32,i32} %x, 1 + ret i32 %y +T2: + unreachable +}
\ No newline at end of file diff --git a/test/Transforms/DeadArgElim/basictest.ll b/test/Transforms/DeadArgElim/basictest.ll new file mode 100644 index 0000000..9ac2222 --- /dev/null +++ b/test/Transforms/DeadArgElim/basictest.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -deadargelim -S | not grep DEADARG + +; test - an obviously dead argument +define internal i32 @test(i32 %v, i32 %DEADARG1, i32* %p) { + store i32 %v, i32* %p + ret i32 %v +} + +; hardertest - an argument which is only used by a call of a function with a +; dead argument. +define internal i32 @hardertest(i32 %DEADARG2) { + %p = alloca i32 ; <i32*> [#uses=1] + %V = call i32 @test( i32 5, i32 %DEADARG2, i32* %p ) ; <i32> [#uses=1] + ret i32 %V +} + +; evenhardertest - recursive dead argument... +define internal void @evenhardertest(i32 %DEADARG3) { + call void @evenhardertest( i32 %DEADARG3 ) + ret void +} + +define internal void @needarg(i32 %TEST) { + call i32 @needarg2( i32 %TEST ) ; <i32>:1 [#uses=0] + ret void +} + +define internal i32 @needarg2(i32 %TEST) { + ret i32 %TEST +} + +define internal void @needarg3(i32 %TEST3) { + call void @needarg( i32 %TEST3 ) + ret void +} + diff --git a/test/Transforms/DeadArgElim/canon.ll b/test/Transforms/DeadArgElim/canon.ll new file mode 100644 index 0000000..11cd482 --- /dev/null +++ b/test/Transforms/DeadArgElim/canon.ll @@ -0,0 +1,24 @@ +; This test shows a few canonicalizations made by deadargelim +; RUN: opt < %s -deadargelim -S > %t +; This test should remove {} and replace it with void +; RUN: cat %t | grep {define internal void @test} +; This test shouls replace the {i32} return value with just i32 +; RUN: cat %t | grep {define internal i32 @test2} + +define internal {} @test() { + ret {} undef +} + +define internal {i32} @test2() { + ret {i32} undef +} + +define void @caller() { + call {} @test() + %X = call {i32} @test2() + %Y = extractvalue {i32} %X, 0 + call void @user(i32 %Y, {i32} %X) + ret void +} + +declare void @user(i32, {i32}) diff --git a/test/Transforms/DeadArgElim/dead_vaargs.ll b/test/Transforms/DeadArgElim/dead_vaargs.ll new file mode 100644 index 0000000..db3135c --- /dev/null +++ b/test/Transforms/DeadArgElim/dead_vaargs.ll @@ -0,0 +1,12 @@ +; RUN: opt < %s -deadargelim -S | not grep 47 +; RUN: opt < %s -deadargelim -S | not grep 1.0 + +define i32 @bar(i32 %A) { + %tmp4 = tail call i32 (i32, ...)* @foo( i32 %A, i32 %A, i32 %A, i32 %A, i64 47, double 1.000000e+00 ) ; <i32> [#uses=1] + ret i32 %tmp4 +} + +define internal i32 @foo(i32 %X, ...) { + ret i32 %X +} + diff --git a/test/Transforms/DeadArgElim/deadretval.ll b/test/Transforms/DeadArgElim/deadretval.ll new file mode 100644 index 0000000..5f3817c --- /dev/null +++ b/test/Transforms/DeadArgElim/deadretval.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -deadargelim -S | not grep DEAD + +; Dead arg only used by dead retval +define internal i32 @test(i32 %DEADARG) { + ret i32 %DEADARG +} + +define i32 @test2(i32 %A) { + %DEAD = call i32 @test( i32 %A ) ; <i32> [#uses=0] + ret i32 123 +} + +define i32 @test3() { + %X = call i32 @test2( i32 3232 ) ; <i32> [#uses=1] + %Y = add i32 %X, -123 ; <i32> [#uses=1] + ret i32 %Y +} + diff --git a/test/Transforms/DeadArgElim/deadretval2.ll b/test/Transforms/DeadArgElim/deadretval2.ll new file mode 100644 index 0000000..dcdc36e --- /dev/null +++ b/test/Transforms/DeadArgElim/deadretval2.ll @@ -0,0 +1,59 @@ +; RUN: opt < %s -deadargelim -die -S > %t +; RUN: cat %t | not grep DEAD +; RUN: cat %t | grep LIVE | count 4 + +@P = external global i32 ; <i32*> [#uses=1] + +; Dead arg only used by dead retval +define internal i32 @test(i32 %DEADARG) { + ret i32 %DEADARG +} + +define internal i32 @test2(i32 %DEADARG) { + %DEADRETVAL = call i32 @test( i32 %DEADARG ) ; <i32> [#uses=1] + ret i32 %DEADRETVAL +} + +define void @test3(i32 %X) { + %DEADRETVAL = call i32 @test2( i32 %X ) ; <i32> [#uses=0] + ret void +} + +define internal i32 @foo() { + %DEAD = load i32* @P ; <i32> [#uses=1] + ret i32 %DEAD +} + +define internal i32 @id(i32 %X) { + ret i32 %X +} + +define void @test4() { + %DEAD = call i32 @foo( ) ; <i32> [#uses=1] + %DEAD2 = call i32 @id( i32 %DEAD ) ; <i32> [#uses=0] + ret void +} + +; These test if returning another functions return value properly marks that +; other function's return value as live. We do this twice, with the functions in +; different orders (ie, first the caller, than the callee and first the callee +; and then the caller) since DAE processes functions one by one and handles +; these cases slightly different. + +define internal i32 @test5() { + ret i32 123 +} + +define i32 @test6() { + %LIVE = call i32 @test5() + ret i32 %LIVE +} + +define i32 @test7() { + %LIVE = call i32 @test8() + ret i32 %LIVE +} + +define internal i32 @test8() { + ret i32 124 +} diff --git a/test/Transforms/DeadArgElim/dg.exp b/test/Transforms/DeadArgElim/dg.exp new file mode 100644 index 0000000..f200589 --- /dev/null +++ b/test/Transforms/DeadArgElim/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/DeadArgElim/keepalive.ll b/test/Transforms/DeadArgElim/keepalive.ll new file mode 100644 index 0000000..b0b9bf3 --- /dev/null +++ b/test/Transforms/DeadArgElim/keepalive.ll @@ -0,0 +1,30 @@ +; RUN: opt < %s -deadargelim -S > %t +; RUN: grep {define internal zeroext i32 @test1() nounwind} %t +; RUN: grep {define internal %Ty @test2} %t + +%Ty = type <{ i32, i32 }> + +; Check if the pass doesn't modify anything that doesn't need changing. We feed +; an unused argument to each function to lure it into changing _something_ about +; the function and then changing too much. + +; This checks if the return value attributes are not removed +define internal zeroext i32 @test1(i32 %DEADARG1) nounwind { + ret i32 1 +} + +; This checks if the struct doesn't get non-packed +define internal <{ i32, i32 }> @test2(i32 %DEADARG1) { + ret <{ i32, i32 }> <{ i32 1, i32 2 }> +} + +; We use this external function to make sure the return values don't become dead +declare void @user(i32, <{ i32, i32 }>) + +define void @caller() { + %B = call i32 @test1(i32 1) + %C = call <{ i32, i32 }> @test2(i32 2) + call void @user(i32 %B, <{ i32, i32 }> %C) + ret void +} + diff --git a/test/Transforms/DeadArgElim/multdeadretval.ll b/test/Transforms/DeadArgElim/multdeadretval.ll new file mode 100644 index 0000000..68d96ee --- /dev/null +++ b/test/Transforms/DeadArgElim/multdeadretval.ll @@ -0,0 +1,68 @@ +; This test sees if return values (and arguments) are properly removed when they +; are unused. All unused values are typed i16, so we can easily check. We also +; run instcombine to fold insert/extractvalue chains and we run dce to clean up +; any remaining dead stuff. +; RUN: opt < %s -deadargelim -instcombine -dce -S | not grep i16 + +define internal {i16, i32} @test(i16 %DEADARG) { + %A = insertvalue {i16,i32} undef, i16 1, 0 + %B = insertvalue {i16,i32} %A, i32 1001, 1 + ret {i16,i32} %B +} + +define internal {i32, i16} @test2() { + %DEAD = call i16 @test4() + %A = insertvalue {i32,i16} undef, i32 1, 0 + %B = insertvalue {i32,i16} %A, i16 %DEAD, 1 + ret {i32,i16} %B +} + +; Dead argument, used to check if the second result of test2 is dead even when +; it's used as a dead argument +define internal i32 @test3(i16 %A) { + %ret = call {i16, i32} @test( i16 %A ) ; <i32> [#uses=0] + %DEAD = extractvalue {i16, i32} %ret, 0 + %LIVE = extractvalue {i16, i32} %ret, 1 + ret i32 %LIVE +} + +define internal i16 @test4() { + ret i16 0 +} + +; Multiple return values, multiple live return values +define internal {i32, i32, i16} @test5() { + %A = insertvalue {i32,i32,i16} undef, i32 1, 0 + %B = insertvalue {i32,i32,i16} %A, i32 2, 1 + %C = insertvalue {i32,i32,i16} %B, i16 3, 2 + ret {i32, i32, i16} %C +} + +; Nested return values +define internal {{i32}, {i16, i16}} @test6() { + %A = insertvalue {{i32}, {i16, i16}} undef, i32 1, 0, 0 + %B = insertvalue {{i32}, {i16, i16}} %A, i16 2, 1, 0 + %C = insertvalue {{i32}, {i16, i16}} %B, i16 3, 1, 1 + ret {{i32}, {i16, i16}} %C +} + +define i32 @main() { + %ret = call {i32, i16} @test2() ; <i32> [#uses=1] + %LIVE = extractvalue {i32, i16} %ret, 0 + %DEAD = extractvalue {i32, i16} %ret, 1 + %Y = add i32 %LIVE, -123 ; <i32> [#uses=1] + %LIVE2 = call i32 @test3(i16 %DEAD) ; <i32> [#uses=1] + %Z = add i32 %LIVE2, %Y ; <i32> [#uses=1] + %ret1 = call { i32, i32, i16 } @test5 () + %LIVE3 = extractvalue { i32, i32, i16} %ret1, 0 + %LIVE4 = extractvalue { i32, i32, i16} %ret1, 1 + %DEAD2 = extractvalue { i32, i32, i16} %ret1, 2 + %V = add i32 %LIVE3, %LIVE4 + %W = add i32 %Z, %V + %ret2 = call { { i32 }, { i16, i16 } } @test6 () + %LIVE5 = extractvalue { { i32 }, { i16, i16 } } %ret2, 0, 0 + %DEAD3 = extractvalue { { i32 }, { i16, i16 } } %ret2, 1, 0 + %DEAD4 = extractvalue { { i32 }, { i16, i16 } } %ret2, 1, 1 + %Q = add i32 %W, %LIVE5 + ret i32 %Q +} |