llvm.org GIT mirror llvm / 3f407d7
[UnrollRuntime] Fix domTree failures in multiexit unrolling Summary: This fixes the IDom for exit blocks and all blocks reachable from the exit blocks, when runtime unrolling under multiexit/exiting case. We initially had a restrictive check that the IDom is only updated when it is the header of the loop. However, we also need to update the IDom to the correct one when the IDom is any block within the original loop. See added test cases (which fail dom tree verification without the patch). Reviewers: reames, mzolotukhin, mkazantsev, hfinkel Reviewed by: brzycki, kuhar Subscribers: zzheng, dmgreen, llvm-commits Differential Revision: https://reviews.llvm.org/D56284 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350640 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 10 months ago
2 changed file(s) with 173 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
804804 // Now the loop blocks are cloned and the other exiting blocks from the
805805 // remainder are connected to the original Loop's exit blocks. The remaining
806806 // work is to update the phi nodes in the original loop, and take in the
807 // values from the cloned region. Also update the dominator info for
808 // OtherExits and their immediate successors, since we have new edges into
809 // OtherExits.
810 SmallPtrSet ImmediateSuccessorsOfExitBlocks;
807 // values from the cloned region.
811808 for (auto *BB : OtherExits) {
812809 for (auto &II : *BB) {
813810
842839 "Breaks the definition of dedicated exits!");
843840 }
844841 #endif
845 // Update the dominator info because the immediate dominator is no longer the
846 // header of the original Loop. BB has edges both from L and remainder code.
847 // Since the preheader determines which loop is run (L or directly jump to
848 // the remainder code), we set the immediate dominator as the preheader.
849 if (DT) {
850 DT->changeImmediateDominator(BB, PreHeader);
851 // Also update the IDom for immediate successors of BB. If the current
852 // IDom is the header, update the IDom to be the preheader because that is
853 // the nearest common dominator of all predecessors of SuccBB. We need to
854 // check for IDom being the header because successors of exit blocks can
855 // have edges from outside the loop, and we should not incorrectly update
856 // the IDom in that case.
857 for (BasicBlock *SuccBB: successors(BB))
858 if (ImmediateSuccessorsOfExitBlocks.insert(SuccBB).second) {
859 if (DT->getNode(SuccBB)->getIDom()->getBlock() == Header) {
860 assert(!SuccBB->getSinglePredecessor() &&
861 "BB should be the IDom then!");
862 DT->changeImmediateDominator(SuccBB, PreHeader);
863 }
864 }
842 }
843
844 // Update the immediate dominator of the exit blocks and blocks that are
845 // reachable from the exit blocks. This is needed because we now have paths
846 // from both the original loop and the remainder code reaching the exit
847 // blocks. While the IDom of these exit blocks were from the original loop,
848 // now the IDom is the preheader (which decides whether the original loop or
849 // remainder code should run).
850 if (DT && !L->getExitingBlock()) {
851 SmallVector ChildrenToUpdate;
852 // NB! We have to examine the dom children of all loop blocks, not just
853 // those which are the IDom of the exit blocks. This is because blocks
854 // reachable from the exit blocks can have their IDom as the nearest common
855 // dominator of the exit blocks.
856 for (auto *BB : L->blocks()) {
857 auto *DomNodeBB = DT->getNode(BB);
858 for (auto *DomChild : DomNodeBB->getChildren()) {
859 auto *DomChildBB = DomChild->getBlock();
860 if (!L->contains(LI->getLoopFor(DomChildBB)))
861 ChildrenToUpdate.push_back(DomChildBB);
862 }
865863 }
864 for (auto *BB : ChildrenToUpdate)
865 DT->changeImmediateDominator(BB, PreHeader);
866866 }
867867
868868 // Loop structure should be the following:
123123 exitsucc: ; preds = %headerexit
124124 ret i64 96
125125 }
126
127 ; exit block (%default) has an exiting block and another exit block as predecessors.
128 define void @test4(i16 %c3) {
129 ; CHECK-LABEL: test4
130
131 ; CHECK-LABEL: exiting.prol:
132 ; CHECK-NEXT: switch i16 %c3, label %default.loopexit.loopexit1 [
133
134 ; CHECK-LABEL: exiting:
135 ; CHECK-NEXT: switch i16 %c3, label %default.loopexit.loopexit [
136
137 ; CHECK-LABEL: default.loopexit.loopexit:
138 ; CHECK-NEXT: br label %default.loopexit
139
140 ; CHECK-LABEL: default.loopexit.loopexit1:
141 ; CHECK-NEXT: br label %default.loopexit
142
143 ; CHECK-LABEL: default.loopexit:
144 ; CHECK-NEXT: br label %default
145 preheader:
146 %c1 = zext i32 undef to i64
147 br label %header
148
149 header: ; preds = %latch, %preheader
150 %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %latch ]
151 br label %exiting
152
153 exiting: ; preds = %header
154 switch i16 %c3, label %default [
155 i16 45, label %otherexit
156 i16 95, label %latch
157 ]
158
159 latch: ; preds = %exiting
160 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
161 %c2 = icmp ult i64 %indvars.iv.next, %c1
162 br i1 %c2, label %header, label %latchexit
163
164 latchexit: ; preds = %latch
165 ret void
166
167 default: ; preds = %otherexit, %exiting
168 ret void
169
170 otherexit: ; preds = %exiting
171 br label %default
172 }
173
174 ; exit block (%exitB) has an exiting block and another exit block as predecessors.
175 ; exiting block comes from inner loop.
176 define void @test5() {
177 ; CHECK-LABEL: test5
178 ; CHECK-LABEL: bb1:
179 ; CHECK-NEXT: br i1 false, label %outerH.prol.preheader, label %outerH.prol.loopexit
180
181 ; CHECK-LABEL: outerH.prol.preheader:
182 ; CHECK-NEXT: br label %outerH.prol
183
184 ; CHECK-LABEL: outerH.prol:
185 ; CHECK-NEXT: %tmp4.prol = phi i32 [ %tmp6.prol, %outerLatch.prol ], [ undef, %outerH.prol.preheader ]
186 ; CHECK-NEXT: %prol.iter = phi i32 [ 0, %outerH.prol.preheader ], [ %prol.iter.sub, %outerLatch.prol ]
187 ; CHECK-NEXT: br label %innerH.prol
188 bb:
189 %tmp = icmp sgt i32 undef, 79
190 br i1 %tmp, label %outerLatchExit, label %bb1
191
192 bb1: ; preds = %bb
193 br label %outerH
194
195 outerH: ; preds = %outerLatch, %bb1
196 %tmp4 = phi i32 [ %tmp6, %outerLatch ], [ undef, %bb1 ]
197 br label %innerH
198
199 innerH: ; preds = %innerLatch, %outerH
200 br i1 undef, label %innerexiting, label %otherexitB
201
202 innerexiting: ; preds = %innerH
203 br i1 undef, label %innerLatch, label %exitB
204
205 innerLatch: ; preds = %innerexiting
206 %tmp13 = fcmp olt double undef, 2.000000e+00
207 br i1 %tmp13, label %innerH, label %outerLatch
208
209 outerLatch: ; preds = %innerLatch
210 %tmp6 = add i32 %tmp4, 1
211 %tmp7 = icmp sgt i32 %tmp6, 79
212 br i1 %tmp7, label %outerLatchExit, label %outerH
213
214 outerLatchExit: ; preds = %outerLatch, %bb
215 ret void
216
217 exitB: ; preds = %innerexiting, %otherexitB
218 ret void
219
220 otherexitB: ; preds = %innerH
221 br label %exitB
222
223 }
224
225 ; Blocks reachable from exits (not_zero44) have the IDom as the block within the loop (Header).
226 ; Update the IDom to the preheader.
227 define void @test6() {
228 ; CHECK-LABEL: test6
229 ; CHECK-LABEL: header.prol.preheader:
230 ; CHECK-NEXT: br label %header.prol
231
232 ; CHECK-LABEL: header.prol:
233 ; CHECK-NEXT: %indvars.iv.prol = phi i64 [ undef, %header.prol.preheader ], [ %indvars.iv.next.prol, %latch.prol ]
234 ; CHECK-NEXT: %prol.iter = phi i64 [ 1, %header.prol.preheader ], [ %prol.iter.sub, %latch.prol ]
235 ; CHECK-NEXT: br i1 false, label %latch.prol, label %otherexit.loopexit1
236
237 ; CHECK-LABEL: header.prol.loopexit.unr-lcssa:
238 ; CHECK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ]
239 ; CHECK-NEXT: br label %header.prol.loopexit
240
241 ; CHECK-LABEL: header.prol.loopexit:
242 ; CHECK-NEXT: %indvars.iv.unr = phi i64 [ undef, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ]
243 ; CHECK-NEXT: br i1 true, label %latchexit, label %entry.new
244
245 ; CHECK-LABEL: entry.new:
246 ; CHECK-NEXT: br label %header
247 entry:
248 br label %header
249
250 header: ; preds = %latch, %entry
251 %indvars.iv = phi i64 [ undef, %entry ], [ %indvars.iv.next, %latch ]
252 br i1 undef, label %latch, label %otherexit
253
254 latch: ; preds = %header
255 %indvars.iv.next = add nsw i64 %indvars.iv, 2
256 %0 = icmp slt i64 %indvars.iv.next, 616
257 br i1 %0, label %header, label %latchexit
258
259 latchexit: ; preds = %latch
260 br label %latchexitsucc
261
262 otherexit: ; preds = %header
263 br label %otherexitsucc
264
265 otherexitsucc: ; preds = %otherexit
266 br label %not_zero44
267
268 not_zero44: ; preds = %latchexitsucc, %otherexitsucc
269 unreachable
270
271 latchexitsucc: ; preds = %latchexit
272 br label %not_zero44
273 }
274