@@ -99,7 +99,6 @@ bool VPRecipeBase::mayWriteToMemory() const {
9999 case VPWidenLoadSC:
100100 case VPWidenPHISC:
101101 case VPWidenSC:
102- case VPWidenEVLSC:
103102 case VPWidenSelectSC: {
104103 const Instruction *I =
105104 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -143,7 +142,6 @@ bool VPRecipeBase::mayReadFromMemory() const {
143142 case VPWidenIntOrFpInductionSC:
144143 case VPWidenPHISC:
145144 case VPWidenSC:
146- case VPWidenEVLSC:
147145 case VPWidenSelectSC: {
148146 const Instruction *I =
149147 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -184,7 +182,6 @@ bool VPRecipeBase::mayHaveSideEffects() const {
184182 case VPWidenPHISC:
185183 case VPWidenPointerInductionSC:
186184 case VPWidenSC:
187- case VPWidenEVLSC:
188185 case VPWidenSelectSC: {
189186 const Instruction *I =
190187 dyn_cast_or_null<Instruction>(getVPSingleValue ()->getUnderlyingValue ());
@@ -994,24 +991,53 @@ void VPWidenIntrinsicRecipe::execute(VPTransformState &State) {
994991 Args.push_back (Arg);
995992 }
996993
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." );
994+ if (VPIntrinsic::isVPIntrinsic (VectorIntrinsicID) &&
995+ VectorIntrinsicID != Intrinsic::vp_select) {
996+ VectorBuilder VBuilder (State.Builder );
997+ Value *Mask =
998+ State.Builder .CreateVectorSplat (State.VF , State.Builder .getTrue ());
999+ VBuilder.setMask (Mask).setEVL (Args.back ());
1000+ // Remove EVL from Args
1001+ Args.pop_back ();
1002+
1003+ if (VectorIntrinsicID == Intrinsic::vp_icmp ||
1004+ VectorIntrinsicID == Intrinsic::vp_fcmp) {
1005+ auto &Ctx = State.Builder .getContext ();
1006+ Value *Pred = MetadataAsValue::get (
1007+ Ctx, MDString::get (Ctx, CmpInst::getPredicateName (getPredicate ())));
1008+ Args.push_back (Pred);
1009+ }
10021010
1003- auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
1004- SmallVector<OperandBundleDef, 1 > OpBundles;
1005- if (CI)
1006- CI->getOperandBundlesAsDefs (OpBundles);
1011+ Value *VPInst = VBuilder.createSimpleIntrinsic (
1012+ VectorIntrinsicID, TysForDecl[0 ], Args, " vp.call" );
10071013
1008- CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
1014+ if (isa<FPMathOperator>(VPInst))
1015+ setFlags (cast<Instruction>(VPInst));
10091016
1010- setFlags (V);
1017+ if (!VPInst->getType ()->isVoidTy ())
1018+ State.set (this , VPInst);
1019+ State.addMetadata (VPInst,
1020+ dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
1021+ } else {
1022+ // Use vector version of the intrinsic.
1023+ Module *M = State.Builder .GetInsertBlock ()->getModule ();
1024+ Function *VectorF =
1025+ Intrinsic::getOrInsertDeclaration (M, VectorIntrinsicID, TysForDecl);
1026+ assert (VectorF && " Can't retrieve vector intrinsic." );
10111027
1012- if (!V->getType ()->isVoidTy ())
1013- State.set (this , V);
1014- State.addMetadata (V, CI);
1028+ auto *CI = cast_or_null<CallInst>(getUnderlyingValue ());
1029+ SmallVector<OperandBundleDef, 1 > OpBundles;
1030+ if (CI)
1031+ CI->getOperandBundlesAsDefs (OpBundles);
1032+
1033+ CallInst *V = State.Builder .CreateCall (VectorF, Args, OpBundles);
1034+
1035+ setFlags (V);
1036+
1037+ if (!V->getType ()->isVoidTy ())
1038+ State.set (this , V);
1039+ State.addMetadata (V, CI);
1040+ }
10151041}
10161042
10171043InstructionCost VPWidenIntrinsicRecipe::computeCost (ElementCount VF,
@@ -1043,6 +1069,20 @@ InstructionCost VPWidenIntrinsicRecipe::computeCost(ElementCount VF,
10431069 ParamTys.push_back (
10441070 ToVectorTy (Ctx.Types .inferScalarType (getOperand (I)), VF));
10451071
1072+ // TODO: Implment in cost model
1073+ if (std::optional<unsigned > FOp =
1074+ VPIntrinsic::getFunctionalOpcodeForVP (VectorIntrinsicID)) {
1075+ if (FOp == Instruction::FNeg) {
1076+ // Instruction *CtxI =
1077+ dyn_cast_or_null<Instruction>(getUnderlyingValue ());
1078+ Type *VectorTy = ToVectorTy (getResultType (), VF);
1079+ return Ctx.TTI .getArithmeticInstrCost (
1080+ FOp.value (), VectorTy, CostKind,
1081+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
1082+ {TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None});
1083+ }
1084+ }
1085+
10461086 // TODO: Rework TTI interface to avoid reliance on underlying IntrinsicInst.
10471087 FastMathFlags FMF = hasFastMathFlags () ? getFastMathFlags () : FastMathFlags ();
10481088 IntrinsicCostAttributes CostAttrs (
@@ -1454,64 +1494,6 @@ InstructionCost VPWidenRecipe::computeCost(ElementCount VF,
14541494 }
14551495}
14561496
1457- void VPWidenEVLRecipe::execute (VPTransformState &State) {
1458- unsigned Opcode = getOpcode ();
1459- if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
1460- Value *Op1 = State.get (getOperand (0 ));
1461- Value *Op2 = State.get (getOperand (1 ));
1462- auto &Ctx = State.Builder .getContext ();
1463- Value *Pred = MetadataAsValue::get (
1464- Ctx, MDString::get (Ctx, CmpInst::getPredicateName (getPredicate ())));
1465-
1466- IRBuilderBase &BuilderIR = State.Builder ;
1467- VectorBuilder Builder (BuilderIR);
1468-
1469- Value *Mask = BuilderIR.CreateVectorSplat (State.VF , BuilderIR.getTrue ());
1470- Builder.setMask (Mask).setEVL (State.get (getEVL (), /* NeedsScalar=*/ true ));
1471- VectorType *RetType = VectorType::get (Type::getInt1Ty (Ctx), State.VF );
1472- Value *VPInst = Builder.createVectorInstruction (Opcode, RetType,
1473- {Op1, Op2, Pred}, " vp.op" );
1474- if (isa<FPMathOperator>(VPInst))
1475- setFlags (cast<Instruction>(VPInst));
1476-
1477- State.set (this , VPInst);
1478- State.addMetadata (VPInst,
1479- dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
1480- return ;
1481- }
1482-
1483- if (Instruction::isBinaryOp (Opcode) || Instruction::isUnaryOp (Opcode)) {
1484- State.setDebugLocFrom (getDebugLoc ());
1485-
1486- assert (State.get (getOperand (0 ))->getType ()->isVectorTy () &&
1487- " VPWidenEVLRecipe should not be used for scalars" );
1488-
1489- VPValue *EVL = getEVL ();
1490- Value *EVLArg = State.get (EVL, /* NeedsScalar=*/ true );
1491- IRBuilderBase &BuilderIR = State.Builder ;
1492- VectorBuilder Builder (BuilderIR);
1493- Value *Mask = BuilderIR.CreateVectorSplat (State.VF , BuilderIR.getTrue ());
1494-
1495- SmallVector<Value *, 4 > Ops;
1496- for (unsigned I = 0 , E = getNumOperands () - 1 ; I < E; ++I) {
1497- VPValue *VPOp = getOperand (I);
1498- Ops.push_back (State.get (VPOp));
1499- }
1500-
1501- Builder.setMask (Mask).setEVL (EVLArg);
1502- Value *VPInst = Builder.createVectorInstruction (Opcode, Ops[0 ]->getType (),
1503- Ops, " vp.op" );
1504- // Currently vp-intrinsics only accept FMF flags.
1505- // TODO: Enable other flags when support is added.
1506- if (isa<FPMathOperator>(VPInst))
1507- setFlags (cast<Instruction>(VPInst));
1508-
1509- State.set (this , VPInst);
1510- State.addMetadata (VPInst,
1511- dyn_cast_or_null<Instruction>(getUnderlyingValue ()));
1512- }
1513- }
1514-
15151497#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
15161498void VPWidenRecipe::print (raw_ostream &O, const Twine &Indent,
15171499 VPSlotTracker &SlotTracker) const {
@@ -1521,15 +1503,6 @@ void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent,
15211503 printFlags (O);
15221504 printOperands (O, SlotTracker);
15231505}
1524-
1525- void VPWidenEVLRecipe::print (raw_ostream &O, const Twine &Indent,
1526- VPSlotTracker &SlotTracker) const {
1527- O << Indent << " WIDEN " ;
1528- printAsOperand (O, SlotTracker);
1529- O << " = vp." << Instruction::getOpcodeName (getOpcode ());
1530- printFlags (O);
1531- printOperands (O, SlotTracker);
1532- }
15331506#endif
15341507
15351508void VPWidenCastRecipe::execute (VPTransformState &State) {
0 commit comments