@@ -98,7 +98,6 @@ bool VPRecipeBase::mayWriteToMemory() const {
9898 case VPWidenLoadSC:
9999 case VPWidenPHISC:
100100 case VPWidenSC:
101- case VPWidenEVLSC:
102101 case VPWidenSelectSC: {
103102 const Instruction *I =
104103 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -142,7 +141,6 @@ bool VPRecipeBase::mayReadFromMemory() const {
142141 case VPWidenIntOrFpInductionSC:
143142 case VPWidenPHISC:
144143 case VPWidenSC:
145- case VPWidenEVLSC:
146144 case VPWidenSelectSC: {
147145 const Instruction *I =
148146 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -183,7 +181,6 @@ bool VPRecipeBase::mayHaveSideEffects() const {
183181 case VPWidenPHISC:
184182 case VPWidenPointerInductionSC:
185183 case VPWidenSC:
186- case VPWidenEVLSC:
187184 case VPWidenSelectSC: {
188185 const Instruction *I =
189186 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -957,24 +954,53 @@ void VPWidenIntrinsicRecipe::execute(VPTransformState &State) {
957954 Args.push_back (Arg);
958955 }
959956
960- // Use vector version of the intrinsic.
961- Module *M = State.Builder .GetInsertBlock ()->getModule ();
962- Function *VectorF =
963- Intrinsic::getOrInsertDeclaration (M, VectorIntrinsicID, TysForDecl);
964- assert (VectorF && " Can't retrieve vector intrinsic." );
957+ if (VPIntrinsic::isVPIntrinsic (VectorIntrinsicID) &&
958+ VectorIntrinsicID != Intrinsic::vp_select) {
959+ VectorBuilder VBuilder (State.Builder );
960+ Value *Mask =
961+ State.Builder .CreateVectorSplat (State.VF , State.Builder .getTrue ());
962+ VBuilder.setMask (Mask).setEVL (Args.back ());
963+ // Remove EVL from Args
964+ Args.pop_back ();
965+
966+ if (VectorIntrinsicID == Intrinsic::vp_icmp ||
967+ VectorIntrinsicID == Intrinsic::vp_fcmp) {
968+ auto &Ctx = State.Builder .getContext ();
969+ Value *Pred = MetadataAsValue::get (
970+ Ctx, MDString::get (Ctx, CmpInst::getPredicateName (getPredicate ())));
971+ Args.push_back (Pred);
972+ }
965973
966- auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
967- SmallVector<OperandBundleDef, 1 > OpBundles;
968- if (CI)
969- CI->getOperandBundlesAsDefs (OpBundles);
974+ Value *VPInst = VBuilder.createSimpleIntrinsic (
975+ VectorIntrinsicID, TysForDecl[0 ], Args, " vp.call" );
970976
971- CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
977+ if (isa<FPMathOperator>(VPInst))
978+ setFlags (cast<Instruction>(VPInst));
972979
973- setFlags (V);
980+ if (!VPInst->getType ()->isVoidTy ())
981+ State.set (this , VPInst);
982+ State.addMetadata (VPInst,
983+ dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
984+ } else {
985+ // Use vector version of the intrinsic.
986+ Module *M = State.Builder .GetInsertBlock ()->getModule ();
987+ Function *VectorF =
988+ Intrinsic::getOrInsertDeclaration (M, VectorIntrinsicID, TysForDecl);
989+ assert (VectorF && " Can't retrieve vector intrinsic." );
974990
975- if (!V->getType ()->isVoidTy ())
976- State.set (this , V);
977- State.addMetadata (V, CI);
991+ auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
992+ SmallVector<OperandBundleDef, 1 > OpBundles;
993+ if (CI)
994+ CI->getOperandBundlesAsDefs (OpBundles);
995+
996+ CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
997+
998+ setFlags (V);
999+
1000+ if (!V->getType ()->isVoidTy ())
1001+ State.set (this , V);
1002+ State.addMetadata (V, CI);
1003+ }
9781004}
9791005
9801006InstructionCost VPWidenIntrinsicRecipe::computeCost (ElementCount VF,
@@ -1006,6 +1032,20 @@ InstructionCost VPWidenIntrinsicRecipe::computeCost(ElementCount VF,
10061032 ParamTys.push_back (
10071033 ToVectorTy (Ctx.Types .inferScalarType (getOperand (I)), VF));
10081034
1035+ // TODO: Implment in cost model
1036+ if (std::optional<unsigned > FOp =
1037+ VPIntrinsic::getFunctionalOpcodeForVP (VectorIntrinsicID)) {
1038+ if (FOp == Instruction::FNeg) {
1039+ // Instruction *CtxI =
1040+ dyn_cast_or_null<Instruction>(getUnderlyingValue ());
1041+ Type *VectorTy = ToVectorTy (getResultType (), VF);
1042+ return Ctx.TTI .getArithmeticInstrCost (
1043+ FOp.value (), VectorTy, CostKind,
1044+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
1045+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None});
1046+ }
1047+ }
1048+
10091049 // TODO: Rework TTI interface to avoid reliance on underlying IntrinsicInst.
10101050 FastMathFlags FMF = hasFastMathFlags () ? getFastMathFlags () : FastMathFlags ();
10111051 IntrinsicCostAttributes CostAttrs (
@@ -1417,42 +1457,6 @@ InstructionCost VPWidenRecipe::computeCost(ElementCount VF,
14171457 }
14181458}
14191459
1420- void VPWidenEVLRecipe::execute (VPTransformState &State) {
1421- unsigned Opcode = getOpcode ();
1422- // TODO: Support other opcodes
1423- if (!Instruction::isBinaryOp (Opcode) && !Instruction::isUnaryOp (Opcode))
1424- llvm_unreachable (" Unsupported opcode in VPWidenEVLRecipe::execute" );
1425-
1426- State.setDebugLocFrom (getDebugLoc ());
1427-
1428- assert (State.get (getOperand (0 ))->getType ()->isVectorTy () &&
1429- " VPWidenEVLRecipe should not be used for scalars" );
1430-
1431- VPValue *EVL = getEVL ();
1432- Value *EVLArg = State.get (EVL, /* NeedsScalar=*/ true );
1433- IRBuilderBase &BuilderIR = State.Builder ;
1434- VectorBuilder Builder (BuilderIR);
1435- Value *Mask = BuilderIR.CreateVectorSplat (State.VF , BuilderIR.getTrue ());
1436-
1437- SmallVector<Value *, 4 > Ops;
1438- for (unsigned I = 0 , E = getNumOperands () - 1 ; I < E; ++I) {
1439- VPValue *VPOp = getOperand (I);
1440- Ops.push_back (State.get (VPOp));
1441- }
1442-
1443- Builder.setMask (Mask).setEVL (EVLArg);
1444- Value *VPInst =
1445- Builder.createVectorInstruction (Opcode, Ops[0 ]->getType (), Ops, " vp.op" );
1446- // Currently vp-intrinsics only accept FMF flags.
1447- // TODO: Enable other flags when support is added.
1448- if (isa<FPMathOperator>(VPInst))
1449- setFlags (cast<Instruction>(VPInst));
1450-
1451- State.set (this , VPInst);
1452- State.addMetadata (VPInst,
1453- dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
1454- }
1455-
14561460#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
14571461void VPWidenRecipe::print (raw_ostream &O, const Twine &Indent,
14581462 VPSlotTracker &SlotTracker) const {
@@ -1462,15 +1466,6 @@ void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent,
14621466 printFlags (O);
14631467 printOperands (O, SlotTracker);
14641468}
1465-
1466- void VPWidenEVLRecipe::print (raw_ostream &O, const Twine &Indent,
1467- VPSlotTracker &SlotTracker) const {
1468- O << Indent << " WIDEN " ;
1469- printAsOperand (O, SlotTracker);
1470- O << " = vp." << Instruction::getOpcodeName (getOpcode ());
1471- printFlags (O);
1472- printOperands (O, SlotTracker);
1473- }
14741469#endif
14751470
14761471void VPWidenCastRecipe::execute (VPTransformState &State) {
0 commit comments