562 lines · plain
1# RUN: llc -mtriple=thumbv8a-unknown-linux-gnueabi %s -o - -run-pass=if-converter -debug-only=if-converter | FileCheck %s2# RUN: llc -mtriple=thumbv7-unknown-linux-gnueabi %s -o - -run-pass=if-converter -debug-only=if-converter 2>%t| FileCheck %s3# RUN: FileCheck %s < %t --check-prefix=DEBUG4# REQUIRES: asserts5 6# When optimising for size, we use a different set of heuristics for7# if-conversion, which take into account the size of the instructions, not the8# time taken to execute them. This is more complicated for Thumb, where it if9# also affected by selection of narrow branch instructions, insertion if IT10# instructions, and selection of the CB(N)Z instructions.11 12--- |13 14 define void @fn1() minsize {15 entry:16 unreachable17 if.then:18 unreachable19 if.else:20 unreachable21 if.end:22 unreachable23 }24 25 define void @fn2() minsize {26 entry:27 unreachable28 if.then:29 unreachable30 if.else:31 unreachable32 if.end:33 unreachable34 }35 36 define void @fn3() minsize {37 entry:38 unreachable39 if.then:40 unreachable41 if.else:42 unreachable43 if.end:44 unreachable45 }46 47 define void @fn4() minsize "target-features"="-thumb-mode" {48 entry:49 unreachable50 if.then:51 unreachable52 if.else:53 unreachable54 if.end:55 unreachable56 }57 58 define void @fn5() minsize {59 entry:60 unreachable61 if.then:62 unreachable63 if.else:64 unreachable65 if.end:66 unreachable67 }68 69 define void @fn6() minsize {70 entry:71 unreachable72 if.then:73 unreachable74 if.else:75 unreachable76 if2.then:77 unreachable78 if2.else:79 unreachable80 }81 82 define void @fn7() minsize "target-features"="-thumb-mode" {83 entry:84 unreachable85 if.then:86 unreachable87 if.else:88 unreachable89 if.end:90 unreachable91 }92 93 define void @fn8() minsize {94 entry:95 unreachable96 if.then:97 unreachable98 if.else:99 unreachable100 if.end:101 unreachable102 }103 104 define void @fn9() minsize {105 entry:106 unreachable107 if.then:108 unreachable109 if.else:110 unreachable111 lab1:112 unreachable113 }114...115---116name: fn1117alignment: 1118tracksRegLiveness: true119 120# If-conversion is profitable here because it will remove two branches of 2121# bytes each (assuming they can become narrow branches later), and will only122# add 2 bytes with the IT instruction.123 124# CHECK-LABEL: name: fn1125# CHECK: t2CMPri126# CHECK-NEXT: t2LDRi12127# CHECK-NEXT: t2LDRi12128# CHECK-NEXT: t2LDRi12129# CHECK-NEXT: t2LDRSHi12130# CHECK-NEXT: t2MOVi131 132# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn1'133# DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=4, ExtraPredicateBytes=2)134 135body: |136 bb.0.entry:137 successors: %bb.1(0x40000000), %bb.2(0x40000000)138 liveins: $r0, $r1, $r2, $r3139 140 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr141 t2Bcc %bb.2, 11, killed $cpsr142 143 bb.1.if.then:144 successors: %bb.3(0x80000000)145 liveins: $r0, $r3146 147 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg148 t2B %bb.3, 14, $noreg149 150 bb.2.if.else:151 successors: %bb.3(0x80000000)152 liveins: $r1, $r3153 154 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg155 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg156 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg157 158 bb.3.if.end:159 liveins: $r0, $r3160 161 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg162 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg163 tBX_RET 14, $noreg, implicit $r0164 165---166name: fn2167alignment: 1168tracksRegLiveness: true169 170# If-conversion is not profitable here, because the 5 conditional instructions171# would require 2 IT instructions.172 173# CHECK-LABEL: name: fn2174# CHECK: t2CMPri175# CHECK-NEXT: t2Bcc176 177# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn2'178# DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=4)179 180body: |181 bb.0.entry:182 successors: %bb.1(0x40000000), %bb.2(0x40000000)183 liveins: $r0, $r1, $r2, $r3184 185 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr186 t2Bcc %bb.2, 11, killed $cpsr187 188 bb.1.if.then:189 successors: %bb.3(0x80000000)190 liveins: $r0, $r3191 192 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg193 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg194 t2B %bb.3, 14, $noreg195 196 bb.2.if.else:197 successors: %bb.3(0x80000000)198 liveins: $r1, $r3199 200 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg201 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg202 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg203 204 bb.3.if.end:205 liveins: $r0, $r3206 207 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg208 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg209 tBX_RET 14, $noreg, implicit $r0210 211---212name: fn3213alignment: 1214tracksRegLiveness: true215 216# Here, the true and false blocks both end in a tBX_RET instruction. One of217# these will be removed, saving 2 bytes, and the remaining one isn't218# conditional, so doesn't push us over the limit of 4 instructions in an IT219# block.220 221# CHECK-LABEL: name: fn3222# CHECK: t2CMPri223# CHECK-NEXT: t2LDRi12224# CHECK-NEXT: t2LDRi12225# CHECK-NEXT: t2LDRi12226# CHECK-NEXT: t2LDRSHi12227# CHECK-NEXT: tBX_RET228 229# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn3'230# DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=2, NumPredicatedInstructions=4, ExtraPredicateBytes=2)231 232body: |233 bb.0.entry:234 successors: %bb.1(0x40000000), %bb.2(0x40000000)235 liveins: $r0, $r1, $r2, $r3236 237 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr238 t2Bcc %bb.2, 11, killed $cpsr239 240 bb.1.if.then:241 liveins: $r0, $r3242 243 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg244 tBX_RET 14, $noreg, implicit $r0245 246 bb.2.if.else:247 liveins: $r1, $r3248 249 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg250 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg251 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg252 tBX_RET 14, $noreg, implicit $r0253 254---255name: fn4256alignment: 1257tracksRegLiveness: true258 259# This is the same as fn2, but compiled for ARM, which doesn't need IT260# instructions, so if-conversion is profitable.261 262# CHECK-LABEL: name: fn4263# CHECK: CMPri264# CHECK-NEXT: LDRi12265# CHECK-NEXT: LDRi12266# CHECK-NEXT: LDRSH267# CHECK-NEXT: LDRi12268# CHECK-NEXT: LDRi12269# CHECK-NEXT: MOVi270 271# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn4'272# DEBUG: MeetIfcvtSizeLimit(BranchBytes=8, CommonBytes=0, NumPredicatedInstructions=5, ExtraPredicateBytes=0)273 274body: |275 bb.0.entry:276 successors: %bb.1(0x40000000), %bb.2(0x40000000)277 liveins: $r0, $r1, $r2, $r3278 279 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr280 Bcc %bb.2, 11, killed $cpsr281 282 bb.1.if.then:283 successors: %bb.3(0x80000000)284 liveins: $r0, $r3285 286 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg287 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg288 B %bb.3289 290 bb.2.if.else:291 successors: %bb.3(0x80000000)292 liveins: $r1, $r3293 294 renamable $r0 = LDRi12 killed renamable $r1, 0, 14, $noreg295 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg296 renamable $r0 = LDRSH killed renamable $r0, $noreg, 0, 14, $noreg297 298 bb.3.if.end:299 liveins: $r0, $r3300 301 renamable $r1 = MOVi 0, 14, $noreg, $noreg302 STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg303 BX_RET 14, $noreg, implicit $r0304 305---306name: fn5307alignment: 1308tracksRegLiveness: true309 310# Here, the compare and conditional branch can be turned into a CBZ, so we311# don't want to if-convert.312 313# CHECK-LABEL: name: fn5314# CHECK: t2CMPri315# CHECK: t2Bcc316 317# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn5'318# DEBUG: MeetIfcvtSizeLimit(BranchBytes=0, CommonBytes=2, NumPredicatedInstructions=4, ExtraPredicateBytes=2)319 320body: |321 bb.0.entry:322 successors: %bb.1(0x30000000), %bb.2(0x50000000)323 liveins: $r0, $r1, $r2324 325 t2CMPri killed renamable $r2, 0, 14, $noreg, implicit-def $cpsr326 t2Bcc %bb.2, 1, killed $cpsr327 328 bb.1.if.then:329 liveins: $r0330 331 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg332 tBX_RET 14, $noreg, implicit $r0333 334 bb.2.if.else:335 liveins: $r1336 337 renamable $r0 = t2LDRi12 killed renamable $r1, 0, 14, $noreg338 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg339 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg340 tBX_RET 14, $noreg, implicit $r0341 342---343name: fn6344alignment: 1345tracksRegLiveness: true346 347# This is a forked-diamond pattern, we recognise that the conditional branches348# at the ends of the true and false blocks are the same, and can be shared.349 350# CHECK-LABEL: name: fn6351# CHECK: t2CMPri352# CHECK-NEXT: t2LDRSHi12353# CHECK-NEXT: t2LDRi12354# CHECK-NEXT: t2LDRi12355# CHECK-NEXT: t2LDRi12356# CHECK-NEXT: t2CMPri357# CHECK-NEXT: t2Bcc358 359# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn6'360# DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=12, NumPredicatedInstructions=4, ExtraPredicateBytes=2)361 362body: |363 bb.0.entry:364 successors: %bb.1(0x30000000), %bb.2(0x50000000)365 liveins: $r0, $r1, $r2, $r3366 367 t2CMPri killed renamable $r2, 4, 14, $noreg, implicit-def $cpsr368 t2Bcc %bb.2, 1, killed $cpsr369 370 bb.1.if.then:371 successors: %bb.3(0x30000000), %bb.4(0x50000000)372 liveins: $r0, $r1, $r3373 374 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg375 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg376 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg377 t2CMPri renamable $r0, 0, 14, $noreg, implicit-def $cpsr378 t2Bcc %bb.3.if2.then, 1, killed $cpsr379 t2B %bb.4.if2.else, 14, $noreg380 381 bb.2.if.else:382 successors: %bb.3(0x30000000), %bb.4(0x50000000)383 liveins: $r0, $r1, $r3384 385 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg386 t2CMPri renamable $r0, 0, 14, $noreg, implicit-def $cpsr387 t2Bcc %bb.3.if2.then, 1, killed $cpsr388 t2B %bb.4.if2.else, 14, $noreg389 390 bb.3.if2.then:391 liveins: $r0, $r1, $r3392 393 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg394 tBX_RET 14, $noreg, implicit $r0395 396 bb.4.if2.else:397 liveins: $r0398 399 tBX_RET 14, $noreg, implicit $r0400 401---402name: fn7403alignment: 1404tracksRegLiveness: true405 406# When compiling for ARM, it would be good for code size to generate very long407# runs of conditional instructions, but we put an (arbitrary) limit on this to408# avoid generating code which is very bad for performance, and only saves a few409# bytes of code size.410 411# CHECK-LABEL: name: fn7412# CHECK: CMPri413# CHECK-NEXT: Bcc414 415body: |416 bb.0.entry:417 successors: %bb.1(0x40000000), %bb.2(0x40000000)418 liveins: $r0, $r1, $r2, $r3419 420 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr421 Bcc %bb.2, 11, killed $cpsr422 423 bb.1.if.then:424 successors: %bb.3(0x80000000)425 liveins: $r0, $r3426 427 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg428 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg429 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg430 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg431 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg432 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg433 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg434 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg435 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg436 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg437 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg438 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg439 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg440 B %bb.3441 442 bb.2.if.else:443 successors: %bb.3(0x80000000)444 liveins: $r1, $r3445 446 renamable $r0 = LDRi12 killed renamable $r1, 0, 14, $noreg447 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg448 renamable $r0 = LDRSH killed renamable $r0, $noreg, 0, 14, $noreg449 450 bb.3.if.end:451 liveins: $r0, $r3452 453 renamable $r1 = MOVi 0, 14, $noreg, $noreg454 STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg455 BX_RET 14, $noreg, implicit $r0456 457---458name: fn8459alignment: 1460tracksRegLiveness: true461 462# The first t2LDRi12 instruction in each branch is the same, so one copy of it463# will be removed, and it doesn't need to be predicated, keeping us under the 4464# instruction IT block limit.465 466# CHECK-LABEL: name: fn8467# CHECK: t2CMPri468# CHECK-NEXT: t2LDRi12469# CHECK-NEXT: t2LDRi12470# CHECK-NEXT: t2LDRi12471# CHECK-NEXT: t2LDRi12472# CHECK-NEXT: t2LDRSHi12473# CHECK-NEXT: t2MOVi474 475# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn8'476# DEBUG: MeetIfcvtSizeLimit(BranchBytes=4, CommonBytes=4, NumPredicatedInstructions=4, ExtraPredicateBytes=2)477 478body: |479 bb.0.entry:480 successors: %bb.1(0x40000000), %bb.2(0x40000000)481 liveins: $r0, $r1, $r2, $r3482 483 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr484 t2Bcc %bb.2, 11, killed $cpsr485 486 bb.1.if.then:487 successors: %bb.3(0x80000000)488 liveins: $r0, $r3489 490 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg491 renamable $r0 = t2LDRi12 killed renamable $r0, 4, 14, $noreg492 t2B %bb.3, 14, $noreg493 494 bb.2.if.else:495 successors: %bb.3(0x80000000)496 liveins: $r0, $r3497 498 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg499 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg500 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg501 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg502 503 bb.3.if.end:504 liveins: $r0, $r3505 506 renamable $r1 = t2MOVi 0, 14, $noreg, $noreg507 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg508 tBX_RET 14, $noreg, implicit $r0509 510---511name: fn9512alignment: 2513tracksRegLiveness: true514 515# The INLINEASM_BR instructions aren't analyzable, but they are identical so we516# can still do diamond if-conversion. From a code-size POV, they are common517# instructions, so one will be removed, and they don't need an IT block slot.518 519# CHECK-LABEL: name: fn9520# CHECK: tCMPi8521# CHECK-NEXT: tLDRi522# CHECK-NEXT: tLDRi523# CHECK-NEXT: tLDRi524# CHECK-NEXT: t2LDRSHi12525# CHECK-NEXT: INLINEASM_BR526 527# DEBUG-LABEL: Ifcvt: function ({{[0-9]+}}) 'fn9'528# DEBUG: MeetIfcvtSizeLimit(BranchBytes=2, CommonBytes=8, NumPredicatedInstructions=4, ExtraPredicateBytes=2)529 530body: |531 bb.0.entry:532 successors: %bb.1(0x30000000), %bb.3(0x50000000)533 liveins: $r0, $r1, $r2534 535 tCMPi8 renamable $r2, 42, 14, $noreg, implicit-def $cpsr536 t2Bcc %bb.3, 1, killed $cpsr537 538 bb.1.if.then:539 successors: %bb.5(0x7fffffff)540 liveins: $r0, $r2541 542 renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg543 INLINEASM_BR &"b ${0:l}", 1, 13, blockaddress(@fn9, %ir-block.lab1)544 tBX_RET 14, $noreg, implicit $r2545 546 bb.3.if.else:547 successors: %bb.5(0x7fffffff)548 liveins: $r1, $r2549 550 renamable $r0 = tLDRi killed renamable $r1, 0, 14, $noreg551 renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg552 renamable $r0 = t2LDRSHi12 killed renamable $r0, 0, 14, $noreg553 INLINEASM_BR &"b ${0:l}", 1, 13, blockaddress(@fn9, %ir-block.lab1)554 tBX_RET 14, $noreg, implicit $r2555 556 bb.5.lab1 (ir-block-address-taken %ir-block.lab1):557 liveins: $r0558 559 renamable $r0, dead $cpsr = nsw tADDi8 killed renamable $r0, 5, 14, $noreg560 tBX_RET 14, $noreg, implicit $r0561...562