]> granicus.if.org Git - llvm/commitdiff
[LoopSimplifyCFG] Form LCSSA when a parent loop becomes a sibling
authorMax Kazantsev <max.kazantsev@azul.com>
Thu, 17 Jan 2019 12:51:10 +0000 (12:51 +0000)
committerMax Kazantsev <max.kazantsev@azul.com>
Thu, 17 Jan 2019 12:51:10 +0000 (12:51 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351434 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LoopSimplifyCFG.cpp
test/Transforms/LoopSimplifyCFG/lcssa.ll

index d51e6005d684a67b58563e93704bccbde7b2646f..80690b8fadb251554aae7d620332f62522f769c5 100644 (file)
@@ -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);
       }
     }
   }
index 032b12a755b72a5f77345b3c98e0658642f00f81..e3a40a2d530075812e34cd2bb0f0be2cdee74452 100644 (file)
@@ -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