@@ -1482,6 +1482,8 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
1482
1482
setOperationAction(ISD::FNEG, VT, Custom);
1483
1483
setOperationAction(ISD::FP_EXTEND, VT, Custom);
1484
1484
setOperationAction(ISD::FP_ROUND, VT, Custom);
1485
+ setOperationAction(ISD::FP_TO_SINT, VT, Custom);
1486
+ setOperationAction(ISD::FP_TO_UINT, VT, Custom);
1485
1487
setOperationAction(ISD::FRINT, VT, Custom);
1486
1488
setOperationAction(ISD::FROUND, VT, Custom);
1487
1489
setOperationAction(ISD::FROUNDEVEN, VT, Custom);
@@ -1501,6 +1503,7 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
1501
1503
setOperationAction(ISD::SHL, VT, Custom);
1502
1504
setOperationAction(ISD::SIGN_EXTEND, VT, Custom);
1503
1505
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom);
1506
+ setOperationAction(ISD::SINT_TO_FP, VT, Custom);
1504
1507
setOperationAction(ISD::SMAX, VT, Custom);
1505
1508
setOperationAction(ISD::SMIN, VT, Custom);
1506
1509
setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
@@ -1510,6 +1513,7 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
1510
1513
setOperationAction(ISD::SUB, VT, Custom);
1511
1514
setOperationAction(ISD::TRUNCATE, VT, Custom);
1512
1515
setOperationAction(ISD::UDIV, VT, Custom);
1516
+ setOperationAction(ISD::UINT_TO_FP, VT, Custom);
1513
1517
setOperationAction(ISD::UMAX, VT, Custom);
1514
1518
setOperationAction(ISD::UMIN, VT, Custom);
1515
1519
setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
@@ -3260,6 +3264,9 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
3260
3264
return LowerToPredicatedOp(Op, DAG, Opcode);
3261
3265
}
3262
3266
3267
+ if (useSVEForFixedLengthVectorVT(VT) || useSVEForFixedLengthVectorVT(InVT))
3268
+ return LowerFixedLengthFPToIntToSVE(Op, DAG);
3269
+
3263
3270
unsigned NumElts = InVT.getVectorNumElements();
3264
3271
3265
3272
// f16 conversions are promoted to f32 when full fp16 is not supported.
@@ -3384,6 +3391,9 @@ SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
3384
3391
return LowerToPredicatedOp(Op, DAG, Opcode);
3385
3392
}
3386
3393
3394
+ if (useSVEForFixedLengthVectorVT(VT) || useSVEForFixedLengthVectorVT(InVT))
3395
+ return LowerFixedLengthIntToFPToSVE(Op, DAG);
3396
+
3387
3397
uint64_t VTSize = VT.getFixedSizeInBits();
3388
3398
uint64_t InVTSize = InVT.getFixedSizeInBits();
3389
3399
if (VTSize < InVTSize) {
@@ -17994,6 +18004,95 @@ AArch64TargetLowering::LowerFixedLengthFPRoundToSVE(SDValue Op,
17994
18004
return DAG.getNode(ISD::BITCAST, DL, VT, Val);
17995
18005
}
17996
18006
18007
+ SDValue
18008
+ AArch64TargetLowering::LowerFixedLengthIntToFPToSVE(SDValue Op,
18009
+ SelectionDAG &DAG) const {
18010
+ EVT VT = Op.getValueType();
18011
+ assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
18012
+
18013
+ bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP;
18014
+ unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
18015
+ : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
18016
+
18017
+ SDLoc DL(Op);
18018
+ SDValue Val = Op.getOperand(0);
18019
+ EVT SrcVT = Val.getValueType();
18020
+ EVT ContainerDstVT = getContainerForFixedLengthVector(DAG, VT);
18021
+ EVT ContainerSrcVT = getContainerForFixedLengthVector(DAG, SrcVT);
18022
+
18023
+ if (ContainerSrcVT.getVectorElementType().getSizeInBits() <=
18024
+ ContainerDstVT.getVectorElementType().getSizeInBits()) {
18025
+ SDValue Pg = getPredicateForVector(DAG, DL, VT);
18026
+
18027
+ Val = DAG.getNode(IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL,
18028
+ VT.changeTypeToInteger(), Val);
18029
+
18030
+ Val = convertToScalableVector(DAG, ContainerSrcVT, Val);
18031
+ Val = getSVESafeBitCast(ContainerDstVT.changeTypeToInteger(), Val, DAG);
18032
+ // Safe to use a larger than specified operand since we just unpacked the
18033
+ // data, hence the upper bits are zero.
18034
+ Val = DAG.getNode(Opcode, DL, ContainerDstVT, Pg, Val,
18035
+ DAG.getUNDEF(ContainerDstVT));
18036
+ return convertFromScalableVector(DAG, VT, Val);
18037
+ } else {
18038
+ EVT CvtVT = ContainerSrcVT.changeVectorElementType(
18039
+ ContainerDstVT.getVectorElementType());
18040
+ SDValue Pg = getPredicateForVector(DAG, DL, CvtVT);
18041
+
18042
+ Val = convertToScalableVector(DAG, ContainerSrcVT, Val);
18043
+ Val = DAG.getNode(Opcode, DL, CvtVT, Pg, Val, DAG.getUNDEF(CvtVT));
18044
+ Val = getSVESafeBitCast(ContainerSrcVT, Val, DAG);
18045
+ Val = convertFromScalableVector(DAG, SrcVT, Val);
18046
+
18047
+ Val = DAG.getNode(ISD::TRUNCATE, DL, VT.changeTypeToInteger(), Val);
18048
+ return DAG.getNode(ISD::BITCAST, DL, VT, Val);
18049
+ }
18050
+ }
18051
+
18052
+ SDValue
18053
+ AArch64TargetLowering::LowerFixedLengthFPToIntToSVE(SDValue Op,
18054
+ SelectionDAG &DAG) const {
18055
+ EVT VT = Op.getValueType();
18056
+ assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
18057
+
18058
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT;
18059
+ unsigned Opcode = IsSigned ? AArch64ISD::FCVTZS_MERGE_PASSTHRU
18060
+ : AArch64ISD::FCVTZU_MERGE_PASSTHRU;
18061
+
18062
+ SDLoc DL(Op);
18063
+ SDValue Val = Op.getOperand(0);
18064
+ EVT SrcVT = Val.getValueType();
18065
+ EVT ContainerDstVT = getContainerForFixedLengthVector(DAG, VT);
18066
+ EVT ContainerSrcVT = getContainerForFixedLengthVector(DAG, SrcVT);
18067
+
18068
+ if (ContainerSrcVT.getVectorElementType().getSizeInBits() <=
18069
+ ContainerDstVT.getVectorElementType().getSizeInBits()) {
18070
+ EVT CvtVT = ContainerDstVT.changeVectorElementType(
18071
+ ContainerSrcVT.getVectorElementType());
18072
+ SDValue Pg = getPredicateForVector(DAG, DL, VT);
18073
+
18074
+ Val = DAG.getNode(ISD::BITCAST, DL, SrcVT.changeTypeToInteger(), Val);
18075
+ Val = DAG.getNode(ISD::ANY_EXTEND, DL, VT, Val);
18076
+
18077
+ Val = convertToScalableVector(DAG, ContainerSrcVT, Val);
18078
+ Val = getSVESafeBitCast(CvtVT, Val, DAG);
18079
+ Val = DAG.getNode(Opcode, DL, ContainerDstVT, Pg, Val,
18080
+ DAG.getUNDEF(ContainerDstVT));
18081
+ return convertFromScalableVector(DAG, VT, Val);
18082
+ } else {
18083
+ EVT CvtVT = ContainerSrcVT.changeTypeToInteger();
18084
+ SDValue Pg = getPredicateForVector(DAG, DL, CvtVT);
18085
+
18086
+ // Safe to use a larger than specified result since an fp_to_int where the
18087
+ // result doesn't fit into the destination is undefined.
18088
+ Val = convertToScalableVector(DAG, ContainerSrcVT, Val);
18089
+ Val = DAG.getNode(Opcode, DL, CvtVT, Pg, Val, DAG.getUNDEF(CvtVT));
18090
+ Val = convertFromScalableVector(DAG, SrcVT.changeTypeToInteger(), Val);
18091
+
18092
+ return DAG.getNode(ISD::TRUNCATE, DL, VT, Val);
18093
+ }
18094
+ }
18095
+
17997
18096
SDValue AArch64TargetLowering::getSVESafeBitCast(EVT VT, SDValue Op,
17998
18097
SelectionDAG &DAG) const {
17999
18098
SDLoc DL(Op);
0 commit comments