Index: llvm/lib/Analysis/IVDescriptors.cpp =================================================================== --- llvm/lib/Analysis/IVDescriptors.cpp +++ llvm/lib/Analysis/IVDescriptors.cpp @@ -1025,6 +1025,18 @@ // Previous. Nothing left to do. if (DT->dominates(Previous, OtherPrev) || Previous == OtherPrev) return true; + + // If there are other instructions to be sunk after SinkCandidate, remove + // and re-insert SinkCandidate can break those instructions. Bail out for + // simplicity. + const auto SuccIt = find_if( + SinkAfter, + [SinkCandidate](const std::pair &P) { + return P.second == SinkCandidate; + }); + if (SuccIt != std::end(SinkAfter)) + return false; + // Otherwise, Previous comes after OtherPrev and SinkCandidate needs to be // re-sunk to Previous, instead of sinking to OtherPrev. Remove // SinkCandidate from SinkAfter to ensure it's insert position is updated. Index: llvm/test/Transforms/LoopVectorize/sinkafter.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/sinkafter.ll @@ -0,0 +1,36 @@ +; RUN: opt -loop-vectorize -S %s | FileCheck %s + +; Make sure LLVM doesn't generate wrong data in SinkAfter, and causes crash in +; loop vectorizer. + +; CHECK-LABEL: @foo +; CHECK: ret +define void @foo(i64 %count, double %d1, double %d2, ptr %p1, ptr %p2) { +Entry: + br label %Loop + +Loop: + %v792 = phi double [ %v806, %Loop ], [ %d1, %Entry ] + %v793 = phi double [ %v813, %Loop ], [ %d1, %Entry ] + %v794 = phi double [ %v793, %Loop ], [ %d2, %Entry ] + %v795 = phi i64 [ %v811, %Loop ], [ 1, %Entry ] + %v802 = fdiv double %v794, %v792 + %v803 = getelementptr inbounds [4 x double], ptr %p1, i64 %v795 + %v804 = fdiv double 1.000000e+00, %v792 + %v805 = getelementptr inbounds double, ptr %p2, i64 %v795 + %v806 = load double, ptr %v805, align 8 + %v807 = fdiv double 1.000000e+00, %v806 + %v808 = fadd double %v804, %v807 + %v809 = fmul double %v793, %v808 + %v810 = fsub double %v802, %v809 + %v811 = add nuw nsw i64 %v795, 1 + %v812 = getelementptr inbounds [4 x double], ptr %p1, i64 %v811, i64 2 + %v813 = load double, ptr %v812, align 8 + %v815 = fadd double %v813, %v810 + store double %v815, ptr %v803, align 8 + %v818 = icmp eq i64 %v811, %count + br i1 %v818, label %End, label %Loop + +End: + ret void +}