llvm.org GIT mirror llvm / 8cca882
[LoopDeletion] Handle users in unreachable block This is a fix for PR35884. When we want to delete dead loop we must clean uses in unreachable blocks otherwise we'll get an assert during deletion of instructions from the loop. Reviewers: anna, davide Reviewed By: anna Subscribers: llvm-commits, lebedev.ri Differential Revision: https://reviews.llvm.org/D41943 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322357 91177308-0d34-0410-b5e6-96231b3b80d8 Serguei Katkov 1 year, 8 months ago
2 changed file(s) with 50 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
13551355 DT->deleteEdge(Preheader, L->getHeader());
13561356 }
13571357
1358 // Given LCSSA form is satisfied, we should not have users of instructions
1359 // within the dead loop outside of the loop. However, LCSSA doesn't take
1360 // unreachable uses into account. We handle them here.
1361 // We could do it after drop all references (in this case all users in the
1362 // loop will be already eliminated and we have less work to do but according
1363 // to API doc of User::dropAllReferences only valid operation after dropping
1364 // references, is deletion. So let's substitute all usages of
1365 // instruction from the loop with undef value of corresponding type first.
1366 for (auto *Block : L->blocks())
1367 for (Instruction &I : *Block) {
1368 auto *Undef = UndefValue::get(I.getType());
1369 for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E;) {
1370 Use &U = *UI;
1371 ++UI;
1372 if (auto *Usr = dyn_cast(U.getUser()))
1373 if (L->contains(Usr->getParent()))
1374 continue;
1375 // If we have a DT then we can check that uses outside a loop only in
1376 // unreachable block.
1377 if (DT)
1378 assert(!DT->isReachableFromEntry(U) &&
1379 "Unexpected user in reachable block");
1380 U.set(Undef);
1381 }
1382 }
1383
13581384 // Remove the block from the reference counting scheme, so that we can
13591385 // delete it freely later.
13601386 for (auto *Block : L->blocks())
0 ; RUN: opt < %s -loop-deletion -S | FileCheck %s
1
2 ; Checking that possible users of instruction from the loop in
3 ; unreachable blocks are handled.
4
5 define i64 @foo() {
6 entry:
7 br label %invloop
8 ; CHECK-LABEL-NOT: invloop
9 invloop:
10 %indvar1 = phi i64 [ 3, %entry ], [ %indvar2, %invloop_iter ]
11 %check = icmp ult i64 %indvar1, 400
12 br i1 %check, label %invloop_iter, label %loopexit
13 invloop_iter:
14 %indvar2 = add i64 %indvar1, 1
15 %baddef = add i64 0, 0
16 br label %invloop
17 loopexit:
18 ret i64 0
19 deadcode:
20 ; CHECK-LABEL: deadcode
21 ; CHECK: ret i64 undef
22 ret i64 %baddef
23 }