summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2019-01-17 12:51:10 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2019-01-17 12:51:10 +0000
commit61a8d3fb3314fb9993a429ef0c50a7cfcd3f5ebf (patch)
treec1648d2f39956d58ae7316b2db95dc1489dad48e
parent8b134169f5dfb0e4d281eb522ced6b2879b76617 (diff)
[LoopSimplifyCFG] Form LCSSA when a parent loop becomes a sibling
During the transforms in LoopSimplifyCFG, when we remove a dead exiting edge, the parent loop may stop being reachable from the child loop, and therefore they become siblings. If the former child loop had uses of some values from its former parent loop, now such uses will require LCSSA Phis, even if they weren't needed before. So we must form LCSSA for all loops that stopped being ancestors of the current loop in this case. Differential Revision: https://reviews.llvm.org/D56144 Reviewed By: fedor.sergeev llvm-svn: 351434
-rw-r--r--llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp9
-rw-r--r--llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll21
2 files changed, 27 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index d51e6005d684..80690b8fadb2 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -379,6 +379,15 @@ private:
StillReachable->addChildLoop(&L);
else
LI.addTopLevelLoop(&L);
+
+ // Some values from loops in [OuterLoop, StillReachable) could be used
+ // in the current loop. Now it is not their child anymore, so such uses
+ // require LCSSA Phis.
+ Loop *FixLCSSALoop = OuterLoop;
+ while (FixLCSSALoop->getParentLoop() != StillReachable)
+ FixLCSSALoop = FixLCSSALoop->getParentLoop();
+ assert(FixLCSSALoop && "Should be a loop!");
+ formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE);
}
}
}
diff --git a/llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll b/llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll
index 032b12a755b7..e3a40a2d5300 100644
--- a/llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll
+++ b/llvm/test/Transforms/LoopSimplifyCFG/lcssa.ll
@@ -3,9 +3,6 @@
; 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
-; XFAIL: *
-; test_01 is currently failing because the loop is not in LCSSA form after the
-; transform.
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
@@ -56,6 +53,24 @@ if.end.8: ; preds = %if.end.7
}
define void @test_01() {
+; CHECK-LABEL: @test_01(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond.loopexit:
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[INC41_LCSSA3:%.*]] = phi i16 [ undef, [[FOR_COND_LOOPEXIT:%.*]] ], [ undef, [[ENTRY:%.*]] ]
+; CHECK-NEXT: switch i32 0, label [[FOR_COND_SPLIT:%.*]] [
+; CHECK-NEXT: i32 1, label [[FOR_COND_LOOPEXIT]]
+; CHECK-NEXT: ]
+; CHECK: for.cond-split:
+; CHECK-NEXT: [[INC41_LCSSA3_LCSSA:%.*]] = phi i16 [ [[INC41_LCSSA3]], [[FOR_COND]] ]
+; CHECK-NEXT: br label [[WHILE_COND:%.*]]
+; CHECK: while.cond:
+; CHECK-NEXT: [[INC41:%.*]] = phi i16 [ [[INC4:%.*]], [[WHILE_COND]] ], [ [[INC41_LCSSA3_LCSSA]], [[FOR_COND_SPLIT]] ]
+; CHECK-NEXT: [[INC4]] = add nsw i16 [[INC41]], 1
+; CHECK-NEXT: br label [[WHILE_COND]]
+;
entry:
br label %for.cond