1; RUN: llc < %s -mtriple=armv7 | FileCheck %s
2
3declare i16 @ret16(i16 returned)
4declare i32 @ret32(i32 returned)
5
6define i32 @test1(i32 %val) {
7; CHECK-LABEL: test1:
8; CHECK: bl {{_?}}ret16
9  %in = trunc i32 %val to i16
10  tail call i16 @ret16(i16 returned %in)
11  ret i32 %val
12}
13
14define i16 @test2(i32 %val) {
15; CHECK-LABEL: test2:
16; CHECK: b {{_?}}ret16
17  %in = trunc i32 %val to i16
18  tail call i16 @ret16(i16 returned %in)
19  ret i16 %in
20}
21
22declare {i32, i8} @take_i32_i8({i32, i8} returned)
23define { i8, i8 } @test_nocommon_value({i32, i32} %in) {
24; CHECK-LABEL: test_nocommon_value:
25; CHECK: b {{_?}}take_i32_i8
26
27  %first = extractvalue {i32, i32} %in, 0
28  %first.trunc = trunc i32 %first to i8
29
30  %second = extractvalue {i32, i32} %in, 1
31  %second.trunc = trunc i32 %second to i8
32
33  %tmp = insertvalue {i32, i8} undef, i32 %first, 0
34  %callval = insertvalue {i32, i8} %tmp, i8 %second.trunc, 1
35  tail call {i32, i8} @take_i32_i8({i32, i8} returned %callval)
36
37  %restmp = insertvalue {i8, i8} undef, i8 %first.trunc, 0
38  %res = insertvalue {i8, i8} %restmp, i8 %second.trunc, 1
39  ret {i8, i8} %res
40}
41
42declare {i32, {i32, i32}} @give_i32_i32_i32()
43define {{i32, i32}, i32} @test_structs_different_shape() {
44; CHECK-LABEL: test_structs_different_shape:
45; CHECK: b {{_?}}give_i32_i32_i32
46  %val = tail call {i32, {i32, i32}} @give_i32_i32_i32()
47
48  %first = extractvalue {i32, {i32, i32}} %val, 0
49  %second = extractvalue {i32, {i32, i32}} %val, 1, 0
50  %third = extractvalue {i32, {i32, i32}} %val, 1, 1
51
52  %restmp = insertvalue {{i32, i32}, i32} undef, i32 %first, 0, 0
53  %reseventmper = insertvalue {{i32, i32}, i32} %restmp, i32 %second, 0, 1
54  %res = insertvalue {{i32, i32}, i32} %reseventmper, i32 %third, 1
55
56  ret {{i32, i32}, i32} %res
57}
58
59define i32 @test_undef_asymmetry() {
60; CHECK: test_undef_asymmetry:
61; CHECK: bl {{_?}}ret32
62; CHECK-NOT: jmp
63  tail call i32 @ret32(i32 returned undef)
64  ret i32 2
65}
66
67define {{}, {{}, i32, {}}, [1 x i32]} @evil_empty_aggregates() {
68; CHECK-LABEL: evil_empty_aggregates:
69; CHECK: b {{_?}}give_i32_i32_i32
70  %agg = tail call {i32, {i32, i32}} @give_i32_i32_i32()
71
72  %first = extractvalue {i32, {i32, i32}} %agg, 0
73  %second = extractvalue {i32, {i32, i32}} %agg, 1, 0
74
75  %restmp = insertvalue {{}, {{}, i32, {}}, [1 x i32]} undef, i32 %first, 1, 1
76  %res = insertvalue {{}, {{}, i32, {}}, [1 x i32]} %restmp, i32 %second, 2, 0
77  ret {{}, {{}, i32, {}}, [1 x i32]} %res
78}
79
80define i32 @structure_is_unimportant() {
81; CHECK-LABEL: structure_is_unimportant:
82; CHECK: b {{_?}}give_i32_i32_i32
83  %val = tail call {i32, {i32, i32}} @give_i32_i32_i32()
84
85  %res = extractvalue {i32, {i32, i32}} %val, 0
86  ret i32 %res
87}
88
89declare i64 @give_i64()
90define i64 @direct_i64_ok() {
91; CHECK-LABEL: direct_i64_ok:
92; CHECK: b {{_?}}give_i64
93  %val = tail call i64 @give_i64()
94  ret i64 %val
95}
96
97declare {i64, i32} @give_i64_i32()
98define {i32, i32} @trunc_i64_not_ok() {
99; CHECK-LABEL: trunc_i64_not_ok:
100; CHECK: bl {{_?}}give_i64_i32
101  %agg = tail call {i64, i32} @give_i64_i32()
102
103  %first = extractvalue {i64, i32} %agg, 0
104  %second = extractvalue {i64, i32} %agg, 1
105  %first.trunc = trunc i64 %first to i32
106
107  %tmp = insertvalue {i32, i32} undef, i32 %first.trunc, 0
108  %ret = insertvalue {i32, i32} %tmp, i32 %second, 1
109
110  ret {i32, i32} %ret
111}
112