@@ -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) {
@@ -8237,42 +8281,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
82378281 return ;
82388282 }
82398283 case Intrinsic::experimental_vector_extract_last_active: {
8240- SDValue Data = getValue (I.getOperand (0 ));
8241- SDValue Mask = getValue (I.getOperand (1 ));
8242- SDValue PassThru = getValue (I.getOperand (2 ));
8243-
8244- EVT DataVT = Data.getValueType ();
8245- EVT ScalarVT = PassThru.getValueType ();
8246- EVT BoolVT = Mask.getValueType ().getScalarType ();
8247-
8248- // Find a suitable type for a stepvector.
8249- ConstantRange VScaleRange (1 , /* isFullSet=*/ true ); // Dummy value.
8250- if (DataVT.isScalableVector ())
8251- VScaleRange = getVScaleRange (I.getCaller (), 64 );
8252- unsigned EltWidth = TLI.getBitWidthForCttzElements (
8253- I.getType (), DataVT.getVectorElementCount (), /* ZeroIsPoison=*/ true ,
8254- &VScaleRange);
8255- MVT StepVT = MVT::getIntegerVT (EltWidth);
8256- EVT StepVecVT = DataVT.changeVectorElementType (StepVT);
8257-
8258- // Zero out lanes with inactive elements, then find the highest remaining
8259- // value from the stepvector.
8260- SDValue Zeroes = DAG.getConstant (0 , sdl, StepVecVT);
8261- SDValue StepVec = DAG.getStepVector (sdl, StepVecVT);
8262- SDValue ActiveElts = DAG.getSelect (sdl, StepVecVT, Mask, StepVec, Zeroes);
8263- SDValue HighestIdx =
8264- DAG.getNode (ISD::VECREDUCE_UMAX, sdl, StepVT, ActiveElts);
8265-
8266- // Extract the corresponding lane from the data vector
8267- EVT ExtVT = TLI.getVectorIdxTy (DAG.getDataLayout ());
8268- SDValue Idx = DAG.getZExtOrTrunc (HighestIdx, sdl, ExtVT);
8269- SDValue Extract =
8270- DAG.getNode (ISD::EXTRACT_VECTOR_ELT, sdl, ScalarVT, Data, Idx);
8271-
8272- // If all mask lanes were inactive, choose the passthru value instead.
8273- SDValue AnyActive = DAG.getNode (ISD::VECREDUCE_OR, sdl, BoolVT, Mask);
8274- SDValue Result = DAG.getSelect (sdl, ScalarVT, AnyActive, Extract, PassThru);
8275- setValue (&I, Result);
8284+ visitVectorExtractLastActive (I, Intrinsic);
82768285 return ;
82778286 }
82788287 }
0 commit comments