diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -673,8 +673,13 @@ WorkList.push_back(FOR); for (unsigned I = 0; I != WorkList.size(); ++I) { VPRecipeBase *Current = WorkList[I]; - assert(Current->getNumDefinedValues() == 1 && + assert(Current->getNumDefinedValues() <= 1 && "only recipes with a single defined value expected"); + // Skip instruction if it doesn't define a new value (meaning there are no + // more users). + if (Current->getNumDefinedValues() == 0) + continue; + for (VPUser *User : Current->getVPSingleValue()->users()) { if (auto *R = dyn_cast(User)) if (!TryToPushSinkCandidate(R)) diff --git a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-chains-vplan.ll b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-chains-vplan.ll --- a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-chains-vplan.ll +++ b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-chains-vplan.ll @@ -108,3 +108,56 @@ exit: ret void } + +define i32 @test_chained_first_order_recurrences_4() { +; CHECK-LABEL: 'test_chained_first_order_recurrences_4' +; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' { +; CHECK-NEXT: Live-in vp<%0> = vector-trip-count +; CHECK-NEXT: Live-in ir<4098> = original trip-count +; CHECK-EMPTY: +; CHECK-NEXT: vector.ph: +; CHECK-NEXT: Successor(s): vector loop +; CHECK-EMPTY: +; CHECK-NEXT: vector loop: { +; CHECK-NEXT: vector.body: +; CHECK-NEXT: EMIT vp<%1> = CANONICAL-INDUCTION +; CHECK-NEXT: FIRST-ORDER-RECURRENCE-PHI ir<%phi349> = phi ir<0>, ir<%mul368> +; CHECK-NEXT: FIRST-ORDER-RECURRENCE-PHI ir<%phi350> = phi ir<0>, ir<%trunc355> +; CHECK-NEXT: vp<%4> = SCALAR-STEPS vp<%1>, ir<1> +; CHECK-NEXT: CLONE ir<%getelementptr354> = getelementptr ir, vp<%4> +; CHECK-NEXT: WIDEN ir<%mul368> = mul ir<0>, ir<0> +; CHECK-NEXT: EMIT vp<%7> = first-order splice ir<%phi349> ir<%mul368> +; CHECK-NEXT: WIDEN-CAST ir<%trunc355> = trunc vp<%7> to i32 +; CHECK-NEXT: EMIT vp<%9> = first-order splice ir<%phi350> ir<%trunc355> +; CHECK-NEXT: WIDEN-CAST ir<%sext> = sext vp<%9> to i64 +; CHECK-NEXT: WIDEN store ir<%getelementptr354>, ir<%sext> +; CHECK-NEXT: EMIT vp<%11> = VF * UF +(nuw) vp<%1> +; CHECK-NEXT: EMIT branch-on-count vp<%11> vp<%0> +; CHECK-NEXT: No successors +; CHECK-NEXT: } +; CHECK-NEXT: Successor(s): middle.block +; CHECK-EMPTY: +; CHECK-NEXT: middle.block: +; CHECK-NEXT: No successors +; CHECK-NEXT: } + + +bb: + br label %bb347 + +bb271: ; preds = %bb347 + ret i32 0 + +bb347: ; preds = %bb347, %bb + %phi348 = phi i64 [ %add351, %bb347 ], [ 0, %bb ] + %phi349 = phi i64 [ %mul368, %bb347 ], [ 0, %bb ] + %phi350 = phi i32 [ %trunc355, %bb347 ], [ 0, %bb ] + %add351 = add i64 %phi348, 1 + %getelementptr354 = getelementptr i64, ptr addrspace(1) null, i64 %phi348 + %trunc355 = trunc i64 %phi349 to i32 + %sext = sext i32 %phi350 to i64 + store i64 %sext, ptr addrspace(1) %getelementptr354, align 8 + %mul368 = mul i64 0, 0 + %icmp369 = icmp ugt i64 %phi348, 4096 + br i1 %icmp369, label %bb271, label %bb347 +}