Skip to content

Commit 34a55c9

Browse files
authored
[BranchFolding] Fix assertion failure in HoistCommonCodeInSuccs (#141028)
Assertion failure introduced in #140063, which didn't account for TBB and FBB being the same block.
1 parent b63c1c4 commit 34a55c9

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

llvm/lib/CodeGen/BranchFolding.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,9 +2072,11 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
20722072
return false;
20732073

20742074
// Hoist the instructions from [T.begin, TIB) and then delete [F.begin, FIB).
2075-
// Merge the debug locations. FIXME: We should do something with the
2076-
// debug instructions too (from BOTH branches).
2077-
{
2075+
// If we're hoisting from a single block then just splice. Else step through
2076+
// and merge the debug locations.
2077+
if (TBB == FBB) {
2078+
MBB->splice(Loc, TBB, TBB->begin(), TIB);
2079+
} else {
20782080
// TIB and FIB point to the end of the regions to hoist/merge in TBB and
20792081
// FBB.
20802082
MachineBasicBlock::iterator FE = FIB;
@@ -2083,7 +2085,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
20832085
make_early_inc_range(make_range(TBB->begin(), TIB))) {
20842086
// Move debug instructions and pseudo probes without modifying them.
20852087
// FIXME: This is the wrong thing to do for debug locations, which
2086-
// should at least be killed.
2088+
// should at least be killed (and hoisted from BOTH blocks).
20872089
if (TI->isDebugOrPseudoInstr()) {
20882090
TI->moveBefore(&*Loc);
20892091
continue;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=armv7-apple-ios --run-pass=branch-folder %s -o - | FileCheck %s
3+
4+
## We hoist code from successor blocks, and in abnormal circumstances we can
5+
## have control flow that branches to the same block. Test we handle that
6+
## correctly.
7+
##
8+
## bb.5 (empty fall-through) folds into bb.6, making bb.2 branch to bb.6
9+
## unconditionally on a conditional branch (both edges go to bb.6).
10+
## Instructions are hosited from bb.2's successors, which is bb.6 twice,
11+
## along both edges.
12+
13+
...
14+
---
15+
name: f_1418_2054
16+
tracksRegLiveness: true
17+
noPhis: true
18+
isSSA: false
19+
noVRegs: true
20+
body: |
21+
; CHECK-LABEL: name: f_1418_2054
22+
; CHECK: bb.0:
23+
; CHECK-NEXT: successors: %bb.1(0x80000000)
24+
; CHECK-NEXT: {{ $}}
25+
; CHECK-NEXT: bb.1:
26+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
27+
; CHECK-NEXT: {{ $}}
28+
; CHECK-NEXT: $r0 = MOVr undef $r0, 14 /* CC::al */, $noreg, $noreg
29+
; CHECK-NEXT: Bcc %bb.1, 1 /* CC::ne */, undef $cpsr
30+
; CHECK-NEXT: {{ $}}
31+
; CHECK-NEXT: bb.2:
32+
; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000)
33+
; CHECK-NEXT: {{ $}}
34+
; CHECK-NEXT: $r0 = MOVr undef $r0, 14 /* CC::al */, $noreg, $noreg
35+
; CHECK-NEXT: Bcc %bb.4, 1 /* CC::ne */, undef $cpsr
36+
; CHECK-NEXT: {{ $}}
37+
; CHECK-NEXT: bb.3:
38+
; CHECK-NEXT: BX_RET 14 /* CC::al */, $noreg
39+
; CHECK-NEXT: {{ $}}
40+
; CHECK-NEXT: bb.4:
41+
; CHECK-NEXT: TRAP
42+
bb.0:
43+
successors: %bb.1
44+
45+
bb.1:
46+
successors: %bb.3, %bb.2
47+
48+
Bcc %bb.3, 1, undef $cpsr
49+
B %bb.2
50+
51+
bb.2:
52+
successors: %bb.5, %bb.6
53+
54+
Bcc %bb.5, 1, undef $cpsr
55+
B %bb.6
56+
57+
bb.3:
58+
successors: %bb.4
59+
60+
$r0 = MOVr undef $r0, 14, $noreg, $noreg
61+
62+
bb.4:
63+
successors: %bb.1
64+
65+
B %bb.1
66+
67+
bb.5:
68+
successors: %bb.6
69+
70+
bb.6:
71+
successors: %bb.8, %bb.7
72+
73+
$r0 = MOVr undef $r0, 14, $noreg, $noreg
74+
$r0 = MOVr undef $r0, 14, $noreg, $noreg
75+
76+
Bcc %bb.7, 1, undef $cpsr
77+
B %bb.8
78+
79+
bb.7:
80+
successors:
81+
82+
TRAP
83+
84+
bb.8:
85+
BX_RET 14, _
86+
...

0 commit comments

Comments
 (0)