[PATCH] D66334: [LoopUnroll] Handle certain PHIs in full unrolling properly.

Bevin Hansson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 01:50:23 PDT 2019


ebevhan created this revision.
ebevhan added a reviewer: fhahn.
Herald added subscribers: llvm-commits, dmgreen, zzheng.
Herald added a project: LLVM.

When reconstructing the CFG of the loop after unrolling,
LoopUnroll could in some cases remove the phi operands of
loop-carried values instead of preserving them, resulting
in undef phi values after loop unrolling.

When doing this reconstruction, avoid removing incoming
phi values for phis in the successor blocks if the successor
is the block we are jumping to anyway.


Repository:
  rL LLVM

https://reviews.llvm.org/D66334

Files:
  lib/Transforms/Utils/LoopUnroll.cpp
  test/Transforms/LoopUnroll/full-unroll-miscompile.ll


Index: test/Transforms/LoopUnroll/full-unroll-miscompile.ll
===================================================================
--- /dev/null
+++ test/Transforms/LoopUnroll/full-unroll-miscompile.ll
@@ -0,0 +1,49 @@
+; RUN: opt < %s -S -loop-unroll | FileCheck %s
+
+; The phi which acts as input to func should not be undef. It should
+; have its loop-carried value (the load of d in the entry block)
+; replaced accordingly after unrolling the loop.
+
+; CHECK-LABEL: main
+; CHECK: %.lcssa10.lcssa = phi i16 [ %tmp2, %for.cond.cleanup3 ]
+
+ at a = dso_local global i16 0, align 1
+ at b = dso_local global i16 0, align 1
+ at c = dso_local global [2 x i16] [i16 1, i16 1], align 1
+ at d = dso_local global i16 0, align 1
+ at e = dso_local global i64 0, align 1
+
+; Function Attrs: minsize nounwind optsize
+define dso_local i16 @main() #0 {
+entry:
+  %tmp = load i16, i16* @a, align 1
+  %tmp1 = load i16, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @c, i32 0, i32 0), align 1
+  %div = sdiv i16 %tmp, %tmp1
+  store i16 %div, i16* @b, align 1
+  %tmp2 = load i16, i16* @d, align 1
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond.cleanup3, %entry
+  %.lcssa10 = phi i16 [ %div, %entry ], [ %.lcssa, %for.cond.cleanup3 ]
+  %i.0 = phi i64 [ 37, %entry ], [ %inc9, %for.cond.cleanup3 ]
+  %cmp = icmp ult i64 %i.0, 38
+  br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ]
+  store i16 %.lcssa10.lcssa, i16* @b, align 1
+  store i64 1, i64* @e, align 1
+  %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa)
+  ret i16 0
+
+for.cond.cleanup3:                                ; preds = %for.cond
+  %.lcssa = phi i16 [ %tmp2, %for.cond ]
+  %inc9 = add i64 %i.0, 1
+  br label %for.cond
+}
+
+; Function Attrs: nounwind
+declare i16 @func(i16) #1
+
+attributes #0 = { minsize nounwind optsize }
+attributes #1 = { nounwind }
Index: lib/Transforms/Utils/LoopUnroll.cpp
===================================================================
--- lib/Transforms/Utils/LoopUnroll.cpp
+++ lib/Transforms/Utils/LoopUnroll.cpp
@@ -723,7 +723,7 @@
       if (Dest != LoopExit) {
         BasicBlock *BB = Src;
         for (BasicBlock *Succ : successors(BB)) {
-          if (Succ == CurrentHeader)
+          if (Succ == CurrentHeader || Succ == Dest)
             continue;
           for (PHINode &Phi : Succ->phis())
             Phi.removeIncomingValue(BB, false);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66334.215540.patch
Type: text/x-patch
Size: 2536 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190816/4f0d993c/attachment.bin>


More information about the llvm-commits mailing list