[clang-tidy][modernize-use-starts-ends-with] Fix operator rewriting false negative...
[llvm-project.git] / llvm / test / CodeGen / ARM / ifcvt-size.mir
blobbe065af498bd0079ad24ccbe1ee0cb9dd4baa596
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
4 # REQUIRES: asserts
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.
12 --- |
14   define void @fn1() minsize {
15   entry:
16     unreachable
17   if.then:
18     unreachable
19   if.else:
20     unreachable
21   if.end:
22     unreachable
23   }
25   define void @fn2() minsize {
26   entry:
27     unreachable
28   if.then:
29     unreachable
30   if.else:
31     unreachable
32   if.end:
33     unreachable
34   }
36   define void @fn3() minsize {
37   entry:
38     unreachable
39   if.then:
40     unreachable
41   if.else:
42     unreachable
43   if.end:
44     unreachable
45   }
47   define void @fn4() minsize "target-features"="-thumb-mode" {
48   entry:
49     unreachable
50   if.then:
51     unreachable
52   if.else:
53     unreachable
54   if.end:
55     unreachable
56   }
58   define void @fn5() minsize {
59   entry:
60     unreachable
61   if.then:
62     unreachable
63   if.else:
64     unreachable
65   if.end:
66     unreachable
67   }
69   define void @fn6() minsize {
70   entry:
71     unreachable
72   if.then:
73     unreachable
74   if.else:
75     unreachable
76   if2.then:
77     unreachable
78   if2.else:
79     unreachable
80   }
82   define void @fn7() minsize "target-features"="-thumb-mode" {
83   entry:
84     unreachable
85   if.then:
86     unreachable
87   if.else:
88     unreachable
89   if.end:
90     unreachable
91   }
93   define void @fn8() minsize {
94   entry:
95     unreachable
96   if.then:
97     unreachable
98   if.else:
99     unreachable
100   if.end:
101     unreachable
102   }
104   define void @fn9() minsize {
105   entry:
106     unreachable
107   if.then:
108     unreachable
109   if.else:
110     unreachable
111   lab1:
112     unreachable
113   }
116 name:            fn1
117 alignment:       1
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
125 # CHECK:      t2CMPri
126 # CHECK-NEXT: t2LDRi12
127 # CHECK-NEXT: t2LDRi12
128 # CHECK-NEXT: t2LDRi12
129 # CHECK-NEXT: t2LDRSHi12
130 # CHECK-NEXT: t2MOVi
132 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn1'
133 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
135 body:             |
136   bb.0.entry:
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
143   bb.1.if.then:
144     successors: %bb.3(0x80000000)
145     liveins: $r0, $r3
147     renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
148     t2B %bb.3, 14, $noreg
150   bb.2.if.else:
151     successors: %bb.3(0x80000000)
152     liveins: $r1, $r3
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
158   bb.3.if.end:
159     liveins: $r0, $r3
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
166 name:            fn2
167 alignment:       1
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
174 # CHECK:      t2CMPri
175 # CHECK-NEXT: t2Bcc
177 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn2'
178 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=4)
180 body:             |
181   bb.0.entry:
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
188   bb.1.if.then:
189     successors: %bb.3(0x80000000)
190     liveins: $r0, $r3
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
196   bb.2.if.else:
197     successors: %bb.3(0x80000000)
198     liveins: $r1, $r3
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
204   bb.3.if.end:
205     liveins: $r0, $r3
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
212 name:            fn3
213 alignment:       1
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
219 # block.
221 # CHECK-LABEL: name:            fn3
222 # CHECK:      t2CMPri
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)
232 body:             |
233   bb.0.entry:
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
240   bb.1.if.then:
241     liveins: $r0, $r3
243     renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
244     tBX_RET 14, $noreg, implicit $r0
246   bb.2.if.else:
247     liveins: $r1, $r3
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
255 name:            fn4
256 alignment:       1
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
263 # CHECK:      CMPri
264 # CHECK-NEXT: LDRi12
265 # CHECK-NEXT: LDRi12
266 # CHECK-NEXT: LDRSH
267 # CHECK-NEXT: LDRi12
268 # CHECK-NEXT: LDRi12
269 # CHECK-NEXT: MOVi
271 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn4'
272 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=8, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=0)
274 body:             |
275   bb.0.entry:
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
282   bb.1.if.then:
283     successors: %bb.3(0x80000000)
284     liveins: $r0, $r3
286     renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
287     renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg
288     B %bb.3
290   bb.2.if.else:
291     successors: %bb.3(0x80000000)
292     liveins: $r1, $r3
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
298   bb.3.if.end:
299     liveins: $r0, $r3
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
306 name:            fn5
307 alignment:       1
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
314 # CHECK: t2CMPri
315 # CHECK: t2Bcc
317 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn5'
318 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=0, CommonBytes=2, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
320 body:             |
321   bb.0.entry:
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
328   bb.1.if.then:
329     liveins: $r0
331     renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg
332     tBX_RET 14, $noreg, implicit $r0
334   bb.2.if.else:
335     liveins: $r1
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
343 name:            fn6
344 alignment:       1
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
351 # CHECK:      t2CMPri
352 # CHECK-NEXT: t2LDRSHi12
353 # CHECK-NEXT: t2LDRi12
354 # CHECK-NEXT: t2LDRi12
355 # CHECK-NEXT: t2LDRi12
356 # CHECK-NEXT: t2CMPri
357 # CHECK-NEXT: t2Bcc
359 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn6'
360 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=12, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
362 body:             |
363   bb.0.entry:
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
370   bb.1.if.then:
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
381   bb.2.if.else:
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
390   bb.3.if2.then:
391     liveins: $r0, $r1, $r3
393     t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg
394     tBX_RET 14, $noreg, implicit $r0
396   bb.4.if2.else:
397     liveins: $r0
399     tBX_RET 14, $noreg, implicit $r0
402 name:            fn7
403 alignment:       1
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
412 # CHECK:      CMPri
413 # CHECK-NEXT: Bcc
415 body:             |
416   bb.0.entry:
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
423   bb.1.if.then:
424     successors: %bb.3(0x80000000)
425     liveins: $r0, $r3
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
440     B %bb.3
442   bb.2.if.else:
443     successors: %bb.3(0x80000000)
444     liveins: $r1, $r3
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
450   bb.3.if.end:
451     liveins: $r0, $r3
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
458 name:            fn8
459 alignment:       1
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
467 # CHECK:      t2CMPri
468 # CHECK-NEXT: t2LDRi12
469 # CHECK-NEXT: t2LDRi12
470 # CHECK-NEXT: t2LDRi12
471 # CHECK-NEXT: t2LDRi12
472 # CHECK-NEXT: t2LDRSHi12
473 # CHECK-NEXT: t2MOVi
475 # DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn8'
476 # DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=4, NumPredicatedInstructions=4, ExtraPredicateBytes=2)
478 body:             |
479   bb.0.entry:
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
486   bb.1.if.then:
487     successors: %bb.3(0x80000000)
488     liveins: $r0, $r3
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
494   bb.2.if.else:
495     successors: %bb.3(0x80000000)
496     liveins: $r0, $r3
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
503   bb.3.if.end:
504     liveins: $r0, $r3
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
511 name:            fn9
512 alignment:       2
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
520 # CHECK:      tCMPi8
521 # CHECK-NEXT: tLDRi
522 # CHECK-NEXT: tLDRi
523 # CHECK-NEXT: tLDRi
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)
530 body:             |
531   bb.0.entry:
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
538   bb.1.if.then:
539     successors:  %bb.5(0x7fffffff)
540     liveins: $r0, $r2
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
546   bb.3.if.else:
547     successors: %bb.5(0x7fffffff)
548     liveins: $r1, $r2
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
555     
556   bb.5.lab1 (ir-block-address-taken %ir-block.lab1):
557     liveins: $r0
559     renamable $r0, dead $cpsr = nsw tADDi8 killed renamable $r0, 5, 14, $noreg
560     tBX_RET 14, $noreg, implicit $r0