https://bugs.llvm.org/show_bug.cgi?id=45958
Let's see simple IR snippet after loop vectorization with VPlanNatviePath.
vector.body: br label %for.body10.preheader67 for.body10.preheader67: ; preds = %for.cond.cleanup972, %vector.body %vec.phi = phi <4 x i64> [ zeroinitializer, %for.cond.cleanup972 ], [ %8, %vector.body ] for.cond.cleanup972: ; preds = %for.body1068 %8 = add nuw nsw <4 x i64> %vec.phi, <i64 1, i64 1, i64 1, i64 1> br i1 %10, label %for.cond.cleanup373, label %for.body10.preheader67
As you can see, %vec.phi has wrong incoming basic blocks.
The problem comes from "InnerLoopVectorizer::fixNonInductionPHIs()".
This function has assumption about the order of predecessors as below.
// The predecessor order is preserved and we can rely on mapping between // scalar and vector block predecessors. for (unsigned i = 0; i < NumIncomingValues; ++i) {
The original phi's order of predecessors can be different with the new phi's one.
This seems a bit more complicated than necessary I think
IIUC, if we have a map ScalarPred -> VectorPred (lets call it ScalarPred2VectorPred) we can get the blocks in the loop as follows:
Building ScalarPred2VectorPred should be straight-forward IIUC, as we should be able to rely on the predecessor order being the same between vector and scalar versions: just set ScalarPred2VectorPred[ScalarBBPredecessors[I]] = VectorBBPredecessors[I]; You also don't have to ScalarBBPredecessors/VectorBBPredecessors directly. You can just iterate over the predecessors for both and populate the map (you might want to use llvm::zip from STLExtras.h)