@@ -6416,6 +6416,50 @@ void SelectionDAGBuilder::visitVectorHistogram(const CallInst &I,
64166416 DAG.setRoot (Histogram);
64176417}
64186418
6419+ void SelectionDAGBuilder::visitVectorExtractLastActive (const CallInst &I,
6420+ unsigned Intrinsic) {
6421+ assert (Intrinsic == Intrinsic::experimental_vector_extract_last_active &&
6422+ " Tried lowering invalid vector extract last" );
6423+ SDLoc sdl = getCurSDLoc ();
6424+ SDValue Data = getValue (I.getOperand (0 ));
6425+ SDValue Mask = getValue (I.getOperand (1 ));
6426+ SDValue PassThru = getValue (I.getOperand (2 ));
6427+
6428+ EVT DataVT = Data.getValueType ();
6429+ EVT ScalarVT = PassThru.getValueType ();
6430+ EVT BoolVT = Mask.getValueType ().getScalarType ();
6431+
6432+ // Find a suitable type for a stepvector.
6433+ ConstantRange VScaleRange (1 , /* isFullSet=*/ true ); // Dummy value.
6434+ if (DataVT.isScalableVector ())
6435+ VScaleRange = getVScaleRange (I.getCaller (), 64 );
6436+ const TargetLowering &TLI = DAG.getTargetLoweringInfo ();
6437+ unsigned EltWidth = TLI.getBitWidthForCttzElements (
6438+ I.getType (), DataVT.getVectorElementCount (), /* ZeroIsPoison=*/ true ,
6439+ &VScaleRange);
6440+ MVT StepVT = MVT::getIntegerVT (EltWidth);
6441+ EVT StepVecVT = DataVT.changeVectorElementType (StepVT);
6442+
6443+ // Zero out lanes with inactive elements, then find the highest remaining
6444+ // value from the stepvector.
6445+ SDValue Zeroes = DAG.getConstant (0 , sdl, StepVecVT);
6446+ SDValue StepVec = DAG.getStepVector (sdl, StepVecVT);
6447+ SDValue ActiveElts = DAG.getSelect (sdl, StepVecVT, Mask, StepVec, Zeroes);
6448+ SDValue HighestIdx =
6449+ DAG.getNode (ISD::VECREDUCE_UMAX, sdl, StepVT, ActiveElts);
6450+
6451+ // Extract the corresponding lane from the data vector
6452+ EVT ExtVT = TLI.getVectorIdxTy (DAG.getDataLayout ());
6453+ SDValue Idx = DAG.getZExtOrTrunc (HighestIdx, sdl, ExtVT);
6454+ SDValue Extract =
6455+ DAG.getNode (ISD::EXTRACT_VECTOR_ELT, sdl, ScalarVT, Data, Idx);
6456+
6457+ // If all mask lanes were inactive, choose the passthru value instead.
6458+ SDValue AnyActive = DAG.getNode (ISD::VECREDUCE_OR, sdl, BoolVT, Mask);
6459+ SDValue Result = DAG.getSelect (sdl, ScalarVT, AnyActive, Extract, PassThru);
6460+ setValue (&I, Result);
6461+ }
6462+
64196463// / Lower the call to the specified intrinsic function.
64206464void SelectionDAGBuilder::visitIntrinsicCall (const CallInst &I,
64216465 unsigned Intrinsic) {
@@ -8208,42 +8252,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
82088252 return ;
82098253 }
82108254 case Intrinsic::experimental_vector_extract_last_active: {
8211- SDValue Data = getValue (I.getOperand (0 ));
8212- SDValue Mask = getValue (I.getOperand (1 ));
8213- SDValue PassThru = getValue (I.getOperand (2 ));
8214-
8215- EVT DataVT = Data.getValueType ();
8216- EVT ScalarVT = PassThru.getValueType ();
8217- EVT BoolVT = Mask.getValueType ().getScalarType ();
8218-
8219- // Find a suitable type for a stepvector.
8220- ConstantRange VScaleRange (1 , /* isFullSet=*/ true ); // Dummy value.
8221- if (DataVT.isScalableVector ())
8222- VScaleRange = getVScaleRange (I.getCaller (), 64 );
8223- unsigned EltWidth = TLI.getBitWidthForCttzElements (
8224- I.getType (), DataVT.getVectorElementCount (), /* ZeroIsPoison=*/ true ,
8225- &VScaleRange);
8226- MVT StepVT = MVT::getIntegerVT (EltWidth);
8227- EVT StepVecVT = DataVT.changeVectorElementType (StepVT);
8228-
8229- // Zero out lanes with inactive elements, then find the highest remaining
8230- // value from the stepvector.
8231- SDValue Zeroes = DAG.getConstant (0 , sdl, StepVecVT);
8232- SDValue StepVec = DAG.getStepVector (sdl, StepVecVT);
8233- SDValue ActiveElts = DAG.getSelect (sdl, StepVecVT, Mask, StepVec, Zeroes);
8234- SDValue HighestIdx =
8235- DAG.getNode (ISD::VECREDUCE_UMAX, sdl, StepVT, ActiveElts);
8236-
8237- // Extract the corresponding lane from the data vector
8238- EVT ExtVT = TLI.getVectorIdxTy (DAG.getDataLayout ());
8239- SDValue Idx = DAG.getZExtOrTrunc (HighestIdx, sdl, ExtVT);
8240- SDValue Extract =
8241- DAG.getNode (ISD::EXTRACT_VECTOR_ELT, sdl, ScalarVT, Data, Idx);
8242-
8243- // If all mask lanes were inactive, choose the passthru value instead.
8244- SDValue AnyActive = DAG.getNode (ISD::VECREDUCE_OR, sdl, BoolVT, Mask);
8245- SDValue Result = DAG.getSelect (sdl, ScalarVT, AnyActive, Extract, PassThru);
8246- setValue (&I, Result);
8255+ visitVectorExtractLastActive (I, Intrinsic);
82478256 return ;
82488257 }
82498258 }
0 commit comments