From 705d2af9e1d409274befa1580d5addea4a25edb9 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 9 Feb 2015 01:21:00 +0000 Subject: DeadArgElim: fix mismatch in accounting of array return types. Some parts of DeadArgElim were only considering the individual fields of StructTypes separately, but others (where insertvalue & extractvalue instructions occur) also looked into ArrayTypes. This one is an actual bug; the mismatch can lead to an argument being considered used by a return sub-value that isn't being tracked (and hence is dead by default). It then gets incorrectly eliminated. llvm-svn: 228559 --- llvm/test/Transforms/DeadArgElim/aggregates.ll | 46 +++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'llvm/test/Transforms/DeadArgElim/aggregates.ll') diff --git a/llvm/test/Transforms/DeadArgElim/aggregates.ll b/llvm/test/Transforms/DeadArgElim/aggregates.ll index ce1d7ebca66..153289947c1 100644 --- a/llvm/test/Transforms/DeadArgElim/aggregates.ll +++ b/llvm/test/Transforms/DeadArgElim/aggregates.ll @@ -68,4 +68,48 @@ use_aggregate: ret { i32, i32 } %val } -declare void @callee(i32) \ No newline at end of file +declare void @callee(i32) + +; Case 3: the insertvalue meant %in was live if ret-slot-1 was, but we were only +; tracking multiple ret-slots for struct types. So %in was eliminated +; incorrectly. + +; CHECK-LABEL: define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) + +define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) { + %ret = insertvalue [2 x i32] undef, i32 %in, 1 + ret [2 x i32] %ret +} + +define [2 x i32] @test_array_rets_have_multiple_slots() { + %res = call [2 x i32] @array_rets_have_multiple_slots(i32 42) + ret [2 x i32] %res +} + +; Case 4: we can remove some retvals from the array. It's nice to produce an +; array again having done so (rather than converting it to a struct). + +; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays() +; CHECK: [[VAL0:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 0 +; CHECK: [[RESTMP:%.*]] = insertvalue [2 x i32] undef, i32 [[VAL0]], 0 +; CHECK: [[VAL2:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 2 +; CHECK: [[RES:%.*]] = insertvalue [2 x i32] [[RESTMP]], i32 [[VAL2]], 1 +; CHECK: ret [2 x i32] [[RES]] + +; CHECK-LABEL: define void @test_can_shrink_arrays() + +define internal [3 x i32] @can_shrink_arrays() { + ret [3 x i32] [i32 42, i32 43, i32 44] +} + +define void @test_can_shrink_arrays() { + %res = call [3 x i32] @can_shrink_arrays() + + %res.0 = extractvalue [3 x i32] %res, 0 + call void @callee(i32 %res.0) + + %res.2 = extractvalue [3 x i32] %res, 2 + call void @callee(i32 %res.2) + + ret void +} -- cgit v1.2.3