@@ -5231,18 +5231,19 @@ defm FCVTZS : FPToIntegerScaled<0b11, 0b000, "fcvtzs", any_fp_to_sint>;
5231
5231
defm FCVTZU : FPToIntegerScaled<0b11, 0b001, "fcvtzu", any_fp_to_uint>;
5232
5232
5233
5233
let 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 >;
5242
5242
defm FCVTZS : FPToIntegerSIMDScalar<0b10, 0b110, "fcvtzs">;
5243
5243
defm FCVTZU : FPToIntegerSIMDScalar<0b10, 0b111, "fcvtzu">;
5244
5244
}
5245
5245
5246
+
5246
5247
// AArch64's FCVT instructions saturate when out of range.
5247
5248
multiclass FPToIntegerSatPats<SDNode to_int_sat, SDNode to_int_sat_gi, string INST> {
5248
5249
let Predicates = [HasFullFP16] in {
@@ -5309,35 +5310,6 @@ multiclass FPToIntegerSatPats<SDNode to_int_sat, SDNode to_int_sat_gi, string IN
5309
5310
defm : FPToIntegerSatPats<fp_to_sint_sat, fp_to_sint_sat_gi, "FCVTZS">;
5310
5311
defm : FPToIntegerSatPats<fp_to_uint_sat, fp_to_uint_sat_gi, "FCVTZU">;
5311
5312
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
-
5341
5313
multiclass FPToIntegerPats<SDNode to_int, SDNode to_int_sat, SDNode round, string INST> {
5342
5314
def : Pat<(i32 (to_int (round f32:$Rn))),
5343
5315
(!cast<Instruction>(INST # UWSr) f32:$Rn)>;
@@ -6572,14 +6544,14 @@ defm FCMGE : SIMDFPCmpTwoScalar<1, 1, 0b01100, "fcmge", AArch64fcmgez>;
6572
6544
defm FCMGT : SIMDFPCmpTwoScalar<0, 1, 0b01100, "fcmgt", AArch64fcmgtz>;
6573
6545
defm FCMLE : SIMDFPCmpTwoScalar<1, 1, 0b01101, "fcmle", AArch64fcmlez>;
6574
6546
defm 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 >;
6583
6555
def FCVTXNv1i64 : SIMDInexactCvtTwoScalar<0b10110, "fcvtxn">;
6584
6556
defm FCVTZS : SIMDFPTwoScalar< 0, 1, 0b11011, "fcvtzs">;
6585
6557
defm FCVTZU : SIMDFPTwoScalar< 1, 1, 0b11011, "fcvtzu">;
@@ -6600,6 +6572,86 @@ defm UQXTN : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
6600
6572
defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd",
6601
6573
int_aarch64_neon_usqadd>;
6602
6574
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
+
6603
6655
// f16 -> s16 conversions
6604
6656
let Predicates = [HasFullFP16] in {
6605
6657
def : Pat<(i16(fp_to_sint_sat_gi f16:$Rn)), (FCVTZSv1f16 f16:$Rn)>;
0 commit comments