Skip to content

Commit df9d60a

Browse files
author
Chen Zheng
committed
[PowerPC] handle more than two predecessors loop header in ctrloop pass
After ISEL, the "valid" loop header which has two predecessors (one is preheader and the other one is latch) may be transformed to have more than two predecessors by some optimizations, like tail duplicator, if the old header's successor(will be changed to new header) is a sub loop. The predecessors of the new loop header are preheader, loop latch and the loop latch(es) of the sub loop(old header's successor). Before the patch, ctrloop pass assumes two predecessors for candidate loop header. This patch fixes this case. Reviewed By: lkail Differential Revision: https://reviews.llvm.org/D135846
1 parent 13d6a57 commit df9d60a

File tree

2 files changed

+243
-4
lines changed

2 files changed

+243
-4
lines changed

llvm/lib/Target/PowerPC/PPCCTRLoops.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,38 @@ void PPCCTRLoops::expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
267267

268268
// Add other inputs for the PHI node.
269269
if (ML->isLoopLatch(Exiting)) {
270-
// There must be only two predecessors for the loop header, one is the
271-
// Preheader and the other one is loop latch Exiting. In hardware loop
270+
// Normally there must be only two predecessors for the loop header, one is
271+
// the Preheader and the other one is loop latch Exiting. In hardware loop
272272
// insertion pass, the block containing DecreaseCTRloop must dominate all
273273
// loop latches. So there must be only one latch.
274-
assert(ML->getHeader()->pred_size() == 2 &&
275-
"Loop header predecessor is not right!");
274+
// But there are some optimizations after ISEL, like tail duplicator, may
275+
// merge the two-predecessor loop header with its successor. If the
276+
// successor happens to be a header of nest loop, then we will have a header
277+
// which has more than 2 predecessors.
278+
assert(std::find(ML->getHeader()->predecessors().begin(),
279+
ML->getHeader()->predecessors().end(),
280+
Exiting) != ML->getHeader()->predecessors().end() &&
281+
"Loop latch is not loop header predecessor!");
282+
assert(std::find(ML->getHeader()->predecessors().begin(),
283+
ML->getHeader()->predecessors().end(),
284+
Preheader) != ML->getHeader()->predecessors().end() &&
285+
"Loop preheader is not loop header predecessor!");
286+
276287
PHIMIB.addReg(ADDIDef).addMBB(Exiting);
288+
289+
if (ML->getHeader()->pred_size() > 2) {
290+
Register HeaderIncoming = MRI->createVirtualRegister(
291+
Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
292+
: &PPC::GPRC_and_GPRC_NOR0RegClass);
293+
BuildMI(*ML->getHeader(), ML->getHeader()->getFirstNonPHI(), DebugLoc(),
294+
TII->get(TargetOpcode::COPY), HeaderIncoming)
295+
.addReg(PHIDef);
296+
297+
for (MachineBasicBlock *P : ML->getHeader()->predecessors()) {
298+
if (P != Preheader && P != Exiting)
299+
PHIMIB.addReg(HeaderIncoming).addMBB(P);
300+
}
301+
}
277302
} else {
278303
// If the block containing DecreaseCTRloop is not a loop latch, we can use
279304
// ADDIDef as the value for all other blocks for the PHI. In hardware loop
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -ppc-asm-full-reg-names -mtriple=powerpc-ibm-aix-xcoff \
3+
# RUN: -stop-after=ppc-ctrloops %s -o - -verify-machineinstrs | FileCheck %s
4+
5+
---
6+
name: three-preds-single-block-loop
7+
8+
tracksRegLiveness: true
9+
body: |
10+
; CHECK-LABEL: name: three-preds-single-block-loop
11+
; CHECK: bb.0.entry:
12+
; CHECK-NEXT: successors: %bb.1(0x80000000)
13+
; CHECK-NEXT: {{ $}}
14+
; CHECK-NEXT: [[LI:%[0-9]+]]:gprc = LI 2048
15+
; CHECK-NEXT: [[LI1:%[0-9]+]]:gprc = LI 9
16+
; CHECK-NEXT: [[CMPLWI:%[0-9]+]]:crrc = CMPLWI [[LI1]], 0
17+
; CHECK-NEXT: [[COPY:%[0-9]+]]:crbitrc = COPY [[CMPLWI]].sub_eq
18+
; CHECK-NEXT: {{ $}}
19+
; CHECK-NEXT: bb.1:
20+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
21+
; CHECK-NEXT: {{ $}}
22+
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprc_and_gprc_nor0 = PHI [[LI]], %bb.0, %7, %bb.2, %8, %bb.1
23+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprc_and_gprc_nor0 = COPY [[PHI]]
24+
; CHECK-NEXT: BC [[COPY]], %bb.1
25+
; CHECK-NEXT: B %bb.2
26+
; CHECK-NEXT: {{ $}}
27+
; CHECK-NEXT: bb.2:
28+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
29+
; CHECK-NEXT: {{ $}}
30+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
31+
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprc_and_gprc_nor0 = ADDI [[PHI]], -1
32+
; CHECK-NEXT: [[CMPLWI1:%[0-9]+]]:crrc = CMPLWI [[ADDI]], 0
33+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:crbitrc = COPY [[CMPLWI1]].sub_gt
34+
; CHECK-NEXT: BC [[COPY2]], %bb.1
35+
; CHECK-NEXT: B %bb.3
36+
; CHECK-NEXT: {{ $}}
37+
; CHECK-NEXT: bb.3:
38+
; CHECK-NEXT: BLR implicit $lr, implicit $rm
39+
bb.0.entry:
40+
41+
%0:gprc = LI 2048
42+
%1:gprc_and_gprc_nor0 = LI 10
43+
MTCTRloop killed %0:gprc, implicit-def dead $ctr
44+
45+
bb.1:
46+
%2:gprc = ADDI %1:gprc_and_gprc_nor0, -1
47+
%3:crrc = CMPLWI %2:gprc, 0
48+
%4:crbitrc = COPY %3.sub_eq
49+
BC killed %4:crbitrc, %bb.1
50+
B %bb.2
51+
52+
bb.2:
53+
54+
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
55+
%5:crbitrc = DecreaseCTRloop 1, implicit-def dead $ctr, implicit $ctr
56+
BC killed %5:crbitrc, %bb.1
57+
B %bb.3
58+
59+
bb.3:
60+
61+
BLR implicit $lr, implicit $rm
62+
...
63+
---
64+
name: three-preds-mult-blocks-loop
65+
66+
tracksRegLiveness: true
67+
body: |
68+
; CHECK-LABEL: name: three-preds-mult-blocks-loop
69+
; CHECK: bb.0.entry:
70+
; CHECK-NEXT: successors: %bb.1(0x80000000)
71+
; CHECK-NEXT: {{ $}}
72+
; CHECK-NEXT: [[LI:%[0-9]+]]:gprc = LI 2048
73+
; CHECK-NEXT: [[LI1:%[0-9]+]]:gprc = LI 9
74+
; CHECK-NEXT: [[CMPLWI:%[0-9]+]]:crrc = CMPLWI [[LI1]], 0
75+
; CHECK-NEXT: [[COPY:%[0-9]+]]:crbitrc = COPY [[CMPLWI]].sub_eq
76+
; CHECK-NEXT: {{ $}}
77+
; CHECK-NEXT: bb.1:
78+
; CHECK-NEXT: successors: %bb.2(0x80000000)
79+
; CHECK-NEXT: {{ $}}
80+
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprc_and_gprc_nor0 = PHI [[LI]], %bb.0, %7, %bb.3, %8, %bb.2
81+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprc_and_gprc_nor0 = COPY [[PHI]]
82+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
83+
; CHECK-NEXT: B %bb.2
84+
; CHECK-NEXT: {{ $}}
85+
; CHECK-NEXT: bb.2:
86+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
87+
; CHECK-NEXT: {{ $}}
88+
; CHECK-NEXT: BC [[COPY]], %bb.1
89+
; CHECK-NEXT: B %bb.3
90+
; CHECK-NEXT: {{ $}}
91+
; CHECK-NEXT: bb.3:
92+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
93+
; CHECK-NEXT: {{ $}}
94+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
95+
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprc_and_gprc_nor0 = ADDI [[PHI]], -1
96+
; CHECK-NEXT: [[CMPLWI1:%[0-9]+]]:crrc = CMPLWI [[ADDI]], 0
97+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:crbitrc = COPY [[CMPLWI1]].sub_gt
98+
; CHECK-NEXT: BC [[COPY2]], %bb.1
99+
; CHECK-NEXT: B %bb.4
100+
; CHECK-NEXT: {{ $}}
101+
; CHECK-NEXT: bb.4:
102+
; CHECK-NEXT: BLR implicit $lr, implicit $rm
103+
bb.0.entry:
104+
105+
%0:gprc = LI 2048
106+
%1:gprc_and_gprc_nor0 = LI 10
107+
MTCTRloop killed %0:gprc, implicit-def dead $ctr
108+
109+
bb.1:
110+
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
111+
B %bb.2
112+
113+
bb.2:
114+
%2:gprc = ADDI %1:gprc_and_gprc_nor0, -1
115+
%3:crrc = CMPLWI %2:gprc, 0
116+
%4:crbitrc = COPY %3.sub_eq
117+
BC killed %4:crbitrc, %bb.1
118+
B %bb.3
119+
120+
bb.3:
121+
122+
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
123+
%5:crbitrc = DecreaseCTRloop 1, implicit-def dead $ctr, implicit $ctr
124+
BC killed %5:crbitrc, %bb.1
125+
B %bb.4
126+
127+
bb.4:
128+
129+
BLR implicit $lr, implicit $rm
130+
...
131+
---
132+
name: more-than-three-preds
133+
134+
tracksRegLiveness: true
135+
body: |
136+
; CHECK-LABEL: name: more-than-three-preds
137+
; CHECK: bb.0.entry:
138+
; CHECK-NEXT: successors: %bb.1(0x80000000)
139+
; CHECK-NEXT: {{ $}}
140+
; CHECK-NEXT: [[LI:%[0-9]+]]:gprc = LI 2048
141+
; CHECK-NEXT: [[LI1:%[0-9]+]]:gprc = LI 9
142+
; CHECK-NEXT: [[CMPLWI:%[0-9]+]]:crrc = CMPLWI [[LI1]], 0
143+
; CHECK-NEXT: [[COPY:%[0-9]+]]:crbitrc = COPY [[CMPLWI]].sub_eq
144+
; CHECK-NEXT: [[LI2:%[0-9]+]]:gprc = LI 8
145+
; CHECK-NEXT: [[CMPLWI1:%[0-9]+]]:crrc = CMPLWI [[LI2]], 0
146+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:crbitrc = COPY [[CMPLWI1]].sub_gt
147+
; CHECK-NEXT: {{ $}}
148+
; CHECK-NEXT: bb.1:
149+
; CHECK-NEXT: successors: %bb.2(0x80000000)
150+
; CHECK-NEXT: {{ $}}
151+
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprc_and_gprc_nor0 = PHI [[LI]], %bb.0, %10, %bb.4, %11, %bb.2, %11, %bb.3
152+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprc_and_gprc_nor0 = COPY [[PHI]]
153+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
154+
; CHECK-NEXT: B %bb.2
155+
; CHECK-NEXT: {{ $}}
156+
; CHECK-NEXT: bb.2:
157+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
158+
; CHECK-NEXT: {{ $}}
159+
; CHECK-NEXT: BC [[COPY]], %bb.1
160+
; CHECK-NEXT: B %bb.3
161+
; CHECK-NEXT: {{ $}}
162+
; CHECK-NEXT: bb.3:
163+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
164+
; CHECK-NEXT: {{ $}}
165+
; CHECK-NEXT: BC [[COPY1]], %bb.1
166+
; CHECK-NEXT: B %bb.4
167+
; CHECK-NEXT: {{ $}}
168+
; CHECK-NEXT: bb.4:
169+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.5(0x40000000)
170+
; CHECK-NEXT: {{ $}}
171+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
172+
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gprc_and_gprc_nor0 = ADDI [[PHI]], -1
173+
; CHECK-NEXT: [[CMPLWI2:%[0-9]+]]:crrc = CMPLWI [[ADDI]], 0
174+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:crbitrc = COPY [[CMPLWI2]].sub_gt
175+
; CHECK-NEXT: BC [[COPY3]], %bb.1
176+
; CHECK-NEXT: B %bb.5
177+
; CHECK-NEXT: {{ $}}
178+
; CHECK-NEXT: bb.5:
179+
; CHECK-NEXT: BLR implicit $lr, implicit $rm
180+
bb.0.entry:
181+
182+
%0:gprc = LI 2048
183+
%1:gprc_and_gprc_nor0 = LI 10
184+
MTCTRloop killed %0:gprc, implicit-def dead $ctr
185+
186+
bb.1:
187+
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
188+
B %bb.2
189+
190+
bb.2:
191+
%2:gprc = ADDI %1:gprc_and_gprc_nor0, -1
192+
%3:crrc = CMPLWI %2:gprc, 0
193+
%4:crbitrc = COPY %3.sub_eq
194+
BC killed %4:crbitrc, %bb.1
195+
B %bb.3
196+
197+
bb.3:
198+
%5:gprc = ADDI %1:gprc_and_gprc_nor0, -2
199+
%6:crrc = CMPLWI %5:gprc, 0
200+
%7:crbitrc = COPY %6.sub_gt
201+
BC killed %7:crbitrc, %bb.1
202+
B %bb.4
203+
204+
bb.4:
205+
206+
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $ctr
207+
%8:crbitrc = DecreaseCTRloop 1, implicit-def dead $ctr, implicit $ctr
208+
BC killed %8:crbitrc, %bb.1
209+
B %bb.5
210+
211+
bb.5:
212+
213+
BLR implicit $lr, implicit $rm
214+
...

0 commit comments

Comments
 (0)