Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -4746,6 +4746,16 @@ def : Pat<(v2f64 (AArch64frsqrts (v2f64 FPR128:$Rn), (v2f64 FPR128:$Rm))), (FRSQRTSv2f64 FPR128:$Rn, FPR128:$Rm)>; +// Some float -> int -> float conversion patterns for which we want to keep the +// int values in FP registers using the corresponding NEON instructions to +// avoid more costly int <-> fp register transfers. +def : Pat<(f64 (sint_to_fp (i64 (fp_to_sint f64:$Rn)))), + (SCVTFv1i64 (i64 (FCVTZSv1i64 f64:$Rn)))>; +def : Pat<(f32 (sint_to_fp (i32 (fp_to_sint f32:$Rn)))), + (SCVTFv1i32 (i32 (FCVTZSv1i32 f32:$Rn)))>; +def : Pat<(f16 (sint_to_fp (i32 (fp_to_sint f16:$Rn)))), + (SCVTFv1i16 (f16 (FCVTZSv1f16 f16:$Rn)))>; + // If an integer is about to be converted to a floating point value, // just load it on the floating point unit. // Here are the patterns for 8 and 16-bits to float. Index: llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll =================================================================== --- llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll +++ llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll @@ -4,8 +4,8 @@ define double @t1(double %x) { ; CHECK-LABEL: t1: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: fcvtzs x8, d0 -; CHECK-NEXT: scvtf d0, x8 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: scvtf d0, d0 ; CHECK-NEXT: ret entry: %conv = fptosi double %x to i64 @@ -16,8 +16,8 @@ define float @t2(float %x) { ; CHECK-LABEL: t2: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: fcvtzs w8, s0 -; CHECK-NEXT: scvtf s0, w8 +; CHECK-NEXT: fcvtzs s0, s0 +; CHECK-NEXT: scvtf s0, s0 ; CHECK-NEXT: ret entry: %conv = fptosi float %x to i32 @@ -29,8 +29,8 @@ ; CHECK-LABEL: t3: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: fcvtzs w8, s0 -; CHECK-NEXT: scvtf s0, w8 +; CHECK-NEXT: fcvtzs s0, s0 +; CHECK-NEXT: scvtf s0, s0 ; CHECK-NEXT: fcvt h0, s0 ; CHECK-NEXT: ret entry: