@@ -6415,6 +6415,50 @@ void SelectionDAGBuilder::visitVectorHistogram(const CallInst &I,
64156415 DAG.setRoot (Histogram);
64166416}
64176417
6418+ void SelectionDAGBuilder::visitVectorExtractLastActive (const CallInst &I,
6419+ unsigned Intrinsic) {
6420+ assert (Intrinsic == Intrinsic::experimental_vector_extract_last_active &&
6421+ " Tried lowering invalid vector extract last" );
6422+ SDLoc sdl = getCurSDLoc ();
6423+ SDValue Data = getValue (I.getOperand (0 ));
6424+ SDValue Mask = getValue (I.getOperand (1 ));
6425+ SDValue PassThru = getValue (I.getOperand (2 ));
6426+
6427+ EVT DataVT = Data.getValueType ();
6428+ EVT ScalarVT = PassThru.getValueType ();
6429+ EVT BoolVT = Mask.getValueType ().getScalarType ();
6430+
6431+ // Find a suitable type for a stepvector.
6432+ ConstantRange VScaleRange (1 , /* isFullSet=*/ true ); // Dummy value.
6433+ if (DataVT.isScalableVector ())
6434+ VScaleRange = getVScaleRange (I.getCaller (), 64 );
6435+ const TargetLowering &TLI = DAG.getTargetLoweringInfo ();
6436+ unsigned EltWidth = TLI.getBitWidthForCttzElements (
6437+ I.getType (), DataVT.getVectorElementCount (), /* ZeroIsPoison=*/ true ,
6438+ &VScaleRange);
6439+ MVT StepVT = MVT::getIntegerVT (EltWidth);
6440+ EVT StepVecVT = DataVT.changeVectorElementType (StepVT);
6441+
6442+ // Zero out lanes with inactive elements, then find the highest remaining
6443+ // value from the stepvector.
6444+ SDValue Zeroes = DAG.getConstant (0 , sdl, StepVecVT);
6445+ SDValue StepVec = DAG.getStepVector (sdl, StepVecVT);
6446+ SDValue ActiveElts = DAG.getSelect (sdl, StepVecVT, Mask, StepVec, Zeroes);
6447+ SDValue HighestIdx =
6448+ DAG.getNode (ISD::VECREDUCE_UMAX, sdl, StepVT, ActiveElts);
6449+
6450+ // Extract the corresponding lane from the data vector
6451+ EVT ExtVT = TLI.getVectorIdxTy (DAG.getDataLayout ());
6452+ SDValue Idx = DAG.getZExtOrTrunc (HighestIdx, sdl, ExtVT);
6453+ SDValue Extract =
6454+ DAG.getNode (ISD::EXTRACT_VECTOR_ELT, sdl, ScalarVT, Data, Idx);
6455+
6456+ // If all mask lanes were inactive, choose the passthru value instead.
6457+ SDValue AnyActive = DAG.getNode (ISD::VECREDUCE_OR, sdl, BoolVT, Mask);
6458+ SDValue Result = DAG.getSelect (sdl, ScalarVT, AnyActive, Extract, PassThru);
6459+ setValue (&I, Result);
6460+ }
6461+
64186462// / Lower the call to the specified intrinsic function.
64196463void SelectionDAGBuilder::visitIntrinsicCall (const CallInst &I,
64206464 unsigned Intrinsic) {
@@ -8236,6 +8280,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
82368280 visitVectorHistogram (I, Intrinsic);
82378281 return ;
82388282 }
8283+ case Intrinsic::experimental_vector_extract_last_active: {
8284+ visitVectorExtractLastActive (I, Intrinsic);
8285+ return ;
8286+ }
82398287 }
82408288}
82418289
0 commit comments