summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2015-02-09 01:21:00 +0000
committerTim Northover <tnorthover@apple.com>2015-02-09 01:21:00 +0000
commit705d2af9e1d409274befa1580d5addea4a25edb9 (patch)
tree7ce9712a4ea4f499176cee75b149b99546332f87 /llvm/test
parent854c927de5caf761d85a89cfef4acbafd51bf01b (diff)
downloadbcm5719-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.ll46
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
+}
OpenPOWER on IntegriCloud