[llvm] r330582 - [LoopRotate] Fix incorrect SCEV invalidation in loop rotation

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 23 05:33:31 PDT 2018


Author: mkazantsev
Date: Mon Apr 23 05:33:31 2018
New Revision: 330582

URL: http://llvm.org/viewvc/llvm-project?rev=330582&view=rev
Log:
[LoopRotate] Fix incorrect SCEV invalidation in loop rotation

LoopRotate only invalidates innermost loops while the changes that it makes may
also affert any of this parents. With patch rL329047, SCEV becomes much smarter
about calculation of exit counts for outer loops, so we cannot assume that they are
not affected.

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

Added:
    llvm/trunk/test/Transforms/LoopRotate/pr37205.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp

Modified: llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp?rev=330582&r1=330581&r2=330582&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp Mon Apr 23 05:33:31 2018
@@ -259,9 +259,10 @@ bool LoopRotate::rotateLoop(Loop *L, boo
     return false;
 
   // Anything ScalarEvolution may know about this loop or the PHI nodes
-  // in its header will soon be invalidated.
+  // in its header will soon be invalidated, and it can also affect its parent
+  // loops as well.
   if (SE)
-    SE->forgetLoop(L);
+    SE->forgetTopmostLoop(L);
 
   DEBUG(dbgs() << "LoopRotation: rotating "; L->dump());
 
@@ -476,6 +477,12 @@ bool LoopRotate::rotateLoop(Loop *L, boo
 
   DEBUG(dbgs() << "LoopRotation: into "; L->dump());
 
+#ifndef NDEBUG
+  // Make sure that after all our transforms SE is correct.
+  if (SE)
+    SE->verify();
+#endif
+
   ++NumRotated;
   return true;
 }

Added: llvm/trunk/test/Transforms/LoopRotate/pr37205.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/pr37205.ll?rev=330582&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopRotate/pr37205.ll (added)
+++ llvm/trunk/test/Transforms/LoopRotate/pr37205.ll Mon Apr 23 05:33:31 2018
@@ -0,0 +1,116 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -indvars -verify -loop-rotate -loop-idiom < %s | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+
+; Verify that we invalidate SCEV properly.
+
+define void @test_01() {
+; CHECK-LABEL: @test_01(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LBL1:%.*]]
+; CHECK:       lbl1:
+; CHECK-NEXT:    br label [[FOR_COND:%.*]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    br i1 false, label [[FOR_BODY3_LR_PH:%.*]], label [[FOR_COND_FOR_END5_CRIT_EDGE:%.*]]
+; CHECK:       for.body3.lr.ph:
+; CHECK-NEXT:    br label [[FOR_BODY3:%.*]]
+; CHECK:       for.cond1:
+; CHECK-NEXT:    br i1 false, label [[FOR_BODY3]], label [[FOR_COND1_FOR_END5_CRIT_EDGE:%.*]]
+; CHECK:       for.body3:
+; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[FOR_COND1:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    br label [[LBL1]]
+; CHECK:       for.cond.for.end5_crit_edge:
+; CHECK-NEXT:    br label [[FOR_END5:%.*]]
+; CHECK:       for.cond1.for.end5_crit_edge:
+; CHECK-NEXT:    br label [[FOR_END5]]
+; CHECK:       for.end5:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %lbl1
+
+lbl1:                                             ; preds = %if.then, %entry
+  br label %for.cond
+
+for.cond:                                         ; preds = %lbl1
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %if.end, %for.cond
+  br i1 false, label %for.body3, label %for.end5
+
+for.body3:                                        ; preds = %for.cond1
+  br i1 false, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  br label %lbl1
+
+if.end:                                           ; preds = %for.body3
+  br label %for.cond1
+
+for.end5:                                         ; preds = %for.cond1
+  ret void
+}
+
+define void @test_02() {
+; CHECK-LABEL: @test_02(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LBL1:%.*]]
+; CHECK:       lbl1:
+; CHECK-NEXT:    br label [[FOR_COND:%.*]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END7:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    br i1 false, label [[FOR_BODY_LR_PH:%.*]], label [[IF_THEN_FOR_END6_CRIT_EDGE:%.*]]
+; CHECK:       for.body.lr.ph:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    br i1 false, label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then3:
+; CHECK-NEXT:    br label [[LBL1]]
+; CHECK:       if.end:
+; CHECK-NEXT:    br label [[FOR_COND4:%.*]]
+; CHECK:       for.cond4:
+; CHECK-NEXT:    br i1 false, label [[FOR_BODY]], label [[FOR_COND1_FOR_END6_CRIT_EDGE:%.*]]
+; CHECK:       if.then.for.end6_crit_edge:
+; CHECK-NEXT:    br label [[FOR_END6:%.*]]
+; CHECK:       for.cond1.for.end6_crit_edge:
+; CHECK-NEXT:    br label [[FOR_END6]]
+; CHECK:       for.end6:
+; CHECK-NEXT:    ret void
+; CHECK:       if.end7:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  br label %lbl1
+
+lbl1:                                             ; preds = %if.then3, %entry
+  br label %for.cond
+
+for.cond:                                         ; preds = %lbl1
+  br i1 false, label %if.then, label %if.end7
+
+if.then:                                          ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.cond4, %if.then
+  br i1 undef, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond1
+  br i1 false, label %if.then3, label %if.end
+
+if.then3:                                         ; preds = %for.body
+  br label %lbl1
+
+if.end:                                           ; preds = %for.body
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %if.end
+  br label %for.cond1
+
+for.end6:                                         ; preds = %for.cond1
+  ret void
+
+if.end7:                                          ; preds = %for.cond
+  unreachable
+}




More information about the llvm-commits mailing list