• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Tests the branch optimizations under O2 (against a lack of
2; optimizations under Om1).
3
4; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
5; RUN:   --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \
6; RUN:   | %if --need=target_X8632 --command FileCheck --check-prefix=O2 %s
7
8; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
9; RUN:   --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \
10; RUN:   | %if --need=target_X8632 --command FileCheck --check-prefix=OM1 %s
11
12; RUN: %if --need=target_ARM32_dump \
13; RUN:   --command %p2i --filetype=obj \
14; RUN:   --disassemble --target arm32 -i %s --args -O2 \
15; RUN:   -allow-externally-defined-symbols \
16; RUN:   | %if --need=target_ARM32_dump \
17; RUN:   --command FileCheck --check-prefix ARM32O2 %s
18
19; RUN: %if --need=target_ARM32 \
20; RUN:   --command %p2i --filetype=obj \
21; RUN:   --disassemble --target arm32 -i %s --args -Om1 \
22; RUN:   -allow-externally-defined-symbols \
23; RUN:   | %if --need=target_ARM32 \
24; RUN:   --command FileCheck \
25; RUN:   --check-prefix ARM32OM1 %s
26
27; RUN: %if --need=target_MIPS32 --need=allow_dump \
28; RUN:   --command %p2i --filetype=asm --assemble \
29; RUN:   --disassemble --target mips32 -i %s --args -O2 \
30; RUN:   -allow-externally-defined-symbols \
31; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
32; RUN:   --command FileCheck --check-prefix MIPS32O2 %s
33
34; RUN: %if --need=target_MIPS32 --need=allow_dump \
35; RUN:   --command %p2i --filetype=asm --assemble \
36; RUN:   --disassemble --target mips32 -i %s --args -Om1 \
37; RUN:   -allow-externally-defined-symbols \
38; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
39; RUN:   --command FileCheck \
40; RUN:   --check-prefix MIPS32OM1 %s
41
42declare void @dummy()
43
44; An unconditional branch to the next block should be removed.
45define internal void @testUncondToNextBlock() {
46entry:
47  call void @dummy()
48  br label %next
49next:
50  call void @dummy()
51  ret void
52}
53; O2-LABEL: testUncondToNextBlock
54; O2: call
55; There will be nops for bundle align to end (for NaCl), but there should
56; not be a branch.
57; O2-NOT: j
58; O2: call
59
60; OM1-LABEL: testUncondToNextBlock
61; OM1: call
62; OM1-NEXT: jmp
63; OM1: call
64
65; ARM32O2-LABEL: testUncondToNextBlock
66; ARM32O2: bl {{.*}} dummy
67; ARM32O2-NEXT: bl {{.*}} dummy
68
69; ARM32OM1-LABEL: testUncondToNextBlock
70; ARM32OM1: bl {{.*}} dummy
71; ARM32OM1-NEXT: b
72; ARM32OM1-NEXT: bl {{.*}} dummy
73
74; MIPS32O2-LABEL: testUncondToNextBlock
75; MIPS32O2: jal {{.*}} dummy
76; MIPS32O2-NEXT: nop
77; MIPS32O2-LABEL: <.LtestUncondToNextBlock$next>:
78; MIPS32O2-NEXT: jal {{.*}} dummy
79; MIPS32O2-NEXT: nop
80
81; MIPS32OM1-LABEL: testUncondToNextBlock
82; MIPS32OM1: jal {{.*}} dummy
83; MIPS32OM1-NEXT: nop
84; MIPS32OM1-NEXT: b {{.*}} <.LtestUncondToNextBlock$next>
85; MIPS32OM1-NEXT: nop
86; MIPS32OM1-LABEL: <.LtestUncondToNextBlock$next>:
87; MIPS32OM1-NEXT: jal {{.*}} dummy
88; MIPS32OM1-NEXT: nop
89
90; For a conditional branch with a fallthrough to the next block, the
91; fallthrough branch should be removed.
92define internal void @testCondFallthroughToNextBlock(i32 %arg) {
93entry:
94  %cmp = icmp sge i32 %arg, 123
95  br i1 %cmp, label %target, label %fallthrough
96fallthrough:
97  call void @dummy()
98  ret void
99target:
100  call void @dummy()
101  ret void
102}
103; O2-LABEL: testCondFallthroughToNextBlock
104; O2: cmp {{.*}},0x7b
105; O2-NEXT: jge
106; O2-NOT: j
107; O2: call
108; O2: ret
109; O2: call
110; O2: ret
111
112; OM1-LABEL: testCondFallthroughToNextBlock
113; OM1: cmp {{.*}},0x7b
114; OM1: setge
115; OM1: cmp
116; OM1: jne
117; OM1: jmp
118; OM1: call
119; OM1: ret
120; OM1: call
121; OM1: ret
122
123; ARM32O2-LABEL: testCondFallthroughToNextBlock
124; ARM32O2: cmp {{.*}}, #123
125; ARM32O2-NEXT: bge
126; ARM32O2-NEXT: bl
127; ARM32O2: bx lr
128; ARM32O2: bl
129; ARM32O2: bx lr
130
131; ARM32OM1-LABEL: testCondFallthroughToNextBlock
132; ARM32OM1: mov {{.*}}, #0
133; ARM32OM1: cmp {{.*}}, #123
134; ARM32OM1: movge {{.*}}, #1
135; ARM32OM1: tst {{.*}}, #1
136; ARM32OM1: bne
137; ARM32OM1: b
138; ARM32OM1: bl
139; ARM32OM1: bx lr
140; ARM32OM1: bl
141; ARM32OM1: bx lr
142
143; MIPS32O2-LABEL: testCondFallthroughToNextBlock
144; MIPS32O2: li {{.*}},123
145; MIPS32O2: slt {{.*}},{{.*}},{{.*}}
146; MIPS32O2: beqz
147; MIPS32O2: nop
148; MIPS32O2: .LtestCondFallthroughToNextBlock$fallthrough
149; MIPS32O2: jal {{.*}} dummy
150; MIPS32O2: nop
151; MIPS32O2: jr
152; MIPS32O2: nop
153; MIPS32O2: .LtestCondFallthroughToNextBlock$target
154; MIPS32O2: jal {{.*}} dummy
155; MIPS32O2: nop
156; MIPS32O2: jr
157; MIPS32O2: nop
158
159; MIPS32OM1-LABEL: testCondFallthroughToNextBlock
160; MIPS32OM1: li {{.*}},123
161; MIPS32OM1: slt {{.*}},{{.*}},{{.*}}
162; MIPS32OM1: xori {{.*}},{{.*}},{{.*}}
163; MIPS32OM1: beqz
164; MIPS32OM1: nop
165; MIPS32OM1: b
166; MIPS32OM1: nop
167; MIPS32OM1: .LtestCondFallthroughToNextBlock$fallthrough
168; MIPS32OM1: jal {{.*}} dummy
169; MIPS32OM1: nop
170; MIPS32OM1: jr
171; MIPS32OM1: nop
172; MIPS32OM1: .LtestCondFallthroughToNextBlock$target
173; MIPS32OM1: jal {{.*}} dummy
174; MIPS32OM1: nop
175; MIPS32OM1: jr
176; MIPS32OM1: nop
177
178; For a conditional branch with the next block as the target and a
179; different block as the fallthrough, the branch condition should be
180; inverted, the fallthrough block changed to the target, and the
181; branch to the next block removed.
182define internal void @testCondTargetNextBlock(i32 %arg) {
183entry:
184  %cmp = icmp sge i32 %arg, 123
185  br i1 %cmp, label %fallthrough, label %target
186fallthrough:
187  call void @dummy()
188  ret void
189target:
190  call void @dummy()
191  ret void
192}
193; O2-LABEL: testCondTargetNextBlock
194; O2: cmp {{.*}},0x7b
195; O2-NEXT: jl
196; O2-NOT: j
197; O2: call
198; O2: ret
199; O2: call
200; O2: ret
201
202; OM1-LABEL: testCondTargetNextBlock
203; OM1: cmp {{.*}},0x7b
204; OM1: setge
205; OM1: cmp
206; OM1: jne
207; OM1: jmp
208; OM1: call
209; OM1: ret
210; OM1: call
211; OM1: ret
212
213; Note that compare and branch folding isn't implemented yet
214; (compared to x86-32).
215; ARM32O2-LABEL: testCondTargetNextBlock
216; ARM32O2: cmp {{.*}}, #123
217; ARM32O2-NEXT: blt
218; ARM32O2-NEXT: bl
219; ARM32O2: bx lr
220; ARM32O2: bl
221; ARM32O2: bx lr
222
223; ARM32OM1-LABEL: testCondTargetNextBlock
224; ARM32OM1: cmp {{.*}}, #123
225; ARM32OM1: movge {{.*}}, #1
226; ARM32OM1: tst {{.*}}, #1
227; ARM32OM1: bne
228; ARM32OM1: b
229; ARM32OM1: bl
230; ARM32OM1: bx lr
231; ARM32OM1: bl
232; ARM32OM1: bx lr
233
234; MIPS32O2-LABEL: testCondTargetNextBlock
235; MIPS32O2: li {{.*}},123
236; MIPS32O2: slt {{.*}},{{.*}},{{.*}}
237; MIPS32O2: bnez
238; MIPS32O2: nop
239; MIPS32O2: .LtestCondTargetNextBlock$fallthrough
240; MIPS32O2: jal {{.*}} dummy
241; MIPS32O2: nop
242; MIPS32O2: jr
243; MIPS32O2: nop
244; MIPS32O2: .LtestCondTargetNextBlock$target
245; MIPS32O2: jal {{.*}} dummy
246; MIPS32O2: nop
247; MIPS32O2: jr
248; MIPS32O2: nop
249
250; MIPS32OM1-LABEL: testCondTargetNextBlock
251; MIPS32OM1: li {{.*}},123
252; MIPS32OM1: slt {{.*}},{{.*}},{{.*}}
253; MIPS32OM1: xori {{.*}},{{.*}},{{.*}}
254; MIPS32OM1: beqz
255; MIPS32OM1: nop
256; MIPS32OM1: b
257; MIPS32OM1: nop
258; MIPS32OM1: .LtestCondTargetNextBlock$fallthrough
259; MIPS32OM1: jal {{.*}} dummy
260; MIPS32OM1: nop
261; MIPS32OM1: jr
262; MIPS32OM1: nop
263; MIPS32OM1: .LtestCondTargetNextBlock$target
264; MIPS32OM1: jal {{.*}} dummy
265; MIPS32OM1: nop
266; MIPS32OM1: jr
267; MIPS32OM1: nop
268
269; Unconditional branches to the block after a contracted block should be
270; removed.
271define internal void @testUncondToBlockAfterContract() {
272entry:
273  call void @dummy()
274  br label %target
275contract:
276  br label %target
277target:
278  call void @dummy()
279  ret void
280}
281
282; O2-LABEL: testUncondToBlockAfterContract
283; O2: call
284; There will be nops for bundle align to end (for NaCl), but there should
285; not be a branch.
286; O2-NOT: j
287; O2: call
288
289; OM1-LABEL: testUncondToBlockAfterContract
290; OM1: call
291; OM1-NEXT: jmp
292; OM1: call
293
294; ARM32O2-LABEL: testUncondToBlockAfterContract
295; ARM32O2: bl {{.*}} dummy
296; ARM32O2-NEXT: bl {{.*}} dummy
297
298; ARM32OM1-LABEL: testUncondToBlockAfterContract
299; ARM32OM1: bl {{.*}} dummy
300; ARM32OM1-NEXT: b
301; ARM32OM1-NEXT: bl {{.*}} dummy
302
303; MIPS32O2-LABEL: testUncondToBlockAfterContract
304; MIPS32O2: jal {{.*}} dummy
305; MIPS32O2: .LtestUncondToBlockAfterContract$target
306
307; MIPS32OM1-LABEL: testUncondToBlockAfterContract
308; MIPS32OM1: jal {{.*}} dummy
309; MIPS32OM1: b
310; MIPS32OM1: .LtestUncondToBlockAfterContract$target
311