[VPlan] Assert can IV is only used by increments during epilogue vec.
authorFlorian Hahn <flo@fhahn.com>
Wed, 19 Jan 2022 10:09:46 +0000 (10:09 +0000)
committerFlorian Hahn <flo@fhahn.com>
Wed, 19 Jan 2022 10:10:05 +0000 (10:10 +0000)
After resetting the start value of the canonical IV, it might not be
canonical any more. Add an assertion to make sure it is only used by its
increment, to avoid potential mis-use. Suggested in D117140.

llvm/lib/Transforms/Vectorize/VPlan.cpp
llvm/lib/Transforms/Vectorize/VPlan.h

index 2598b5b..04c8e39 100644 (file)
@@ -871,6 +871,16 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
     VPValue *VPV = new VPValue(CanonicalIVStartValue);
     addExternalDef(VPV);
     auto *IV = getCanonicalIV();
+    assert(all_of(IV->users(),
+                  [](const VPUser *U) {
+                    auto *VPI = cast<VPInstruction>(U);
+                    return VPI->getOpcode() ==
+                               VPInstruction::CanonicalIVIncrement ||
+                           VPI->getOpcode() ==
+                               VPInstruction::CanonicalIVIncrementNUW;
+                  }) &&
+           "the canonical IV should only be used by its increments when "
+           "resetting the start value");
     IV->setOperand(0, VPV);
   }
 }
index 585fe75..c7946b6 100644 (file)
@@ -836,6 +836,16 @@ public:
     return R->getVPDefID() == VPRecipeBase::VPInstructionSC;
   }
 
+  /// Extra classof implementations to allow directly casting from VPUser ->
+  /// VPInstruction.
+  static inline bool classof(const VPUser *U) {
+    auto *R = dyn_cast<VPRecipeBase>(U);
+    return R && R->getVPDefID() == VPRecipeBase::VPInstructionSC;
+  }
+  static inline bool classof(const VPRecipeBase *R) {
+    return R->getVPDefID() == VPRecipeBase::VPInstructionSC;
+  }
+
   unsigned getOpcode() const { return Opcode; }
 
   /// Generate the instruction.