@@ -994,24 +994,39 @@ void VPWidenIntrinsicRecipe::execute(VPTransformState &State) {
994994 Args.push_back (Arg);
995995 }
996996
997- // Use vector version of the intrinsic.
998- Module *M = State.Builder .GetInsertBlock ()->getModule ();
999- Function *VectorF =
1000- Intrinsic::getOrInsertDeclaration (M, VectorIntrinsicID, TysForDecl);
1001- assert (VectorF && " Can't retrieve vector intrinsic." );
1002-
1003- auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
1004- SmallVector<OperandBundleDef, 1 > OpBundles;
1005- if (CI)
1006- CI->getOperandBundlesAsDefs (OpBundles);
997+ if (VPIntrinsic::isVPIntrinsic (VectorIntrinsicID)) {
998+ // Use vector version of the vector predicate Intrinsic
999+ IRBuilderBase &BuilderIR = State.Builder ;
1000+ VectorBuilder VBuilder (BuilderIR);
1001+ Value *Mask = BuilderIR.CreateVectorSplat (State.VF , BuilderIR.getTrue ());
1002+ VBuilder.setMask (Mask).setEVL (Args.back ());
1003+ // Remove the EVL from Args
1004+ Args.pop_back ();
1005+ Value *VPInst = VBuilder.createSimpleIntrinsic (
1006+ VectorIntrinsicID, TysForDecl[0 ], Args, " vp.call" );
1007+ if (!VPInst->getType ()->isVoidTy ())
1008+ State.set (this , VPInst);
1009+ State.addMetadata (VPInst,
1010+ dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
1011+ } else {
1012+ // Use vector version of the intrinsic.
1013+ Module *M = State.Builder .GetInsertBlock ()->getModule ();
1014+ Function *VectorF =
1015+ Intrinsic::getOrInsertDeclaration (M, VectorIntrinsicID, TysForDecl);
1016+ assert (VectorF && " Can't retrieve vector intrinsic." );
10071017
1008- CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
1018+ auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
1019+ SmallVector<OperandBundleDef, 1 > OpBundles;
1020+ if (CI)
1021+ CI->getOperandBundlesAsDefs (OpBundles);
10091022
1010- setFlags (V);
1023+ CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
1024+ setFlags (V);
10111025
1012- if (!V->getType ()->isVoidTy ())
1013- State.set (this , V);
1014- State.addMetadata (V, CI);
1026+ if (!V->getType ()->isVoidTy ())
1027+ State.set (this , V);
1028+ State.addMetadata (V, CI);
1029+ }
10151030}
10161031
10171032InstructionCost VPWidenIntrinsicRecipe::computeCost (ElementCount VF,
@@ -1024,6 +1039,18 @@ InstructionCost VPWidenIntrinsicRecipe::computeCost(ElementCount VF,
10241039 // clear Arguments.
10251040 // TODO: Rework TTI interface to be independent of concrete IR values.
10261041 SmallVector<const Value *> Arguments;
1042+
1043+ Intrinsic::ID FID = VectorIntrinsicID;
1044+ unsigned NumOperands = getNumOperands ();
1045+ if (VPIntrinsic::isVPIntrinsic (VectorIntrinsicID)) {
1046+ std::optional<Intrinsic::ID> ID =
1047+ VPIntrinsic::getFunctionalIntrinsicIDForVP (VectorIntrinsicID);
1048+ if (ID) {
1049+ FID = ID.value ();
1050+ NumOperands = getNumOperands () - 1 ;
1051+ }
1052+ }
1053+
10271054 for (const auto &[Idx, Op] : enumerate(operands ())) {
10281055 auto *V = Op->getUnderlyingValue ();
10291056 if (!V) {
@@ -1039,14 +1066,14 @@ InstructionCost VPWidenIntrinsicRecipe::computeCost(ElementCount VF,
10391066
10401067 Type *RetTy = ToVectorTy (Ctx.Types .inferScalarType (this ), VF);
10411068 SmallVector<Type *> ParamTys;
1042- for (unsigned I = 0 ; I != getNumOperands () ; ++I)
1069+ for (unsigned I = 0 ; I != NumOperands ; ++I)
10431070 ParamTys.push_back (
10441071 ToVectorTy (Ctx.Types .inferScalarType (getOperand (I)), VF));
10451072
10461073 // TODO: Rework TTI interface to avoid reliance on underlying IntrinsicInst.
10471074 FastMathFlags FMF = hasFastMathFlags () ? getFastMathFlags () : FastMathFlags ();
10481075 IntrinsicCostAttributes CostAttrs (
1049- VectorIntrinsicID , RetTy, Arguments, ParamTys, FMF,
1076+ FID , RetTy, Arguments, ParamTys, FMF,
10501077 dyn_cast_or_null<IntrinsicInst>(getUnderlyingValue ()));
10511078 return Ctx.TTI .getIntrinsicInstrCost (CostAttrs, CostKind);
10521079}
0 commit comments