[llvm] [AArch64] Add @llvm.experimental.vector.match (PR #101974)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 13 06:30:07 PST 2024
================
@@ -5778,6 +5791,73 @@ SDValue LowerSMELdrStr(SDValue N, SelectionDAG &DAG, bool IsLoad) {
DAG.getTargetConstant(ImmAddend, DL, MVT::i32)});
}
+SDValue LowerVectorMatch(SDValue Op, SelectionDAG &DAG) {
+ SDLoc dl(Op);
+ SDValue ID =
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_match, dl, MVT::i64);
+
+ auto Op1 = Op.getOperand(1);
+ auto Op2 = Op.getOperand(2);
+ auto Mask = Op.getOperand(3);
+
+ EVT Op1VT = Op1.getValueType();
+ EVT Op2VT = Op2.getValueType();
+ EVT ResVT = Op.getValueType();
+
+ assert((Op1VT.getVectorElementType() == MVT::i8 ||
+ Op1VT.getVectorElementType() == MVT::i16) &&
+ "Expected 8-bit or 16-bit characters.");
+
+ // Scalable vector type used to wrap operands.
+ // A single container is enough for both operands because ultimately the
+ // operands will have to be wrapped to the same type (nxv16i8 or nxv8i16).
+ EVT OpContainerVT = Op1VT.isScalableVector()
+ ? Op1VT
+ : getContainerForFixedLengthVector(DAG, Op1VT);
+
+ if (Op2VT.is128BitVector()) {
+ // If Op2 is a full 128-bit vector, wrap it trivially in a scalable vector.
+ Op2 = convertToScalableVector(DAG, OpContainerVT, Op2);
+ // Further, if the result is scalable, broadcast Op2 to a full SVE register.
+ if (ResVT.isScalableVector())
+ Op2 = DAG.getNode(AArch64ISD::DUPLANE128, dl, OpContainerVT, Op2,
+ DAG.getTargetConstant(0, dl, MVT::i64));
+ } else {
+ // If Op2 is not a full 128-bit vector, we always need to broadcast it.
+ unsigned Op2BitWidth = Op2VT.getFixedSizeInBits();
+ MVT Op2IntVT = MVT::getIntegerVT(Op2BitWidth);
+ MVT Op2PromotedVT = MVT::getVectorVT(Op2IntVT, 128 / Op2BitWidth,
+ /*IsScalable=*/true);
----------------
paulwalker-arm wrote:
```suggestion
MVT Op2PromotedVT = getPackedSVEVectorVT(Op2IntVT);
```
https://github.com/llvm/llvm-project/pull/101974
More information about the llvm-commits
mailing list