@@ -6415,6 +6415,50 @@ void SelectionDAGBuilder::visitVectorHistogram(const CallInst &I,
6415
6415
DAG.setRoot (Histogram);
6416
6416
}
6417
6417
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
+
6418
6462
// / Lower the call to the specified intrinsic function.
6419
6463
void SelectionDAGBuilder::visitIntrinsicCall (const CallInst &I,
6420
6464
unsigned Intrinsic) {
@@ -8237,42 +8281,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
8237
8281
return ;
8238
8282
}
8239
8283
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);
8276
8285
return ;
8277
8286
}
8278
8287
}
0 commit comments