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 5 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. 11 12--- | 13 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 } 24 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 } 35 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 } 46 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 } 57 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 } 68 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 } 81 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 } 92 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 } 103 104 define void @fn9() minsize { 105 entry: 106 unreachable 107 if.then: 108 unreachable 109 if.else: 110 unreachable 111 lab1: 112 unreachable 113 } 114... 115--- 116name: fn1 117alignment: 1 118tracksRegLiveness: true 119 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. 123 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 131 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, $r3 139 140 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 141 t2Bcc %bb.2, 11, killed $cpsr 142 143 bb.1.if.then: 144 successors: %bb.3(0x80000000) 145 liveins: $r0, $r3 146 147 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg 148 t2B %bb.3, 14, $noreg 149 150 bb.2.if.else: 151 successors: %bb.3(0x80000000) 152 liveins: $r1, $r3 153 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 157 158 bb.3.if.end: 159 liveins: $r0, $r3 160 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 164 165--- 166name: fn2 167alignment: 1 168tracksRegLiveness: true 169 170# If-conversion is not profitable here, because the 5 conditional instructions 171# would require 2 IT instructions. 172 173# CHECK-LABEL: name: fn2 174# CHECK: t2CMPri 175# CHECK-NEXT: t2Bcc 176 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, $r3 184 185 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 186 t2Bcc %bb.2, 11, killed $cpsr 187 188 bb.1.if.then: 189 successors: %bb.3(0x80000000) 190 liveins: $r0, $r3 191 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 195 196 bb.2.if.else: 197 successors: %bb.3(0x80000000) 198 liveins: $r1, $r3 199 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 203 204 bb.3.if.end: 205 liveins: $r0, $r3 206 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 210 211--- 212name: fn3 213alignment: 1 214tracksRegLiveness: true 215 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. 220 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 228 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, $r3 236 237 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 238 t2Bcc %bb.2, 11, killed $cpsr 239 240 bb.1.if.then: 241 liveins: $r0, $r3 242 243 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg 244 tBX_RET 14, $noreg, implicit $r0 245 246 bb.2.if.else: 247 liveins: $r1, $r3 248 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 253 254--- 255name: fn4 256alignment: 1 257tracksRegLiveness: true 258 259# This is the same as fn2, but compiled for ARM, which doesn't need IT 260# instructions, so if-conversion is profitable. 261 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 270 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, $r3 278 279 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 280 Bcc %bb.2, 11, killed $cpsr 281 282 bb.1.if.then: 283 successors: %bb.3(0x80000000) 284 liveins: $r0, $r3 285 286 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg 287 renamable $r0 = LDRi12 killed renamable $r0, 0, 14, $noreg 288 B %bb.3 289 290 bb.2.if.else: 291 successors: %bb.3(0x80000000) 292 liveins: $r1, $r3 293 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 297 298 bb.3.if.end: 299 liveins: $r0, $r3 300 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 304 305--- 306name: fn5 307alignment: 1 308tracksRegLiveness: true 309 310# Here, the compare and conditional branch can be turned into a CBZ, so we 311# don't want to if-convert. 312 313# CHECK-LABEL: name: fn5 314# CHECK: t2CMPri 315# CHECK: t2Bcc 316 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, $r2 324 325 t2CMPri killed renamable $r2, 0, 14, $noreg, implicit-def $cpsr 326 t2Bcc %bb.2, 1, killed $cpsr 327 328 bb.1.if.then: 329 liveins: $r0 330 331 renamable $r0 = t2LDRi12 killed renamable $r0, 0, 14, $noreg 332 tBX_RET 14, $noreg, implicit $r0 333 334 bb.2.if.else: 335 liveins: $r1 336 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 341 342--- 343name: fn6 344alignment: 1 345tracksRegLiveness: true 346 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. 349 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 358 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, $r3 366 367 t2CMPri killed renamable $r2, 4, 14, $noreg, implicit-def $cpsr 368 t2Bcc %bb.2, 1, killed $cpsr 369 370 bb.1.if.then: 371 successors: %bb.3(0x30000000), %bb.4(0x50000000) 372 liveins: $r0, $r1, $r3 373 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 380 381 bb.2.if.else: 382 successors: %bb.3(0x30000000), %bb.4(0x50000000) 383 liveins: $r0, $r1, $r3 384 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 389 390 bb.3.if2.then: 391 liveins: $r0, $r1, $r3 392 393 t2STRi12 killed renamable $r1, killed renamable $r3, 0, 14, $noreg 394 tBX_RET 14, $noreg, implicit $r0 395 396 bb.4.if2.else: 397 liveins: $r0 398 399 tBX_RET 14, $noreg, implicit $r0 400 401--- 402name: fn7 403alignment: 1 404tracksRegLiveness: true 405 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. 410 411# CHECK-LABEL: name: fn7 412# CHECK: CMPri 413# CHECK-NEXT: Bcc 414 415body: | 416 bb.0.entry: 417 successors: %bb.1(0x40000000), %bb.2(0x40000000) 418 liveins: $r0, $r1, $r2, $r3 419 420 CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 421 Bcc %bb.2, 11, killed $cpsr 422 423 bb.1.if.then: 424 successors: %bb.3(0x80000000) 425 liveins: $r0, $r3 426 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 441 442 bb.2.if.else: 443 successors: %bb.3(0x80000000) 444 liveins: $r1, $r3 445 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 449 450 bb.3.if.end: 451 liveins: $r0, $r3 452 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 456 457--- 458name: fn8 459alignment: 1 460tracksRegLiveness: true 461 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. 465 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 474 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, $r3 482 483 t2CMPri killed renamable $r2, 5, 14, $noreg, implicit-def $cpsr 484 t2Bcc %bb.2, 11, killed $cpsr 485 486 bb.1.if.then: 487 successors: %bb.3(0x80000000) 488 liveins: $r0, $r3 489 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 493 494 bb.2.if.else: 495 successors: %bb.3(0x80000000) 496 liveins: $r0, $r3 497 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 502 503 bb.3.if.end: 504 liveins: $r0, $r3 505 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 509 510--- 511name: fn9 512alignment: 2 513tracksRegLiveness: true 514 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. 518 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 526 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, $r2 534 535 tCMPi8 renamable $r2, 42, 14, $noreg, implicit-def $cpsr 536 t2Bcc %bb.3, 1, killed $cpsr 537 538 bb.1.if.then: 539 successors: %bb.5(0x7fffffff) 540 liveins: $r0, $r2 541 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 545 546 bb.3.if.else: 547 successors: %bb.5(0x7fffffff) 548 liveins: $r1, $r2 549 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 (address-taken): 557 liveins: $r0 558 559 renamable $r0, dead $cpsr = nsw tADDi8 killed renamable $r0, 5, 14, $noreg 560 tBX_RET 14, $noreg, implicit $r0 561... 562