Skip to content

Commit f3c577e

Browse files
committed
[AArch64][SVE] Add fixed length codegen for FP_TO_{S,U}INT/{S,U}INT_TO_FP
Depends on D102607 Differential Revision: https://reviews.llvm.org/D102777
1 parent c2c2be4 commit f3c577e

File tree

5 files changed

+3621
-70
lines changed

5 files changed

+3621
-70
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,8 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
14821482
setOperationAction(ISD::FNEG, VT, Custom);
14831483
setOperationAction(ISD::FP_EXTEND, VT, Custom);
14841484
setOperationAction(ISD::FP_ROUND, VT, Custom);
1485+
setOperationAction(ISD::FP_TO_SINT, VT, Custom);
1486+
setOperationAction(ISD::FP_TO_UINT, VT, Custom);
14851487
setOperationAction(ISD::FRINT, VT, Custom);
14861488
setOperationAction(ISD::FROUND, VT, Custom);
14871489
setOperationAction(ISD::FROUNDEVEN, VT, Custom);
@@ -1501,6 +1503,7 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
15011503
setOperationAction(ISD::SHL, VT, Custom);
15021504
setOperationAction(ISD::SIGN_EXTEND, VT, Custom);
15031505
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom);
1506+
setOperationAction(ISD::SINT_TO_FP, VT, Custom);
15041507
setOperationAction(ISD::SMAX, VT, Custom);
15051508
setOperationAction(ISD::SMIN, VT, Custom);
15061509
setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
@@ -1510,6 +1513,7 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
15101513
setOperationAction(ISD::SUB, VT, Custom);
15111514
setOperationAction(ISD::TRUNCATE, VT, Custom);
15121515
setOperationAction(ISD::UDIV, VT, Custom);
1516+
setOperationAction(ISD::UINT_TO_FP, VT, Custom);
15131517
setOperationAction(ISD::UMAX, VT, Custom);
15141518
setOperationAction(ISD::UMIN, VT, Custom);
15151519
setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
@@ -3260,6 +3264,9 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
32603264
return LowerToPredicatedOp(Op, DAG, Opcode);
32613265
}
32623266

3267+
if (useSVEForFixedLengthVectorVT(VT) || useSVEForFixedLengthVectorVT(InVT))
3268+
return LowerFixedLengthFPToIntToSVE(Op, DAG);
3269+
32633270
unsigned NumElts = InVT.getVectorNumElements();
32643271

32653272
// f16 conversions are promoted to f32 when full fp16 is not supported.
@@ -3384,6 +3391,9 @@ SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
33843391
return LowerToPredicatedOp(Op, DAG, Opcode);
33853392
}
33863393

3394+
if (useSVEForFixedLengthVectorVT(VT) || useSVEForFixedLengthVectorVT(InVT))
3395+
return LowerFixedLengthIntToFPToSVE(Op, DAG);
3396+
33873397
uint64_t VTSize = VT.getFixedSizeInBits();
33883398
uint64_t InVTSize = InVT.getFixedSizeInBits();
33893399
if (VTSize < InVTSize) {
@@ -17994,6 +18004,95 @@ AArch64TargetLowering::LowerFixedLengthFPRoundToSVE(SDValue Op,
1799418004
return DAG.getNode(ISD::BITCAST, DL, VT, Val);
1799518005
}
1799618006

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+
1799718096
SDValue AArch64TargetLowering::getSVESafeBitCast(EVT VT, SDValue Op,
1799818097
SelectionDAG &DAG) const {
1799918098
SDLoc DL(Op);

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,8 @@ class AArch64TargetLowering : public TargetLowering {
10051005
SelectionDAG &DAG) const;
10061006
SDValue LowerFixedLengthFPExtendToSVE(SDValue Op, SelectionDAG &DAG) const;
10071007
SDValue LowerFixedLengthFPRoundToSVE(SDValue Op, SelectionDAG &DAG) const;
1008+
SDValue LowerFixedLengthIntToFPToSVE(SDValue Op, SelectionDAG &DAG) const;
1009+
SDValue LowerFixedLengthFPToIntToSVE(SDValue Op, SelectionDAG &DAG) const;
10081010

10091011
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
10101012
SmallVectorImpl<SDNode *> &Created) const override;

llvm/test/CodeGen/AArch64/sve-fixed-length-fp-converts.ll

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)