DeadArgElim: assess uses of entire return value aggregate.
[oota-llvm.git] / test / Transforms / DeadArgElim / aggregates.ll
1 ; 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
9 define internal { i32, i32 } @agguse_dead() {
10   ret { i32, i32 } { i32 0, i32 1 }
11 }
12
13 define 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
27 define internal { i32, i32 } @rets_independent_if_agguse_dead() {
28   ret { i32, i32 } { i32 0, i32 1 }
29 }
30
31 define 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
35 use_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
41 use_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
52 define internal { i32, i32 } @rets_live_agguse() {
53   ret { i32, i32} { i32 0, i32 1 }
54 }
55
56 define { 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
60 use_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
66 use_aggregate:
67   ; This use is assumed to apply to both 0 and 1.
68   ret { i32, i32 } %val
69 }
70
71 declare void @callee(i32)