Skip to content

Commit

Permalink
[LoopSimplifyCFG] Update MemorySSA after r353911.
Browse files Browse the repository at this point in the history
Summary:
MemorySSA is not properly updated in LoopSimplifyCFG after recent changes. Use SplitBlock utility to resolve that and clear all updates once handleDeadExits is finished.
All updates that follow are removal of edges which are safe to handle via the removeEdge() API.
Also, deleting dead blocks is done correctly as is, i.e. delete from MemorySSA before updating the CFG and DT.

Reviewers: mkazantsev, rtereshin

Subscribers: sanjoy, jlebar, Prazek, george.burgess.iv, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D58524

llvm-svn: 354613
  • Loading branch information
alinas committed Feb 21, 2019
1 parent 73446cd commit d2d3244
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 37 deletions.
27 changes: 17 additions & 10 deletions llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
Expand Up @@ -352,14 +352,9 @@ class ConstantTerminatorFoldingImpl {
// Construct split preheader and the dummy switch to thread edges from it to
// dead exits.
BasicBlock *Preheader = L.getLoopPreheader();
BasicBlock *NewPreheader = Preheader->splitBasicBlock(
Preheader->getTerminator(),
Twine(Preheader->getName()).concat("-split"));
if (MSSAU)
MSSAU->removeEdge(Preheader, L.getHeader());
DTUpdates.push_back({DominatorTree::Delete, Preheader, L.getHeader()});
DTUpdates.push_back({DominatorTree::Insert, NewPreheader, L.getHeader()});
DTUpdates.push_back({DominatorTree::Insert, Preheader, NewPreheader});
BasicBlock *NewPreheader = llvm::SplitBlock(
Preheader, Preheader->getTerminator(), &DT, &LI, MSSAU);

IRBuilder<> Builder(Preheader->getTerminator());
SwitchInst *DummySwitch =
Builder.CreateSwitch(Builder.getInt32(0), NewPreheader);
Expand All @@ -384,8 +379,6 @@ class ConstantTerminatorFoldingImpl {

assert(L.getLoopPreheader() == NewPreheader && "Malformed CFG?");
if (Loop *OuterLoop = LI.getLoopFor(Preheader)) {
OuterLoop->addBasicBlockToLoop(NewPreheader, LI);

// When we break dead edges, the outer loop may become unreachable from
// the current loop. We need to fix loop info accordingly. For this, we
// find the most nested loop that still contains L and remove L from all
Expand Down Expand Up @@ -414,10 +407,21 @@ class ConstantTerminatorFoldingImpl {
assert(FixLCSSALoop && "Should be a loop!");
// We need all DT updates to be done before forming LCSSA.
DTU.applyUpdates(DTUpdates);
if (MSSAU)
MSSAU->applyUpdates(DTUpdates, DT);
DTUpdates.clear();
formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE);
}
}

if (MSSAU) {
// Clear all updates now. Facilitates deletes that follow.
DTU.applyUpdates(DTUpdates);
MSSAU->applyUpdates(DTUpdates, DT);
DTUpdates.clear();
if (VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
}
}

/// Delete loop blocks that have become unreachable after folding. Make all
Expand Down Expand Up @@ -589,6 +593,9 @@ class ConstantTerminatorFoldingImpl {
DTUpdates.clear();
}

if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();

#ifndef NDEBUG
// Make sure that we have preserved all data structures after the transform.
assert(DT.verify() && "DT broken after transform!");
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; REQUIRES: asserts
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"

Expand Down Expand Up @@ -239,7 +239,7 @@ define i32 @dead_exit_test_branch_loop(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[DEAD:%.*]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -288,7 +288,7 @@ define i32 @dead_exit_test_switch_loop(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[DEAD:%.*]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -554,7 +554,7 @@ define i32 @inf_loop_test_branch_loop(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[EXIT:%.*]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -594,7 +594,7 @@ define i32 @inf_loop_test_switch_loop(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[EXIT:%.*]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -1197,7 +1197,7 @@ define i32 @full_sub_loop_test_branch_loop_inverse_2(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -1258,7 +1258,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_2(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -1320,7 +1320,7 @@ define i32 @full_sub_loop_test_branch_loop_inverse_3(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -1380,7 +1380,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_3(i32 %end) {
; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: preheader-split:
; CHECK: preheader.split:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
Expand Down Expand Up @@ -1443,7 +1443,7 @@ define i32 @exit_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N)
; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: loop_2-split:
; CHECK: loop_2.split:
; CHECK-NEXT: br label [[LOOP_3:%.*]]
; CHECK: loop_3:
; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
Expand Down Expand Up @@ -1512,7 +1512,7 @@ define i32 @exit_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N)
; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: loop_2-split:
; CHECK: loop_2.split:
; CHECK-NEXT: br label [[LOOP_3:%.*]]
; CHECK: loop_3:
; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
Expand Down Expand Up @@ -2590,7 +2590,7 @@ define void @test_crash_01() {
; CHECK-NEXT: switch i32 0, label [[BB2_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[BB19:%.*]]
; CHECK-NEXT: ]
; CHECK: bb2-split:
; CHECK: bb2.split:
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb3:
; CHECK-NEXT: switch i32 undef, label [[BB16:%.*]] [
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll
Expand Up @@ -62,7 +62,7 @@ define void @test_01() {
; CHECK-NEXT: switch i32 0, label [[FOR_COND_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[FOR_COND_LOOPEXIT]]
; CHECK-NEXT: ]
; CHECK: for.cond-split:
; CHECK: for.cond.split:
; CHECK-NEXT: [[INC41_LCSSA3_LCSSA:%.*]] = phi i16 [ [[INC41_LCSSA3]], [[FOR_COND]] ]
; CHECK-NEXT: br label [[WHILE_COND:%.*]]
; CHECK: while.cond:
Expand Down Expand Up @@ -96,7 +96,7 @@ define void @bar() {
; CHECK-NEXT: switch i32 0, label [[BB_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[BB10:%.*]]
; CHECK-NEXT: ]
; CHECK: bb-split:
; CHECK: bb.split:
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ [[TMP7:%.*]], [[BB6:%.*]] ], [ undef, [[BB_SPLIT]] ]
Expand Down Expand Up @@ -161,7 +161,7 @@ define void @memlcssa() {
; CHECK-NEXT: switch i32 0, label [[ENTRY_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[DEFAULT_BB:%.*]]
; CHECK-NEXT: ]
; CHECK: entry-split:
; CHECK: entry.split:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: call void @foo()
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Transforms/LoopSimplifyCFG/live_block_marking.ll
@@ -1,16 +1,16 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; REQUIRES: asserts
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -indvars -loop-simplifycfg -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(indvars,simplify-cfg)' -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -indvars -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -indvars -loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(indvars,simplify-cfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -indvars -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s

define void @test(i1 %c) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 0, label [[ENTRY_SPLIT:%.*]] [
; CHECK-NEXT: i32 1, label [[DEAD_EXIT:%.*]]
; CHECK-NEXT: ]
; CHECK: entry-split:
; CHECK: entry.split:
; CHECK-NEXT: br label [[OUTER:%.*]]
; CHECK: outer:
; CHECK-NEXT: br i1 [[C:%.*]], label [[TO_FOLD:%.*]], label [[LATCH:%.*]]
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Transforms/LoopSimplifyCFG/mssa_update.ll
@@ -1,6 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; REQUIRES: asserts
; XFAIL: *
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/LoopSimplifyCFG/update_parents.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; REQUIRES: asserts
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s

target triple = "x86_64-unknown-linux-gnu"

Expand All @@ -20,7 +20,7 @@ define void @test() {
; CHECK-NEXT: i32 1, label [[BB1_LOOPEXIT:%.*]]
; CHECK-NEXT: i32 2, label [[BB2_LOOPEXIT:%.*]]
; CHECK-NEXT: ]
; CHECK: bb2-split:
; CHECK: bb2.split:
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb3:
; CHECK-NEXT: br label [[BB3]]
Expand Down Expand Up @@ -61,7 +61,7 @@ define void @test_many_subloops(i1 %c) {
; CHECK-NEXT: i32 1, label [[BB1_LOOPEXIT:%.*]]
; CHECK-NEXT: i32 2, label [[BB2_LOOPEXIT:%.*]]
; CHECK-NEXT: ]
; CHECK: bb2-split:
; CHECK: bb2.split:
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb3:
; CHECK-NEXT: br label [[BB3]]
Expand Down

0 comments on commit d2d3244

Please sign in to comment.