[PATCH] D39234: [IRCE] Fix SCEVExpander's usage in IRCE

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 24 05:07:24 PDT 2017


mkazantsev created this revision.

When expanding exit conditions for pre- and postloops, we may end up expanding a
recurrency from the loop to in its loop's preheader. This produces incorrect IR.

This patch ensures that IRCE uses SCEVExpander correctly and only expands code which
is safe to expand in this particular location.


https://reviews.llvm.org/D39234

Files:
  lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
  test/Transforms/IRCE/bad_expander.ll


Index: test/Transforms/IRCE/bad_expander.ll
===================================================================
--- /dev/null
+++ test/Transforms/IRCE/bad_expander.ll
@@ -0,0 +1,40 @@
+; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
+target triple = "x86_64-unknown-linux-gnu"
+
+; IRCE should fail here because the preheader's exiting value is a phi from the
+; loop, and this value cannot be expanded at loop's preheader.
+
+; Function Attrs: uwtable
+define void @test_01() {
+
+; CHECK-NOT:   irce: in function test_01: constrained Loop
+
+; CHECK-LABEL: test_01
+; CHECK-NOT:   preloop
+; CHECK-NOT:   postloop
+; CHECK-NOT:   br i1 false
+; CHECK-NOT:   br i1 true
+
+entry:
+  br label %loop
+
+exit:                                       ; preds = %guarded, %loop
+  ret void
+
+loop:                                      ; preds = %guarded, %entry
+  %indvars.iv = phi i64 [ 380, %entry ], [ %indvars.iv.next, %guarded ]
+  %tmp1 = phi i32 [ 3, %entry ], [ %tmp2, %guarded ]
+  %tmp2 = add nuw nsw i32 %tmp1, 1
+  %tmp3 = add nuw nsw i64 %indvars.iv, 1
+  %tmp4 = icmp slt i64 %tmp3, 5
+  br i1 %tmp4, label %guarded, label %exit
+
+guarded:                                          ; preds = %tmp0
+  %indvars.iv.next = add nsw i64 %indvars.iv, -1
+  %tmp5 = add nuw nsw i32 %tmp1, 8
+  %tmp6 = zext i32 %tmp5 to i64
+  %tmp7 = icmp eq i64 %indvars.iv.next, %tmp6
+  br i1 %tmp7, label %exit, label %loop
+}
Index: lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
===================================================================
--- lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -1481,6 +1481,14 @@
       ExitPreLoopAtSCEV = SE.getAddExpr(*SR.HighLimit, MinusOneS);
     }
 
+    if (!isSafeToExpandAt(ExitPreLoopAtSCEV, InsertPt, SE)) {
+      DEBUG(dbgs() << "irce: could not prove that it is save to expand the"
+                   << " preloop exit limit " << *ExitPreLoopAtSCEV
+                   << " can be safely expanded at bloc; "
+                   << InsertPt->getParent()->getName() << "\n");
+      return false;
+    }
+
     ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
     ExitPreLoopAt->setName("exit.preloop.at");
   }
@@ -1500,6 +1508,14 @@
       ExitMainLoopAtSCEV = SE.getAddExpr(*SR.LowLimit, MinusOneS);
     }
 
+    if (!isSafeToExpandAt(ExitMainLoopAtSCEV, InsertPt, SE)) {
+      DEBUG(dbgs() << "irce: could not prove that it is save to expand the"
+                   << " main loop exit limit " << *ExitMainLoopAtSCEV
+                   << " can be safely expanded at block "
+                   << InsertPt->getParent()->getName() << "\n");
+      return false;
+    }
+
     ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
     ExitMainLoopAt->setName("exit.mainloop.at");
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39234.120052.patch
Type: text/x-patch
Size: 2981 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171024/5770c20b/attachment.bin>


More information about the llvm-commits mailing list