blob: ce1d7ebca6676f1207cad4907fed9b504cd216a6 [file] [log] [blame]
Tim Northover854c9272015-02-09 01:20:53 +00001; RUN: opt -S -deadargelim %s | FileCheck %s
2
3; Case 0: the basic example: an entire aggregate use is returned, but it's
4; actually only used in ways we can eliminate. We gain benefit from analysing
5; the "use" and applying its results to all sub-values.
6
7; CHECK-LABEL: define internal void @agguse_dead()
8
9define internal { i32, i32 } @agguse_dead() {
10 ret { i32, i32 } { i32 0, i32 1 }
11}
12
13define internal { i32, i32 } @test_agguse_dead() {
14 %val = call { i32, i32 } @agguse_dead()
15 ret { i32, i32 } %val
16}
17
18
19
20; Case 1: an opaque use of the aggregate exists (in this case dead). Otherwise
21; only one value is used, so function can be simplified.
22
23; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead()
24; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } { i32 0, i32 1 }, 1
25; CHECK: ret i32 [[RET]]
26
27define internal { i32, i32 } @rets_independent_if_agguse_dead() {
28 ret { i32, i32 } { i32 0, i32 1 }
29}
30
31define internal { i32, i32 } @test_rets_independent_if_agguse_dead(i1 %tst) {
32 %val = call { i32, i32 } @rets_independent_if_agguse_dead()
33 br i1 %tst, label %use_1, label %use_aggregate
34
35use_1:
36 ; This use can be classified as applying only to ret 1.
37 %val0 = extractvalue { i32, i32 } %val, 1
38 call void @callee(i32 %val0)
39 ret { i32, i32 } undef
40
41use_aggregate:
42 ; This use is assumed to apply to both 0 and 1.
43 ret { i32, i32 } %val
44}
45
46; Case 2: an opaque use of the aggregate exists (in this case *live*). Other
47; uses shouldn't matter.
48
49; CHECK-LABEL: define internal { i32, i32 } @rets_live_agguse()
50; CHECK: ret { i32, i32 } { i32 0, i32 1 }
51
52define internal { i32, i32 } @rets_live_agguse() {
53 ret { i32, i32} { i32 0, i32 1 }
54}
55
56define { i32, i32 } @test_rets_live_aggues(i1 %tst) {
57 %val = call { i32, i32 } @rets_live_agguse()
58 br i1 %tst, label %use_1, label %use_aggregate
59
60use_1:
61 ; This use can be classified as applying only to ret 1.
62 %val0 = extractvalue { i32, i32 } %val, 1
63 call void @callee(i32 %val0)
64 ret { i32, i32 } undef
65
66use_aggregate:
67 ; This use is assumed to apply to both 0 and 1.
68 ret { i32, i32 } %val
69}
70
71declare void @callee(i32)