blob: 475b80b3bb070eec6d84366483e94d68e5c08df5 [file] [log] [blame]
Jim Grosbach4e0dbee2011-09-30 17:41:35 +00001; RUN: llc < %s -mtriple=arm-apple-darwin -relocation-model=dynamic-no-pic -mcpu=cortex-a8 -asm-verbose=false | FileCheck %s
Bob Wilson108aadf2009-11-18 22:52:37 +00002
3declare void @bar(i32)
4declare void @car(i32)
5declare void @dar(i32)
6declare void @ear(i32)
7declare void @far(i32)
8declare i1 @qux()
9
10@GHJK = global i32 0
11
Dan Gohmanfb419362010-01-05 17:55:26 +000012declare i8* @choose(i8*, i8*)
Bob Wilson108aadf2009-11-18 22:52:37 +000013
14; BranchFolding should tail-duplicate the indirect jump to avoid
15; redundant branching.
16
Stephen Lind24ab202013-07-14 06:24:09 +000017; CHECK-LABEL: tail_duplicate_me:
Bob Wilson108aadf2009-11-18 22:52:37 +000018; CHECK: qux
Evan Cheng2f2435d2011-01-21 18:55:51 +000019; CHECK: movw r{{[0-9]+}}, :lower16:_GHJK
20; CHECK: movt r{{[0-9]+}}, :upper16:_GHJK
Bob Wilson108aadf2009-11-18 22:52:37 +000021; CHECK: str r
22; CHECK-NEXT: bx r
Chandler Carruth4190b502012-04-16 13:49:17 +000023; CHECK: qux
Evan Cheng2f2435d2011-01-21 18:55:51 +000024; CHECK: movw r{{[0-9]+}}, :lower16:_GHJK
25; CHECK: movt r{{[0-9]+}}, :upper16:_GHJK
Bob Wilson108aadf2009-11-18 22:52:37 +000026; CHECK: str r
27; CHECK-NEXT: bx r
Evan Cheng2f2435d2011-01-21 18:55:51 +000028; CHECK: movw r{{[0-9]+}}, :lower16:_GHJK
29; CHECK: movt r{{[0-9]+}}, :upper16:_GHJK
Bob Wilson108aadf2009-11-18 22:52:37 +000030; CHECK: str r
31; CHECK-NEXT: bx r
32
33define void @tail_duplicate_me() nounwind {
34entry:
35 %a = call i1 @qux()
36 %c = call i8* @choose(i8* blockaddress(@tail_duplicate_me, %return),
37 i8* blockaddress(@tail_duplicate_me, %altret))
38 br i1 %a, label %A, label %next
39next:
40 %b = call i1 @qux()
41 br i1 %b, label %B, label %C
42
43A:
44 call void @bar(i32 0)
45 store i32 0, i32* @GHJK
46 br label %M
47
48B:
49 call void @car(i32 1)
50 store i32 0, i32* @GHJK
51 br label %M
52
53C:
54 call void @dar(i32 2)
55 store i32 0, i32* @GHJK
56 br label %M
57
58M:
59 indirectbr i8* %c, [label %return, label %altret]
60
61return:
62 call void @ear(i32 1000)
63 ret void
64altret:
65 call void @far(i32 1001)
66 ret void
67}
Reid Klecknera622fc92017-02-14 21:02:24 +000068
69; Use alternating abort functions so that the blocks we wish to merge are not
70; layout successors during branch folding.
71
72; CHECK-LABEL: merge_alternating_aborts:
73; CHECK-NOT: _abort
74; CHECK-NOT: _alt_abort
75; CHECK: bxne lr
76; CHECK-NOT: _abort
77; CHECK-NOT: _alt_abort
78; CHECK: LBB{{.*}}:
79; CHECK: mov lr, pc
80; CHECK: b _alt_abort
81; CHECK-NOT: _abort
82; CHECK-NOT: _alt_abort
83; CHECK: LBB{{.*}}:
84; CHECK: mov lr, pc
85; CHECK: b _abort
86; CHECK-NOT: _abort
87; CHECK-NOT: _alt_abort
88
89declare void @abort()
90declare void @alt_abort()
91
92define void @merge_alternating_aborts() {
93entry:
94 %c1 = call i1 @qux()
95 br i1 %c1, label %cont1, label %abort1
96abort1:
97 call void @abort()
98 unreachable
99cont1:
100 %c2 = call i1 @qux()
101 br i1 %c2, label %cont2, label %abort2
102abort2:
103 call void @alt_abort()
104 unreachable
105cont2:
106 %c3 = call i1 @qux()
107 br i1 %c3, label %cont3, label %abort3
108abort3:
109 call void @abort()
110 unreachable
111cont3:
112 %c4 = call i1 @qux()
113 br i1 %c4, label %cont4, label %abort4
114abort4:
115 call void @alt_abort()
116 unreachable
117cont4:
118 ret void
119}