@@ -6364,6 +6364,58 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
6364
6364
DAG.getNode(AArch64ISD::CTTZ_ELTS, dl, MVT::i64, CttzOp);
6365
6365
return DAG.getZExtOrTrunc(NewCttzElts, dl, Op.getValueType());
6366
6366
}
6367
+ case Intrinsic::experimental_vector_match: {
6368
+ SDValue ID =
6369
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_match, dl, MVT::i64);
6370
+
6371
+ auto Op1 = Op.getOperand(1);
6372
+ auto Op2 = Op.getOperand(2);
6373
+ auto Mask = Op.getOperand(3);
6374
+
6375
+ EVT Op1VT = Op1.getValueType();
6376
+ EVT Op2VT = Op2.getValueType();
6377
+ EVT ResVT = Op.getValueType();
6378
+
6379
+ assert((Op1VT.getVectorElementType() == MVT::i8 ||
6380
+ Op1VT.getVectorElementType() == MVT::i16) &&
6381
+ "Expected 8-bit or 16-bit characters.");
6382
+ assert(!Op2VT.isScalableVector() && "Search vector cannot be scalable.");
6383
+ assert(Op1VT.getVectorElementType() == Op2VT.getVectorElementType() &&
6384
+ "Operand type mismatch.");
6385
+ assert(Op1VT.getVectorMinNumElements() == Op2VT.getVectorNumElements() &&
6386
+ "Invalid operands.");
6387
+
6388
+ // Wrap the search vector in a scalable vector.
6389
+ EVT OpContainerVT = getContainerForFixedLengthVector(DAG, Op2VT);
6390
+ Op2 = convertToScalableVector(DAG, OpContainerVT, Op2);
6391
+
6392
+ // If the result is scalable, we need to broadbast the search vector across
6393
+ // the SVE register and then carry out the MATCH.
6394
+ if (ResVT.isScalableVector()) {
6395
+ Op2 = DAG.getNode(AArch64ISD::DUPLANE128, dl, OpContainerVT, Op2,
6396
+ DAG.getTargetConstant(0, dl, MVT::i64));
6397
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, ResVT, ID, Mask, Op1,
6398
+ Op2);
6399
+ }
6400
+
6401
+ // If the result is fixed, we can still use MATCH but we need to wrap the
6402
+ // first operand and the mask in scalable vectors before doing so.
6403
+ EVT MatchVT = OpContainerVT.changeElementType(MVT::i1);
6404
+
6405
+ // Wrap the operands.
6406
+ Op1 = convertToScalableVector(DAG, OpContainerVT, Op1);
6407
+ Mask = DAG.getNode(ISD::ANY_EXTEND, dl, Op1VT, Mask);
6408
+ Mask = convertFixedMaskToScalableVector(Mask, DAG);
6409
+
6410
+ // Carry out the match.
6411
+ SDValue Match =
6412
+ DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MatchVT, ID, Mask, Op1, Op2);
6413
+
6414
+ // Extract and return the result.
6415
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, Op1VT,
6416
+ DAG.getNode(ISD::SIGN_EXTEND, dl, OpContainerVT, Match),
6417
+ DAG.getVectorIdxConstant(0, dl));
6418
+ }
6367
6419
}
6368
6420
}
6369
6421
@@ -27046,6 +27098,7 @@ void AArch64TargetLowering::ReplaceNodeResults(
27046
27098
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, V));
27047
27099
return;
27048
27100
}
27101
+ case Intrinsic::experimental_vector_match:
27049
27102
case Intrinsic::get_active_lane_mask: {
27050
27103
if (!VT.isFixedLengthVector() || VT.getVectorElementType() != MVT::i1)
27051
27104
return;
0 commit comments