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); 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 ] + +@a = dso_local global i16 0, align 1 +@b = dso_local global i16 0, align 1 +@c = dso_local global [2 x i16] [i16 1, i16 1], align 1 +@d = dso_local global i16 0, align 1 +@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 }