[PATCH] D79549: [LoopReroll] Fix rerolling loop with use outside the loop

KAWASHIMA Takahiro via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 22:08:49 PDT 2020


kawashima-fj created this revision.
kawashima-fj added a reviewer: efriedma.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Fixes PR41696

The loop-reroll pass generates an invalid IR (or its assertion
fails in debug build) if values of the base instruction and
other root instructions (terms used in the loop-reroll pass)
are used outside the loop block. See IRs written in PR41696
as examples.

The current implementation of the loop-reroll pass can reroll
only loops that don't have values that are used outside the
loop, except reduced values (the last values of reduction chains).
This is described in the comment of the `LoopReroll::reroll`
function.
https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp#L1600

This is checked in the `LoopReroll::DAGRootTracker::validate`
function.
https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp#L1393

However, the base instruction and other root instructions skip
this check in the validation loop.
https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp#L1229

Moving the check in front of the skip is the logically simplest
fix. However, inserting the check in an earlier stage is better
in terms of compilation time of unrerollable loops. This fix
inserts the check for the base instruction into the function
to validate possible base/root instructions. Check for other
root instructions is unnecessary because they don't match any
base instructions if they have uses outside the loop.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79549

Files:
  llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
  llvm/test/Transforms/LoopReroll/external_use.ll


Index: llvm/test/Transforms/LoopReroll/external_use.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/LoopReroll/external_use.ll
@@ -0,0 +1,60 @@
+; RUN: opt < %s -loop-reroll -S | FileCheck %s
+
+; Check whether rerolling is rejected if values of the base and root
+; instruction are used outside the loop block.
+
+; Only the base/root instructions except a loop increment instruction
+define void @test1() {
+entry:
+  br label %loop1
+
+loop1:
+;CHECK-LABEL: loop1:
+;CHECK-NEXT:   %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop1 ]
+;CHECK-NEXT:   %indvar.1 = add nsw i64 %indvar, 1
+
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop1 ]
+  %indvar.1 = add nsw i64 %indvar, 1
+  %indvar.next = add nsw i64 %indvar, 2
+  %cmp = icmp slt i64 %indvar.next, 200
+  br i1 %cmp, label %loop1, label %exit
+
+exit:
+  %var1 = phi i64 [ %indvar.1, %loop1 ]
+  %var2 = phi i64 [ %indvar, %loop1 ]
+  ret void
+}
+
+; Both the base/root instructions and reduction instructions
+define void @test2() {
+entry:
+  br label %loop2
+
+loop2:
+;CHECK-LABEL: loop2:
+;CHECK-NEXT:   %indvar = phi i32  [ 0, %entry ], [ %indvar.next, %loop2 ]
+;CHECK-NEXT:   %redvar = phi i32 [ 0, %entry ], [ %add.2, %loop2 ]
+;CHECK-NEXT:   %indvar.1 = add nuw nsw i32 %indvar, 1
+;CHECK-NEXT:   %indvar.2 = add nuw nsw i32 %indvar, 2
+
+  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %loop2 ]
+  %redvar = phi i32 [ 0, %entry ], [ %add.2, %loop2 ]
+  %indvar.1 = add nuw nsw i32 %indvar, 1
+  %indvar.2 = add nuw nsw i32 %indvar, 2
+  %mul.0 = mul nsw i32 %indvar, %indvar
+  %mul.1 = mul nsw i32 %indvar.1, %indvar.1
+  %mul.2 = mul nsw i32 %indvar.2, %indvar.2
+  %add.0 = add nsw i32 %redvar, %mul.0
+  %add.1 = add nsw i32 %add.0, %mul.1
+  %add.2 = add nsw i32 %add.1, %mul.2
+  %indvar.next = add nuw nsw i32 %indvar, 3
+  %cmp = icmp slt i32 %indvar.next, 300
+  br i1 %cmp, label %loop2, label %exit
+
+exit:
+  %a = phi i32 [ %indvar, %loop2 ]
+  %b = phi i32 [ %indvar.1, %loop2 ]
+  %c = phi i32 [ %indvar.2, %loop2 ]
+  %x = phi i32 [ %add.2, %loop2 ]
+  ret void
+}
Index: llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
+++ llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
@@ -879,6 +879,8 @@
 bool LoopReroll::DAGRootTracker::validateRootSet(DAGRootSet &DRS) {
   if (DRS.Roots.empty())
     return false;
+  if (hasUsesOutsideLoop(DRS.BaseInst, L))
+    return false;
 
   // Consider a DAGRootSet with N-1 roots (so N different values including
   //   BaseInst).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79549.262542.patch
Type: text/x-patch
Size: 2647 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200507/e6f436e1/attachment.bin>


More information about the llvm-commits mailing list