@@ -6416,6 +6416,50 @@ void SelectionDAGBuilder::visitVectorHistogram(const CallInst &I,
6416
6416
DAG.setRoot (Histogram);
6417
6417
}
6418
6418
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
+
6419
6463
// / Lower the call to the specified intrinsic function.
6420
6464
void SelectionDAGBuilder::visitIntrinsicCall (const CallInst &I,
6421
6465
unsigned Intrinsic) {
@@ -8208,42 +8252,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
8208
8252
return ;
8209
8253
}
8210
8254
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);
8247
8256
return ;
8248
8257
}
8249
8258
}
0 commit comments