blob: d2673c36f0f4ccb1922c127cc767c22f0428e6dd [file] [log] [blame]
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=thumbv7-apple-ios -run-pass=if-converter %s -o - | FileCheck %s
# Testcase with unanalyzable branches (that may fallthrough) in the BB
# following the diamond/triangle.
# Goal here is to showcase a problem seen in the IfConverter when
# AnalyzeBranch is indicating that the branches couldn't be analyzed. Problem
# was originally seen for an out-of-tree target, and here we use ARM and a
# MBB with two conditional jumps to make AnalyzeBranch return false.
#
# The problem was that if-converter when analyzing branches was using a
# variable named HasFallThrough, to remember that an MBB could fallthrough to
# the textual successor. When HasFallThrough is set we know that there are
# fallthrough exits, but the opposite is not guaranteed. If
# HasFallThrough==false there could still be fallthrough exists in situations
# when analyzeBranch found unanalyzable branches. There were however a couple
# of places in the code that checked !HasFallThrough assuming that it would
# imply that there was no fallthrough exit.
#
# As a consequence we could end up merging blocks at the end of a converted
# diamond/triangle and while doing that we messed up when fixing up the CFG
# related to fallthrough edges. For the test cases below we incorrectly ended
# up with a fallthrough from the MBBs with two Bcc instructions to the MBB
# with the STRH after if conversion.
#
---
name: avoidMergeBlockDiamond
body: |
; CHECK-LABEL: name: avoidMergeBlockDiamond
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $sp = tADDspi $sp, 2, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: $sp = tADDspi $sp, 1, 0 /* CC::eq */, $cpsr, implicit $sp
; CHECK-NEXT: $sp = tADDspi $sp, 3, 14 /* CC::al */, $noreg
; CHECK-NEXT: tBcc %bb.1, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: tBcc %bb.1, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: tBX_RET 14 /* CC::al */, $noreg
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: STRH $sp, $sp, $noreg, 0, 14 /* CC::al */, $noreg
; CHECK-NEXT: tB %bb.2, 14 /* CC::al */, $noreg
bb.0:
tBcc %bb.2, 1, $cpsr
bb.1:
$sp = tADDspi $sp, 1, 14, _
tB %bb.4, 14, $noreg
bb.2:
$sp = tADDspi $sp, 2, 14, _
tB %bb.4, 14, $noreg
bb.3:
STRH $sp, $sp, $noreg, 0, 14, $noreg
tB %bb.3, 14, $noreg
bb.4:
$sp = tADDspi $sp, 3, 14, _
tBcc %bb.5, 1, $cpsr
tBcc %bb.5, 1, $cpsr
bb.5:
successors:
tBX_RET 14, _
...
# Similar to the above, but with a triangle.
---
name: avoidMergeBlockTriangle
body: |
; CHECK-LABEL: name: avoidMergeBlockTriangle
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $sp = tADDspi $sp, 1, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: $sp = tADDspi $sp, 2, 14 /* CC::al */, $noreg
; CHECK-NEXT: tBcc %bb.1, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: tBcc %bb.1, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: tBX_RET 14 /* CC::al */, $noreg
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: STRH $sp, $sp, $noreg, 0, 14 /* CC::al */, $noreg
; CHECK-NEXT: tB %bb.2, 14 /* CC::al */, $noreg
bb.0:
tBcc %bb.1, 1, $cpsr
tB %bb.3, 14, $noreg
bb.1:
$sp = tADDspi $sp, 1, 14, _
tB %bb.3, 14, $noreg
bb.2:
STRH $sp, $sp, $noreg, 0, 14, $noreg
tB %bb.2, 14, $noreg
bb.3:
$sp = tADDspi $sp, 2, 14, _
tBcc %bb.4, 1, $cpsr
tBcc %bb.4, 1, $cpsr
bb.4:
successors:
tBX_RET 14, _
...