@@ -4600,6 +4600,10 @@ SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
4600
4600
bool Trunc = Op.getConstantOperandVal(IsStrict ? 2 : 1) == 1;
4601
4601
4602
4602
if (VT.isScalableVector()) {
4603
+ // Let common code split the operation.
4604
+ if (SrcVT == MVT::nxv8f32)
4605
+ return Op;
4606
+
4603
4607
if (VT.getScalarType() != MVT::bf16)
4604
4608
return LowerToPredicatedOp(Op, DAG, AArch64ISD::FP_ROUND_MERGE_PASSTHRU);
4605
4609
@@ -4742,6 +4746,22 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
4742
4746
assert(!(IsStrict && VT.isScalableVector()) &&
4743
4747
"Unimplemented SVE support for STRICT_FP_to_INT!");
4744
4748
4749
+ // f16 conversions are promoted to f32 when full fp16 is not supported.
4750
+ if ((InVT.getVectorElementType() == MVT::f16 && !Subtarget->hasFullFP16()) ||
4751
+ InVT.getVectorElementType() == MVT::bf16) {
4752
+ EVT NewVT = VT.changeElementType(MVT::f32);
4753
+ SDLoc dl(Op);
4754
+ if (IsStrict) {
4755
+ SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NewVT, MVT::Other},
4756
+ {Op.getOperand(0), Op.getOperand(1)});
4757
+ return DAG.getNode(Op.getOpcode(), dl, {VT, MVT::Other},
4758
+ {Ext.getValue(1), Ext.getValue(0)});
4759
+ }
4760
+ return DAG.getNode(
4761
+ Op.getOpcode(), dl, Op.getValueType(),
4762
+ DAG.getNode(ISD::FP_EXTEND, dl, NewVT, Op.getOperand(0)));
4763
+ }
4764
+
4745
4765
if (VT.isScalableVector()) {
4746
4766
if (VT.getVectorElementType() == MVT::i1) {
4747
4767
SDLoc DL(Op);
@@ -4751,6 +4771,10 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
4751
4771
return DAG.getSetCC(DL, VT, Cvt, Zero, ISD::SETNE);
4752
4772
}
4753
4773
4774
+ // Let common code split the operation.
4775
+ if (InVT == MVT::nxv8f32)
4776
+ return Op;
4777
+
4754
4778
unsigned Opcode = Op.getOpcode() == ISD::FP_TO_UINT
4755
4779
? AArch64ISD::FCVTZU_MERGE_PASSTHRU
4756
4780
: AArch64ISD::FCVTZS_MERGE_PASSTHRU;
@@ -4761,24 +4785,6 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
4761
4785
useSVEForFixedLengthVectorVT(InVT, !Subtarget->isNeonAvailable()))
4762
4786
return LowerFixedLengthFPToIntToSVE(Op, DAG);
4763
4787
4764
- unsigned NumElts = InVT.getVectorNumElements();
4765
-
4766
- // f16 conversions are promoted to f32 when full fp16 is not supported.
4767
- if ((InVT.getVectorElementType() == MVT::f16 && !Subtarget->hasFullFP16()) ||
4768
- InVT.getVectorElementType() == MVT::bf16) {
4769
- MVT NewVT = MVT::getVectorVT(MVT::f32, NumElts);
4770
- SDLoc dl(Op);
4771
- if (IsStrict) {
4772
- SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NewVT, MVT::Other},
4773
- {Op.getOperand(0), Op.getOperand(1)});
4774
- return DAG.getNode(Op.getOpcode(), dl, {VT, MVT::Other},
4775
- {Ext.getValue(1), Ext.getValue(0)});
4776
- }
4777
- return DAG.getNode(
4778
- Op.getOpcode(), dl, Op.getValueType(),
4779
- DAG.getNode(ISD::FP_EXTEND, dl, NewVT, Op.getOperand(0)));
4780
- }
4781
-
4782
4788
uint64_t VTSize = VT.getFixedSizeInBits();
4783
4789
uint64_t InVTSize = InVT.getFixedSizeInBits();
4784
4790
if (VTSize < InVTSize) {
@@ -4813,7 +4819,7 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
4813
4819
4814
4820
// Use a scalar operation for conversions between single-element vectors of
4815
4821
// the same size.
4816
- if (NumElts == 1) {
4822
+ if (InVT.getVectorNumElements() == 1) {
4817
4823
SDLoc dl(Op);
4818
4824
SDValue Extract = DAG.getNode(
4819
4825
ISD::EXTRACT_VECTOR_ELT, dl, InVT.getScalarType(),
@@ -5059,23 +5065,14 @@ SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
5059
5065
assert(!(IsStrict && VT.isScalableVector()) &&
5060
5066
"Unimplemented SVE support for ISD:::STRICT_INT_TO_FP!");
5061
5067
5062
- if (VT.isScalableVector()) {
5063
- if (InVT.getVectorElementType() == MVT::i1) {
5064
- SDValue FalseVal = DAG.getConstantFP(0.0, dl, VT);
5065
- SDValue TrueVal = IsSigned ? DAG.getConstantFP(-1.0, dl, VT)
5066
- : DAG.getConstantFP(1.0, dl, VT);
5067
- return DAG.getNode(ISD::VSELECT, dl, VT, In, TrueVal, FalseVal);
5068
- }
5069
-
5070
- unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
5071
- : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
5072
- return LowerToPredicatedOp(Op, DAG, Opcode);
5068
+ // NOTE: i1->bf16 does not require promotion to f32.
5069
+ if (VT.isScalableVector() && InVT.getVectorElementType() == MVT::i1) {
5070
+ SDValue FalseVal = DAG.getConstantFP(0.0, dl, VT);
5071
+ SDValue TrueVal = IsSigned ? DAG.getConstantFP(-1.0, dl, VT)
5072
+ : DAG.getConstantFP(1.0, dl, VT);
5073
+ return DAG.getNode(ISD::VSELECT, dl, VT, In, TrueVal, FalseVal);
5073
5074
}
5074
5075
5075
- if (useSVEForFixedLengthVectorVT(VT, !Subtarget->isNeonAvailable()) ||
5076
- useSVEForFixedLengthVectorVT(InVT, !Subtarget->isNeonAvailable()))
5077
- return LowerFixedLengthIntToFPToSVE(Op, DAG);
5078
-
5079
5076
// Promote bf16 conversions to f32.
5080
5077
if (VT.getVectorElementType() == MVT::bf16) {
5081
5078
EVT F32 = VT.changeElementType(MVT::f32);
@@ -5092,6 +5089,20 @@ SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
5092
5089
DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
5093
5090
}
5094
5091
5092
+ if (VT.isScalableVector()) {
5093
+ // Let common code split the operation.
5094
+ if (VT == MVT::nxv8f32)
5095
+ return Op;
5096
+
5097
+ unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
5098
+ : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
5099
+ return LowerToPredicatedOp(Op, DAG, Opcode);
5100
+ }
5101
+
5102
+ if (useSVEForFixedLengthVectorVT(VT, !Subtarget->isNeonAvailable()) ||
5103
+ useSVEForFixedLengthVectorVT(InVT, !Subtarget->isNeonAvailable()))
5104
+ return LowerFixedLengthIntToFPToSVE(Op, DAG);
5105
+
5095
5106
uint64_t VTSize = VT.getFixedSizeInBits();
5096
5107
uint64_t InVTSize = InVT.getFixedSizeInBits();
5097
5108
if (VTSize < InVTSize) {
0 commit comments