[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 04:21:02 PDT 2019
ebevhan updated this revision to Diff 215561.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66334/new/
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,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; 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.
+
+ 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 {
+; CHECK-LABEL: @main(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP:%.*]] = load i16, i16* @a, align 1
+; CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @c, i32 0, i32 0), align 1
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 [[TMP]], [[TMP1]]
+; CHECK-NEXT: store i16 [[DIV]], i16* @b, align 1
+; CHECK-NEXT: [[TMP2:%.*]] = load i16, i16* @d, align 1
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: br label [[FOR_COND_CLEANUP3:%.*]]
+; CHECK: for.cond.cleanup:
+; CHECK-NEXT: [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2]], [[FOR_COND_CLEANUP3]] ]
+; CHECK-NEXT: store i16 [[DOTLCSSA10_LCSSA]], i16* @b, align 1
+; CHECK-NEXT: store i64 1, i64* @e, align 1
+; CHECK-NEXT: [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]])
+; CHECK-NEXT: ret i16 0
+; CHECK: for.cond.cleanup3:
+; CHECK-NEXT: br i1 false, label [[FOR_COND_CLEANUP3_1:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; CHECK: for.cond.cleanup3.1:
+; CHECK-NEXT: unreachable
+;
+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.215561.patch
Type: text/x-patch
Size: 3586 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190816/0caab2d4/attachment.bin>
More information about the llvm-commits
mailing list