diff options
| author | Tim Northover <tnorthover@apple.com> | 2015-02-09 01:21:00 +0000 | 
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2015-02-09 01:21:00 +0000 | 
| commit | 705d2af9e1d409274befa1580d5addea4a25edb9 (patch) | |
| tree | 7ce9712a4ea4f499176cee75b149b99546332f87 /llvm/test | |
| parent | 854c927de5caf761d85a89cfef4acbafd51bf01b (diff) | |
| download | bcm5719-llvm-705d2af9e1d409274befa1580d5addea4a25edb9.tar.gz bcm5719-llvm-705d2af9e1d409274befa1580d5addea4a25edb9.zip  | |
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
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/Transforms/DeadArgElim/aggregates.ll | 46 | 
1 files changed, 45 insertions, 1 deletions
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 +}  | 

