Index: lib/Transforms/Vectorize/VPlan.h =================================================================== --- lib/Transforms/Vectorize/VPlan.h +++ lib/Transforms/Vectorize/VPlan.h @@ -556,6 +556,10 @@ /// Unlink this recipe from its current VPBasicBlock and insert it into /// the VPBasicBlock that MovePos lives in, right after MovePos. void moveAfter(VPRecipeBase *MovePos); + + /// Insert an unlinked instruction into a basic block immediately before + /// the specified instruction. + void insertBefore(VPRecipeBase *InsertPos); }; /// This is a concrete Recipe that models a single VPlan-level instruction. Index: lib/Transforms/Vectorize/VPlan.cpp =================================================================== --- lib/Transforms/Vectorize/VPlan.cpp +++ lib/Transforms/Vectorize/VPlan.cpp @@ -226,6 +226,11 @@ getIterator()); } +void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) { + InsertPos->getParent()->getRecipeList().insert(InsertPos->getIterator(), + this); +} + void VPInstruction::generateInstruction(VPTransformState &State, unsigned Part) { IRBuilder<> &Builder = State.Builder; Index: unittests/Transforms/Vectorize/VPlanTest.cpp =================================================================== --- unittests/Transforms/Vectorize/VPlanTest.cpp +++ unittests/Transforms/Vectorize/VPlanTest.cpp @@ -51,6 +51,21 @@ CHECK_ITERATOR(VPBB2, I4, I3, I5); } +TEST(VPInstructionTest, insertBefore) { + VPInstruction *I1 = new VPInstruction(0, {}); + VPInstruction *I2 = new VPInstruction(1, {}); + VPInstruction *I3 = new VPInstruction(2, {}); + + VPBasicBlock VPBB1; + VPBB1.appendRecipe(I1); + + I2->insertBefore(I1); + CHECK_ITERATOR(VPBB1, I2, I1); + + I3->insertBefore(I2); + CHECK_ITERATOR(VPBB1, I3, I2, I1); +} + TEST(VPInstructionTest, sinkInstructions) { // Create some dummy instructions, we need those for the SinkAfter mapping. LLVMContext Context;