1 # RUN: llc -mtriple=thumbv8a-unknown-linux-gnueabi %s -o - -run-pass=if-converter -debug-only=if-converter | FileCheck %s
2 # RUN: llc -mtriple=thumbv7-unknown-linux-gnueabi %s -o - -run-pass=if-converter -debug-only=if-converter 2>%t| FileCheck %s
3 # RUN: FileCheck %s < %t --check-prefix=DEBUG
6 # When optimising for size, we use a different set of heuristics for
7 # if-conversion, which take into account the size of the instructions, not the
8 # time taken to execute them. This is more complicated for Thumb, where it if
9 # also affected by selection of narrow branch instructions, insertion if IT
10 # instructions, and selection of the CB(N)Z instructions.
14 define void @fn1() minsize {
25 define void @fn2() minsize {
36 define void @fn3() minsize {
47 define void @fn4() minsize "target-features"="-thumb-mode" {
58 define void @fn5() minsize {
69 define void @fn6() minsize {
82 define void @fn7() minsize "target-features"="-thumb-mode" {
93 define void @fn8() minsize {
104 define void @fn9() minsize {
118 tracksRegLiveness: true
120 # If-conversion is profitable here because it will remove two branches of 2
121 # bytes each (assuming they can become narrow branches later), and will only
122 # add 2 bytes with the IT instruction.
124 # CHECK-LABEL: name: fn1
126 # CHECK-NEXT: t2LDRi12
127 # CHECK-NEXT: t2LDRi12
128 # CHECK-NEXT: t2LDRi12
129 # CHECK-NEXT: t2LDRSHi12
132 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn1'
133 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
137 successors: %bb.1(0x40000000), %bb.2(0x40000000)
138 liveins: $r0, $r1, $r2, $r3
140 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
141 t2Bcc %bb.2, 11, killed $cpsr
144 successors: %bb.3(0x80000000)
147 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
148 t2B %bb.3, 14, $noreg
151 successors: %bb.3(0x80000000)
154 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg
155 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
156 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
161 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg
162 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
163 tBX_RET 14, $noreg, implicit $r0
168 tracksRegLiveness: true
170 # If-conversion is not profitable here, because the 5 conditional instructions
171 # would require 2 IT instructions.
173 # CHECK-LABEL: name: fn2
177 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn2'
178 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=4)
182 successors: %bb.1(0x40000000), %bb.2(0x40000000)
183 liveins: $r0, $r1, $r2, $r3
185 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
186 t2Bcc %bb.2, 11, killed $cpsr
189 successors: %bb.3(0x80000000)
192 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
193 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
194 t2B %bb.3, 14, $noreg
197 successors: %bb.3(0x80000000)
200 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg
201 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
202 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
207 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg
208 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
209 tBX_RET 14, $noreg, implicit $r0
214 tracksRegLiveness: true
216 # Here, the true and false blocks both end in a tBX_RET instruction. One of
217 # these will be removed, saving 2 bytes, and the remaining one isn't
218 # conditional, so doesn't push us over the limit of 4 instructions in an IT
221 # CHECK-LABEL: name: fn3
223 # CHECK-NEXT: t2LDRi12
224 # CHECK-NEXT: t2LDRi12
225 # CHECK-NEXT: t2LDRi12
226 # CHECK-NEXT: t2LDRSHi12
227 # CHECK-NEXT: tBX_RET
229 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn3'
230 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=2, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
234 successors: %bb.1(0x40000000), %bb.2(0x40000000)
235 liveins: $r0, $r1, $r2, $r3
237 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
238 t2Bcc %bb.2, 11, killed $cpsr
243 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
244 tBX_RET 14, $noreg, implicit $r0
249 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg
250 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
251 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
252 tBX_RET 14, $noreg, implicit $r0
257 tracksRegLiveness: true
259 # This is the same as fn2, but compiled for ARM, which doesn't need IT
260 # instructions, so if-conversion is profitable.
262 # CHECK-LABEL: name: fn4
271 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn4'
272 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=8, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=0)
276 successors: %bb.1(0x40000000), %bb.2(0x40000000)
277 liveins: $r0, $r1, $r2, $r3
279 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
280 Bcc %bb.2, 11, killed $cpsr
283 successors: %bb.3(0x80000000)
286 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
287 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
291 successors: %bb.3(0x80000000)
294 renamable $r0 = LDRi12 killed renamable $r1, 0, 14, $noreg
295 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
296 renamable $r0 = LDRSH killed renamable $r0, $noreg, 0, 14, $noreg
301 renamable $r1 = MOVi 0, 14, $noreg, $noreg
302 STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
303 BX_RET 14, $noreg, implicit $r0
308 tracksRegLiveness: true
310 # Here, the compare and conditional branch can be turned into a CBZ, so we
311 # don't want to if-convert.
313 # CHECK-LABEL: name: fn5
317 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn5'
318 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=0, CommonBytes=2, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
322 successors: %bb.1(0x30000000), %bb.2(0x50000000)
323 liveins: $r0, $r1, $r2
325 t2CMPri killed renamable $r2, 0, 14, $noreg, implicit-def $cpsr
326 t2Bcc %bb.2, 1, killed $cpsr
331 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
332 tBX_RET 14, $noreg, implicit $r0
337 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg
338 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
339 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
340 tBX_RET 14, $noreg, implicit $r0
345 tracksRegLiveness: true
347 # This is a forked-diamond pattern, we recognise that the conditional branches
348 # at the ends of the true and false blocks are the same, and can be shared.
350 # CHECK-LABEL: name: fn6
352 # CHECK-NEXT: t2LDRSHi12
353 # CHECK-NEXT: t2LDRi12
354 # CHECK-NEXT: t2LDRi12
355 # CHECK-NEXT: t2LDRi12
356 # CHECK-NEXT: t2CMPri
359 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn6'
360 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=12, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
364 successors: %bb.1(0x30000000), %bb.2(0x50000000)
365 liveins: $r0, $r1, $r2, $r3
367 t2CMPri killed renamable $r2, 4, 14, $noreg, implicit-def $cpsr
368 t2Bcc %bb.2, 1, killed $cpsr
371 successors: %bb.3(0x30000000), %bb.4(0x50000000)
372 liveins: $r0, $r1, $r3
374 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
375 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
376 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
377 t2CMPri renamable $r0, 0, 14, $noreg, implicit-def $cpsr
378 t2Bcc %bb.3.if2.then, 1, killed $cpsr
379 t2B %bb.4.if2.else, 14, $noreg
382 successors: %bb.3(0x30000000), %bb.4(0x50000000)
383 liveins: $r0, $r1, $r3
385 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
386 t2CMPri renamable $r0, 0, 14, $noreg, implicit-def $cpsr
387 t2Bcc %bb.3.if2.then, 1, killed $cpsr
388 t2B %bb.4.if2.else, 14, $noreg
391 liveins: $r0, $r1, $r3
393 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
394 tBX_RET 14, $noreg, implicit $r0
399 tBX_RET 14, $noreg, implicit $r0
404 tracksRegLiveness: true
406 # When compiling for ARM, it would be good for code size to generate very long
407 # runs of conditional instructions, but we put an (arbitrary) limit on this to
408 # avoid generating code which is very bad for performance, and only saves a few
409 # bytes of code size.
411 # CHECK-LABEL: name: fn7
417 successors: %bb.1(0x40000000), %bb.2(0x40000000)
418 liveins: $r0, $r1, $r2, $r3
420 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
421 Bcc %bb.2, 11, killed $cpsr
424 successors: %bb.3(0x80000000)
427 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
428 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
429 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
430 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
431 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
432 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
433 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
434 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
435 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
436 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
437 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
438 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
439 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
443 successors: %bb.3(0x80000000)
446 renamable $r0 = LDRi12 killed renamable $r1, 0, 14, $noreg
447 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
448 renamable $r0 = LDRSH killed renamable $r0, $noreg, 0, 14, $noreg
453 renamable $r1 = MOVi 0, 14, $noreg, $noreg
454 STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
455 BX_RET 14, $noreg, implicit $r0
460 tracksRegLiveness: true
462 # The first t2LDRi12 instruction in each branch is the same, so one copy of it
463 # will be removed, and it doesn't need to be predicated, keeping us under the 4
464 # instruction IT block limit.
466 # CHECK-LABEL: name: fn8
468 # CHECK-NEXT: t2LDRi12
469 # CHECK-NEXT: t2LDRi12
470 # CHECK-NEXT: t2LDRi12
471 # CHECK-NEXT: t2LDRi12
472 # CHECK-NEXT: t2LDRSHi12
475 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn8'
476 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=4, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
480 successors: %bb.1(0x40000000), %bb.2(0x40000000)
481 liveins: $r0, $r1, $r2, $r3
483 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr
484 t2Bcc %bb.2, 11, killed $cpsr
487 successors: %bb.3(0x80000000)
490 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
491 renamable $r0 = t2LDRi12 killed renamable $r0, 4, 14, $noreg
492 t2B %bb.3, 14, $noreg
495 successors: %bb.3(0x80000000)
498 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
499 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
500 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
501 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
506 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg
507 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
508 tBX_RET 14, $noreg, implicit $r0
513 tracksRegLiveness: true
515 # The INLINEASM_BR instructions aren't analyzable, but they are identical so we
516 # can still do diamond if-conversion. From a code-size POV, they are common
517 # instructions, so one will be removed, and they don't need an IT block slot.
519 # CHECK-LABEL: name: fn9
524 # CHECK-NEXT: t2LDRSHi12
525 # CHECK-NEXT: INLINEASM_BR
527 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn9'
528 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=8, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
532 successors: %bb.1(0x30000000), %bb.3(0x50000000)
533 liveins: $r0, $r1, $r2
535 tCMPi8 renamable $r2, 42, 14, $noreg, implicit-def $cpsr
536 t2Bcc %bb.3, 1, killed $cpsr
539 successors: %bb.5(0x7fffffff)
542 renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg
543 INLINEASM_BR &"b ${0:l}", 1, 13, blockaddress(@fn9, %ir-block.lab1)
544 tBX_RET 14, $noreg, implicit $r2
547 successors: %bb.5(0x7fffffff)
550 renamable $r0 = tLDRi killed renamable $r1, 0, 14, $noreg
551 renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg
552 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg
553 INLINEASM_BR &"b ${0:l}", 1, 13, blockaddress(@fn9, %ir-block.lab1)
554 tBX_RET 14, $noreg, implicit $r2
556 bb.5.lab1 (ir-block-address-taken %ir-block.lab1):
559 renamable $r0, dead $cpsr = nsw tADDi8 killed renamable $r0, 5, 14, $noreg
560 tBX_RET 14, $noreg, implicit $r0