@@ -457,6 +457,9 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
457457 // / Returns the debug location of the recipe.
458458 DebugLoc getDebugLoc () const { return DL; }
459459
460+ // / Return true if the recipe is a scalar cast.
461+ bool isScalarCast () const ;
462+
460463protected:
461464 // / Compute the cost of this recipe either using a recipe's specialized
462465 // / implementation or using the legacy cost model and the underlying
@@ -531,7 +534,6 @@ class VPSingleDefRecipe : public VPRecipeBase, public VPValue {
531534 case VPRecipeBase::VPWidenIntOrFpInductionSC:
532535 case VPRecipeBase::VPWidenPointerInductionSC:
533536 case VPRecipeBase::VPReductionPHISC:
534- case VPRecipeBase::VPScalarCastSC:
535537 case VPRecipeBase::VPPartialReductionSC:
536538 return true ;
537539 case VPRecipeBase::VPBranchOnMaskSC:
@@ -1025,6 +1027,56 @@ class VPInstruction : public VPRecipeWithIRFlags,
10251027 StringRef getName () const { return Name; }
10261028};
10271029
1030+ // / A specialization of VPInstruction augmenting it with a dedicated result
1031+ // / type, to be used when the opcode and operands of the VPInstruction don't
1032+ // / directly determine the result type. Note that there is no separate VPDef ID
1033+ // / for VPInstructionWithType; it shares the same ID as VPInstruction and is
1034+ // / distinguished purely by the opcode.
1035+ class VPInstructionWithType : public VPInstruction {
1036+ // / Scalar result type produced by the recipe.
1037+ Type *ResultTy;
1038+
1039+ public:
1040+ VPInstructionWithType (unsigned Opcode, ArrayRef<VPValue *> Operands,
1041+ Type *ResultTy, DebugLoc DL, const Twine &Name = " " )
1042+ : VPInstruction(Opcode, Operands, DL, Name), ResultTy(ResultTy) {}
1043+
1044+ static inline bool classof (const VPRecipeBase *R) {
1045+ // VPInstructionWithType are VPInstructions with specific opcodes requiring
1046+ // type information.
1047+ return R->isScalarCast ();
1048+ }
1049+
1050+ static inline bool classof (const VPUser *R) {
1051+ return isa<VPInstructionWithType>(cast<VPRecipeBase>(R));
1052+ }
1053+
1054+ VPInstruction *clone () override {
1055+ SmallVector<VPValue *, 2 > Operands (operands ());
1056+ auto *New = new VPInstructionWithType (
1057+ getOpcode (), Operands, getResultType (), getDebugLoc (), getName ());
1058+ New->setUnderlyingValue (getUnderlyingValue ());
1059+ return New;
1060+ }
1061+
1062+ void execute (VPTransformState &State) override ;
1063+
1064+ // / Return the cost of this VPInstruction.
1065+ InstructionCost computeCost (ElementCount VF,
1066+ VPCostContext &Ctx) const override {
1067+ // TODO: Compute accurate cost after retiring the legacy cost model.
1068+ return 0 ;
1069+ }
1070+
1071+ Type *getResultType () const { return ResultTy; }
1072+
1073+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1074+ // / Print the recipe.
1075+ void print (raw_ostream &O, const Twine &Indent,
1076+ VPSlotTracker &SlotTracker) const override ;
1077+ #endif
1078+ };
1079+
10281080// / A recipe to wrap on original IR instruction not to be modified during
10291081// / execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
10301082// / Expect PHIs, VPIRInstructions cannot have any operands.
@@ -1211,54 +1263,6 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags {
12111263 Type *getResultType () const { return ResultTy; }
12121264};
12131265
1214- // / VPScalarCastRecipe is a recipe to create scalar cast instructions.
1215- class VPScalarCastRecipe : public VPSingleDefRecipe {
1216- Instruction::CastOps Opcode;
1217-
1218- Type *ResultTy;
1219-
1220- Value *generate (VPTransformState &State);
1221-
1222- public:
1223- VPScalarCastRecipe (Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy,
1224- DebugLoc DL)
1225- : VPSingleDefRecipe(VPDef::VPScalarCastSC, {Op}, DL), Opcode(Opcode),
1226- ResultTy (ResultTy) {}
1227-
1228- ~VPScalarCastRecipe () override = default ;
1229-
1230- VPScalarCastRecipe *clone () override {
1231- return new VPScalarCastRecipe (Opcode, getOperand (0 ), ResultTy,
1232- getDebugLoc ());
1233- }
1234-
1235- VP_CLASSOF_IMPL (VPDef::VPScalarCastSC)
1236-
1237- void execute (VPTransformState &State) override ;
1238-
1239- // / Return the cost of this VPScalarCastRecipe.
1240- InstructionCost computeCost (ElementCount VF,
1241- VPCostContext &Ctx) const override {
1242- // TODO: Compute accurate cost after retiring the legacy cost model.
1243- return 0 ;
1244- }
1245-
1246- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1247- void print (raw_ostream &O, const Twine &Indent,
1248- VPSlotTracker &SlotTracker) const override ;
1249- #endif
1250-
1251- // / Returns the result type of the cast.
1252- Type *getResultType () const { return ResultTy; }
1253-
1254- bool onlyFirstLaneUsed (const VPValue *Op) const override {
1255- // At the moment, only uniform codegen is implemented.
1256- assert (is_contained (operands (), Op) &&
1257- " Op must be an operand of the recipe" );
1258- return true ;
1259- }
1260- };
1261-
12621266// / A recipe for widening vector intrinsics.
12631267class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
12641268 // / ID of the vector intrinsic to widen.
0 commit comments