[llvm] fba17cd - [AArch64] Guard fptosi+sitofp patterns with one use checks. (#156407)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 00:21:31 PDT 2025
Author: David Green
Date: 2025-09-03T08:21:27+01:00
New Revision: fba17cdee1830951867ecfc7d40f7b6caa78310a
URL: https://github.com/llvm/llvm-project/commit/fba17cdee1830951867ecfc7d40f7b6caa78310a
DIFF: https://github.com/llvm/llvm-project/commit/fba17cdee1830951867ecfc7d40f7b6caa78310a.diff
LOG: [AArch64] Guard fptosi+sitofp patterns with one use checks. (#156407)
Otherwise we can end up with more instructions, needing to emit both
`fcvtzu w0, s0` and `fcvtzu s0, s0`.
Added:
Modified:
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index ce40e202f30f5..62b26b5239365 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6706,20 +6706,24 @@ def : Pat<(v2f64 (AArch64frsqrts (v2f64 FPR128:$Rn), (v2f64 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.
+let HasOneUse = 1 in {
+def any_fp_to_sint_oneuse: PatFrag<(ops node:$src0), (any_fp_to_sint $src0)>;
+def any_fp_to_uint_oneuse: PatFrag<(ops node:$src0), (any_fp_to_uint $src0)>;
+}
let Predicates = [HasNEONandIsSME2p2StreamingSafe] in {
-def : Pat<(f64 (any_sint_to_fp (i64 (any_fp_to_sint f64:$Rn)))),
+def : Pat<(f64 (any_sint_to_fp (i64 (any_fp_to_sint_oneuse f64:$Rn)))),
(SCVTFv1i64 (i64 (FCVTZSv1i64 f64:$Rn)))>;
-def : Pat<(f32 (any_sint_to_fp (i32 (any_fp_to_sint f32:$Rn)))),
+def : Pat<(f32 (any_sint_to_fp (i32 (any_fp_to_sint_oneuse f32:$Rn)))),
(SCVTFv1i32 (i32 (FCVTZSv1i32 f32:$Rn)))>;
-def : Pat<(f64 (any_uint_to_fp (i64 (any_fp_to_uint f64:$Rn)))),
+def : Pat<(f64 (any_uint_to_fp (i64 (any_fp_to_uint_oneuse f64:$Rn)))),
(UCVTFv1i64 (i64 (FCVTZUv1i64 f64:$Rn)))>;
-def : Pat<(f32 (any_uint_to_fp (i32 (any_fp_to_uint f32:$Rn)))),
+def : Pat<(f32 (any_uint_to_fp (i32 (any_fp_to_uint_oneuse f32:$Rn)))),
(UCVTFv1i32 (i32 (FCVTZUv1i32 f32:$Rn)))>;
let Predicates = [HasNEONandIsSME2p2StreamingSafe, HasFullFP16] in {
-def : Pat<(f16 (any_sint_to_fp (i32 (any_fp_to_sint f16:$Rn)))),
+def : Pat<(f16 (any_sint_to_fp (i32 (any_fp_to_sint_oneuse f16:$Rn)))),
(SCVTFv1i16 (f16 (FCVTZSv1f16 f16:$Rn)))>;
-def : Pat<(f16 (any_uint_to_fp (i32 (any_fp_to_uint f16:$Rn)))),
+def : Pat<(f16 (any_uint_to_fp (i32 (any_fp_to_uint_oneuse f16:$Rn)))),
(UCVTFv1i16 (f16 (FCVTZUv1f16 f16:$Rn)))>;
}
diff --git a/llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll b/llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll
index d4caf64294f45..1207de746894b 100644
--- a/llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll
+++ b/llvm/test/CodeGen/AArch64/cvt-fp-int-fp.ll
@@ -122,9 +122,8 @@ entry:
define i64 @testu_f64_multiuse(double %x) {
; CHECK-LABEL: testu_f64_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzu d1, d0
; CHECK-NEXT: fcvtzu x8, d0
-; CHECK-NEXT: ucvtf d1, d1
+; CHECK-NEXT: ucvtf d1, x8
; CHECK-NEXT: fcmp d0, d1
; CHECK-NEXT: csel x0, x8, xzr, eq
; CHECK-NEXT: ret
@@ -139,9 +138,8 @@ entry:
define i32 @testu_f32_multiuse(float %x) {
; CHECK-LABEL: testu_f32_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzu s1, s0
; CHECK-NEXT: fcvtzu w8, s0
-; CHECK-NEXT: ucvtf s1, s1
+; CHECK-NEXT: ucvtf s1, w8
; CHECK-NEXT: fcmp s0, s1
; CHECK-NEXT: csel w0, w8, wzr, eq
; CHECK-NEXT: ret
@@ -156,9 +154,8 @@ entry:
define i32 @testu_f16_multiuse(half %x) {
; CHECK-LABEL: testu_f16_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzu h1, h0
; CHECK-NEXT: fcvtzu w8, h0
-; CHECK-NEXT: ucvtf h1, h1
+; CHECK-NEXT: ucvtf h1, w8
; CHECK-NEXT: fcmp h0, h1
; CHECK-NEXT: csel w0, w8, wzr, eq
; CHECK-NEXT: ret
@@ -173,9 +170,8 @@ entry:
define i64 @tests_f64_multiuse(double %x) {
; CHECK-LABEL: tests_f64_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzs d1, d0
; CHECK-NEXT: fcvtzs x8, d0
-; CHECK-NEXT: scvtf d1, d1
+; CHECK-NEXT: scvtf d1, x8
; CHECK-NEXT: fcmp d0, d1
; CHECK-NEXT: csel x0, x8, xzr, eq
; CHECK-NEXT: ret
@@ -190,9 +186,8 @@ entry:
define i32 @tests_f32_multiuse(float %x) {
; CHECK-LABEL: tests_f32_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzs s1, s0
; CHECK-NEXT: fcvtzs w8, s0
-; CHECK-NEXT: scvtf s1, s1
+; CHECK-NEXT: scvtf s1, w8
; CHECK-NEXT: fcmp s0, s1
; CHECK-NEXT: csel w0, w8, wzr, eq
; CHECK-NEXT: ret
@@ -207,9 +202,8 @@ entry:
define i32 @tests_f16_multiuse(half %x) {
; CHECK-LABEL: tests_f16_multiuse:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: fcvtzs h1, h0
; CHECK-NEXT: fcvtzs w8, h0
-; CHECK-NEXT: scvtf h1, h1
+; CHECK-NEXT: scvtf h1, w8
; CHECK-NEXT: fcmp h0, h1
; CHECK-NEXT: csel w0, w8, wzr, eq
; CHECK-NEXT: ret
More information about the llvm-commits
mailing list