@@ -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) {
@@ -8236,6 +8280,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
8236
8280
visitVectorHistogram (I, Intrinsic);
8237
8281
return ;
8238
8282
}
8283
+ case Intrinsic::experimental_vector_extract_last_active: {
8284
+ visitVectorExtractLastActive (I, Intrinsic);
8285
+ return ;
8286
+ }
8239
8287
}
8240
8288
}
8241
8289
0 commit comments