@@ -5231,18 +5231,19 @@ defm FCVTZS : FPToIntegerScaled<0b11, 0b000, "fcvtzs", any_fp_to_sint>;
52315231defm FCVTZU : FPToIntegerScaled<0b11, 0b001, "fcvtzu", any_fp_to_uint>;
52325232
52335233let Predicates = [HasNEON, HasFPRCVT] in{
5234- defm FCVTAS : FPToIntegerSIMDScalar<0b11, 0b010, "fcvtas">;
5235- defm FCVTAU : FPToIntegerSIMDScalar<0b11, 0b011, "fcvtau">;
5236- defm FCVTMS : FPToIntegerSIMDScalar<0b10, 0b100, "fcvtms">;
5237- defm FCVTMU : FPToIntegerSIMDScalar<0b10, 0b101, "fcvtmu">;
5238- defm FCVTNS : FPToIntegerSIMDScalar<0b01, 0b010, "fcvtns">;
5239- defm FCVTNU : FPToIntegerSIMDScalar<0b01, 0b011, "fcvtnu">;
5240- defm FCVTPS : FPToIntegerSIMDScalar<0b10, 0b010, "fcvtps">;
5241- defm FCVTPU : FPToIntegerSIMDScalar<0b10, 0b011, "fcvtpu">;
5234+ defm FCVTAS : FPToIntegerSIMDScalar<0b11, 0b010, "fcvtas", int_aarch64_neon_fcvtas >;
5235+ defm FCVTAU : FPToIntegerSIMDScalar<0b11, 0b011, "fcvtau", int_aarch64_neon_fcvtau >;
5236+ defm FCVTMS : FPToIntegerSIMDScalar<0b10, 0b100, "fcvtms", int_aarch64_neon_fcvtms >;
5237+ defm FCVTMU : FPToIntegerSIMDScalar<0b10, 0b101, "fcvtmu", int_aarch64_neon_fcvtmu >;
5238+ defm FCVTNS : FPToIntegerSIMDScalar<0b01, 0b010, "fcvtns", int_aarch64_neon_fcvtns >;
5239+ defm FCVTNU : FPToIntegerSIMDScalar<0b01, 0b011, "fcvtnu", int_aarch64_neon_fcvtnu >;
5240+ defm FCVTPS : FPToIntegerSIMDScalar<0b10, 0b010, "fcvtps", int_aarch64_neon_fcvtps >;
5241+ defm FCVTPU : FPToIntegerSIMDScalar<0b10, 0b011, "fcvtpu", int_aarch64_neon_fcvtpu >;
52425242 defm FCVTZS : FPToIntegerSIMDScalar<0b10, 0b110, "fcvtzs">;
52435243 defm FCVTZU : FPToIntegerSIMDScalar<0b10, 0b111, "fcvtzu">;
52445244}
52455245
5246+
52465247// AArch64's FCVT instructions saturate when out of range.
52475248multiclass FPToIntegerSatPats<SDNode to_int_sat, SDNode to_int_sat_gi, string INST> {
52485249 let Predicates = [HasFullFP16] in {
@@ -5309,35 +5310,6 @@ multiclass FPToIntegerSatPats<SDNode to_int_sat, SDNode to_int_sat_gi, string IN
53095310defm : FPToIntegerSatPats<fp_to_sint_sat, fp_to_sint_sat_gi, "FCVTZS">;
53105311defm : FPToIntegerSatPats<fp_to_uint_sat, fp_to_uint_sat_gi, "FCVTZU">;
53115312
5312- multiclass FPToIntegerIntPats<Intrinsic round, string INST> {
5313- let Predicates = [HasFullFP16] in {
5314- def : Pat<(i32 (round f16:$Rn)), (!cast<Instruction>(INST # UWHr) $Rn)>;
5315- def : Pat<(i64 (round f16:$Rn)), (!cast<Instruction>(INST # UXHr) $Rn)>;
5316- }
5317- def : Pat<(i32 (round f32:$Rn)), (!cast<Instruction>(INST # UWSr) $Rn)>;
5318- def : Pat<(i64 (round f32:$Rn)), (!cast<Instruction>(INST # UXSr) $Rn)>;
5319- def : Pat<(i32 (round f64:$Rn)), (!cast<Instruction>(INST # UWDr) $Rn)>;
5320- def : Pat<(i64 (round f64:$Rn)), (!cast<Instruction>(INST # UXDr) $Rn)>;
5321-
5322- let Predicates = [HasFullFP16] in {
5323- def : Pat<(i32 (round (fmul f16:$Rn, fixedpoint_f16_i32:$scale))),
5324- (!cast<Instruction>(INST # SWHri) $Rn, $scale)>;
5325- def : Pat<(i64 (round (fmul f16:$Rn, fixedpoint_f16_i64:$scale))),
5326- (!cast<Instruction>(INST # SXHri) $Rn, $scale)>;
5327- }
5328- def : Pat<(i32 (round (fmul f32:$Rn, fixedpoint_f32_i32:$scale))),
5329- (!cast<Instruction>(INST # SWSri) $Rn, $scale)>;
5330- def : Pat<(i64 (round (fmul f32:$Rn, fixedpoint_f32_i64:$scale))),
5331- (!cast<Instruction>(INST # SXSri) $Rn, $scale)>;
5332- def : Pat<(i32 (round (fmul f64:$Rn, fixedpoint_f64_i32:$scale))),
5333- (!cast<Instruction>(INST # SWDri) $Rn, $scale)>;
5334- def : Pat<(i64 (round (fmul f64:$Rn, fixedpoint_f64_i64:$scale))),
5335- (!cast<Instruction>(INST # SXDri) $Rn, $scale)>;
5336- }
5337-
5338- defm : FPToIntegerIntPats<int_aarch64_neon_fcvtzs, "FCVTZS">;
5339- defm : FPToIntegerIntPats<int_aarch64_neon_fcvtzu, "FCVTZU">;
5340-
53415313multiclass FPToIntegerPats<SDNode to_int, SDNode to_int_sat, SDNode round, string INST> {
53425314 def : Pat<(i32 (to_int (round f32:$Rn))),
53435315 (!cast<Instruction>(INST # UWSr) f32:$Rn)>;
@@ -6572,14 +6544,14 @@ defm FCMGE : SIMDFPCmpTwoScalar<1, 1, 0b01100, "fcmge", AArch64fcmgez>;
65726544defm FCMGT : SIMDFPCmpTwoScalar<0, 1, 0b01100, "fcmgt", AArch64fcmgtz>;
65736545defm FCMLE : SIMDFPCmpTwoScalar<1, 1, 0b01101, "fcmle", AArch64fcmlez>;
65746546defm FCMLT : SIMDFPCmpTwoScalar<0, 1, 0b01110, "fcmlt", AArch64fcmltz>;
6575- defm FCVTAS : SIMDFPTwoScalar< 0, 0, 0b11100, "fcvtas">;
6576- defm FCVTAU : SIMDFPTwoScalar< 1, 0, 0b11100, "fcvtau">;
6577- defm FCVTMS : SIMDFPTwoScalar< 0, 0, 0b11011, "fcvtms">;
6578- defm FCVTMU : SIMDFPTwoScalar< 1, 0, 0b11011, "fcvtmu">;
6579- defm FCVTNS : SIMDFPTwoScalar< 0, 0, 0b11010, "fcvtns">;
6580- defm FCVTNU : SIMDFPTwoScalar< 1, 0, 0b11010, "fcvtnu">;
6581- defm FCVTPS : SIMDFPTwoScalar< 0, 1, 0b11010, "fcvtps">;
6582- defm FCVTPU : SIMDFPTwoScalar< 1, 1, 0b11010, "fcvtpu">;
6547+ defm FCVTAS : SIMDFPTwoScalar< 0, 0, 0b11100, "fcvtas", int_aarch64_neon_fcvtas >;
6548+ defm FCVTAU : SIMDFPTwoScalar< 1, 0, 0b11100, "fcvtau", int_aarch64_neon_fcvtau >;
6549+ defm FCVTMS : SIMDFPTwoScalar< 0, 0, 0b11011, "fcvtms", int_aarch64_neon_fcvtms >;
6550+ defm FCVTMU : SIMDFPTwoScalar< 1, 0, 0b11011, "fcvtmu", int_aarch64_neon_fcvtmu >;
6551+ defm FCVTNS : SIMDFPTwoScalar< 0, 0, 0b11010, "fcvtns", int_aarch64_neon_fcvtns >;
6552+ defm FCVTNU : SIMDFPTwoScalar< 1, 0, 0b11010, "fcvtnu", int_aarch64_neon_fcvtnu >;
6553+ defm FCVTPS : SIMDFPTwoScalar< 0, 1, 0b11010, "fcvtps", int_aarch64_neon_fcvtps >;
6554+ defm FCVTPU : SIMDFPTwoScalar< 1, 1, 0b11010, "fcvtpu", int_aarch64_neon_fcvtpu >;
65836555def FCVTXNv1i64 : SIMDInexactCvtTwoScalar<0b10110, "fcvtxn">;
65846556defm FCVTZS : SIMDFPTwoScalar< 0, 1, 0b11011, "fcvtzs">;
65856557defm FCVTZU : SIMDFPTwoScalar< 1, 1, 0b11011, "fcvtzu">;
@@ -6600,6 +6572,86 @@ defm UQXTN : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
66006572defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd",
66016573 int_aarch64_neon_usqadd>;
66026574
6575+ // Floating-point conversion patterns.
6576+ multiclass FPToIntegerSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
6577+ def : Pat<(f32 (bitconvert (i32 (OpN (f64 FPR64:$Rn))))),
6578+ (!cast<Instruction>(INST # SDr) FPR64:$Rn)>;
6579+ def : Pat<(f32 (bitconvert (i32 (OpN (f16 FPR16:$Rn))))),
6580+ (!cast<Instruction>(INST # SHr) FPR16:$Rn)>;
6581+ def : Pat<(f64 (bitconvert (i64 (OpN (f16 FPR16:$Rn))))),
6582+ (!cast<Instruction>(INST # DHr) FPR16:$Rn)>;
6583+ def : Pat<(f64 (bitconvert (i64 (OpN (f32 FPR32:$Rn))))),
6584+ (!cast<Instruction>(INST # DSr) FPR32:$Rn)>;
6585+ def : Pat<(f32 (bitconvert (i32 (OpN (f32 FPR32:$Rn))))),
6586+ (!cast<Instruction>(INST # v1i32) FPR32:$Rn)>;
6587+ def : Pat<(f64 (bitconvert (i64 (OpN (f64 FPR64:$Rn))))),
6588+ (!cast<Instruction>(INST # v1i64) FPR64:$Rn)>;
6589+
6590+ }
6591+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtas, "FCVTAS">;
6592+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtau, "FCVTAU">;
6593+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtms, "FCVTMS">;
6594+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtmu, "FCVTMU">;
6595+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtns, "FCVTNS">;
6596+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtnu, "FCVTNU">;
6597+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtps, "FCVTPS">;
6598+ defm: FPToIntegerSIMDScalarPatterns<int_aarch64_neon_fcvtpu, "FCVTPU">;
6599+
6600+ multiclass FPToIntegerIntPats<Intrinsic round, string INST> {
6601+ let Predicates = [HasFullFP16] in {
6602+ def : Pat<(i32 (round f16:$Rn)), (!cast<Instruction>(INST # UWHr) $Rn)>;
6603+ def : Pat<(i64 (round f16:$Rn)), (!cast<Instruction>(INST # UXHr) $Rn)>;
6604+ }
6605+ def : Pat<(i32 (round f32:$Rn)), (!cast<Instruction>(INST # UWSr) $Rn)>;
6606+ def : Pat<(i64 (round f32:$Rn)), (!cast<Instruction>(INST # UXSr) $Rn)>;
6607+ def : Pat<(i32 (round f64:$Rn)), (!cast<Instruction>(INST # UWDr) $Rn)>;
6608+ def : Pat<(i64 (round f64:$Rn)), (!cast<Instruction>(INST # UXDr) $Rn)>;
6609+
6610+ // For global-isel we can use register classes to determine
6611+ // which FCVT instruction to use.
6612+ let Predicates = [HasFPRCVT] in {
6613+ def : Pat<(i32 (round f16:$Rn)), (!cast<Instruction>(INST # SHr) $Rn)>;
6614+ def : Pat<(i64 (round f16:$Rn)), (!cast<Instruction>(INST # DHr) $Rn)>;
6615+ def : Pat<(i64 (round f32:$Rn)), (!cast<Instruction>(INST # DSr) $Rn)>;
6616+ def : Pat<(i32 (round f64:$Rn)), (!cast<Instruction>(INST # SDr) $Rn)>;
6617+ }
6618+ def : Pat<(i32 (round f32:$Rn)), (!cast<Instruction>(INST # v1i32) $Rn)>;
6619+ def : Pat<(i64 (round f64:$Rn)), (!cast<Instruction>(INST # v1i64) $Rn)>;
6620+
6621+ let Predicates = [HasFPRCVT] in {
6622+ def : Pat<(f32 (bitconvert (i32 (round f16:$Rn)))),
6623+ (!cast<Instruction>(INST # SHr) $Rn)>;
6624+ def : Pat<(f64 (bitconvert (i64 (round f16:$Rn)))),
6625+ (!cast<Instruction>(INST # DHr) $Rn)>;
6626+ def : Pat<(f64 (bitconvert (i64 (round f32:$Rn)))),
6627+ (!cast<Instruction>(INST # DSr) $Rn)>;
6628+ def : Pat<(f32 (bitconvert (i32 (round f64:$Rn)))),
6629+ (!cast<Instruction>(INST # SDr) $Rn)>;
6630+ }
6631+ def : Pat<(f32 (bitconvert (i32 (round f32:$Rn)))),
6632+ (!cast<Instruction>(INST # v1i32) $Rn)>;
6633+ def : Pat<(f64 (bitconvert (i64 (round f64:$Rn)))),
6634+ (!cast<Instruction>(INST # v1i64) $Rn)>;
6635+
6636+ let Predicates = [HasFullFP16] in {
6637+ def : Pat<(i32 (round (fmul f16:$Rn, fixedpoint_f16_i32:$scale))),
6638+ (!cast<Instruction>(INST # SWHri) $Rn, $scale)>;
6639+ def : Pat<(i64 (round (fmul f16:$Rn, fixedpoint_f16_i64:$scale))),
6640+ (!cast<Instruction>(INST # SXHri) $Rn, $scale)>;
6641+ }
6642+ def : Pat<(i32 (round (fmul f32:$Rn, fixedpoint_f32_i32:$scale))),
6643+ (!cast<Instruction>(INST # SWSri) $Rn, $scale)>;
6644+ def : Pat<(i64 (round (fmul f32:$Rn, fixedpoint_f32_i64:$scale))),
6645+ (!cast<Instruction>(INST # SXSri) $Rn, $scale)>;
6646+ def : Pat<(i32 (round (fmul f64:$Rn, fixedpoint_f64_i32:$scale))),
6647+ (!cast<Instruction>(INST # SWDri) $Rn, $scale)>;
6648+ def : Pat<(i64 (round (fmul f64:$Rn, fixedpoint_f64_i64:$scale))),
6649+ (!cast<Instruction>(INST # SXDri) $Rn, $scale)>;
6650+ }
6651+
6652+ defm : FPToIntegerIntPats<int_aarch64_neon_fcvtzs, "FCVTZS">;
6653+ defm : FPToIntegerIntPats<int_aarch64_neon_fcvtzu, "FCVTZU">;
6654+
66036655// f16 -> s16 conversions
66046656let Predicates = [HasFullFP16] in {
66056657 def : Pat<(i16(fp_to_sint_sat_gi f16:$Rn)), (FCVTZSv1f16 f16:$Rn)>;
0 commit comments