[llvm] [AArch64][llvm] Pre-commit tests for new fpcvt codegen (PR #173272)

Jonathan Thackray via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 6 02:33:06 PST 2026


https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/173272

>From d5bff825fe714b8b0080034ff79cc13293aa9bd8 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Mon, 22 Dec 2025 14:17:52 +0000
Subject: [PATCH 1/3] [AArch64][llvm] Pre-commit tests for new fpcvt codegen

---
 .../AArch64/arm64-cvtf-simd-intrinsics.ll     | 134 ++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll

diff --git a/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll b/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
new file mode 100644
index 0000000000000..a31ed1c9729f0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
@@ -0,0 +1,134 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=aarch64-unknown-unknown -mattr=+neon,+fullfp16,+fprcvt | FileCheck %s --check-prefixes=CHECK
+
+define double @scvtf_bitcast_f32_to_f64(float %f) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f32_to_f64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    scvtf d0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = sitofp i32 %i to double
+  ret double %r
+}
+
+define double @ucvtf_bitcast_f32_to_f64(float %f) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f32_to_f64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    ucvtf d0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = uitofp i32 %i to double
+  ret double %r
+}
+
+define half @scvtf_bitcast_f32_to_f16(float %f) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f32_to_f16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    scvtf h0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = sitofp i32 %i to half
+  ret half %r
+}
+
+define half @ucvtf_bitcast_f32_to_f16(float %f) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f32_to_f16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    ucvtf h0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = uitofp i32 %i to half
+  ret half %r
+}
+
+define float @scvtf_bitcast_f64_to_f32(double %d) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f64_to_f32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    scvtf s0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = sitofp i64 %i to float
+  ret float %r
+}
+
+define float @ucvtf_bitcast_f64_to_f32(double %d) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f64_to_f32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    ucvtf s0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = uitofp i64 %i to float
+  ret float %r
+}
+
+define half @scvtf_bitcast_f64_to_f16(double %d) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f64_to_f16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    scvtf h0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = sitofp i64 %i to half
+  ret half %r
+}
+
+define half @ucvtf_bitcast_f64_to_f16(double %d) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f64_to_f16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    ucvtf h0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = uitofp i64 %i to half
+  ret half %r
+}
+
+define float @scvtf_bitcast_f32_to_f32(float %f) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f32_to_f32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    scvtf s0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = sitofp i32 %i to float
+  ret float %r
+}
+
+define float @ucvtf_bitcast_f32_to_f32(float %f) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f32_to_f32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    ucvtf s0, w8
+; CHECK-NEXT:    ret
+  %i = bitcast float %f to i32
+  %r = uitofp i32 %i to float
+  ret float %r
+}
+
+define double @scvtf_bitcast_f64_to_f64(double %d) nounwind {
+; CHECK-LABEL: scvtf_bitcast_f64_to_f64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    scvtf d0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = sitofp i64 %i to double
+  ret double %r
+}
+
+define double @ucvtf_bitcast_f64_to_f64(double %d) nounwind {
+; CHECK-LABEL: ucvtf_bitcast_f64_to_f64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov x8, d0
+; CHECK-NEXT:    ucvtf d0, x8
+; CHECK-NEXT:    ret
+  %i = bitcast double %d to i64
+  %r = uitofp i64 %i to double
+  ret double %r
+}

>From 76b59ddb5d2316268bf196b3d174645784db38b2 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 18 Dec 2025 14:28:38 +0000
Subject: [PATCH 2/3] [AArch64][llvm] Add codegen for simd fpcvt intrinsics

Add tablegen patterns to provide codegen for SCVTF and UCVTF
operating purely on SIMD & FP registers, using explicit bitcasts.
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   | 20 +++++++++++
 .../AArch64/arm64-cvtf-simd-intrinsics.ll     | 36 +++++++------------
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 64b55ee8f0d38..f120f1c1e72f8 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6556,6 +6556,26 @@ defm UQXTN  : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
 defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd",
                                     int_aarch64_neon_usqadd>;
 
+// Floating-point conversion patterns.
+multiclass IntegerToFPSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
+  let Predicates = [HasFPRCVT] in {
+  def : Pat<(f64 (OpN (i32 (bitconvert (f32 FPR32:$Rn))))),
+            (!cast<Instruction>(INST # DSr) FPR32:$Rn)>;
+  def : Pat<(f16 (OpN (i32 (bitconvert (f32 FPR32:$Rn))))),
+            (!cast<Instruction>(INST # HSr) FPR32:$Rn)>;
+  def : Pat<(f16 (OpN (i64 (bitconvert (f64 FPR64:$Rn))))),
+            (!cast<Instruction>(INST # HDr) FPR64:$Rn)>;
+  def : Pat<(f32 (OpN (i64 (bitconvert (f64 FPR64:$Rn))))),
+            (!cast<Instruction>(INST # SDr) FPR64:$Rn)>;
+  }
+  def : Pat<(f32 (OpN (i32 (bitconvert (f32 FPR32:$Rn))))),
+            (!cast<Instruction>(INST # v1i32) FPR32:$Rn)>;
+  def : Pat<(f64 (OpN (i64 (bitconvert (f64 FPR64:$Rn))))),
+            (!cast<Instruction>(INST # v1i64) FPR64:$Rn)>;
+}
+defm : IntegerToFPSIMDScalarPatterns<sint_to_fp, "SCVTF">;
+defm : IntegerToFPSIMDScalarPatterns<uint_to_fp, "UCVTF">;
+
 // Floating-point conversion patterns.
 multiclass FPToIntegerSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
   let Predicates = [HasFPRCVT] in {
diff --git a/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll b/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
index a31ed1c9729f0..35667d058b6fd 100644
--- a/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
@@ -4,8 +4,7 @@
 define double @scvtf_bitcast_f32_to_f64(float %f) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f32_to_f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    scvtf d0, w8
+; CHECK-NEXT:    scvtf d0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = sitofp i32 %i to double
@@ -15,8 +14,7 @@ define double @scvtf_bitcast_f32_to_f64(float %f) nounwind {
 define double @ucvtf_bitcast_f32_to_f64(float %f) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f32_to_f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    ucvtf d0, w8
+; CHECK-NEXT:    ucvtf d0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = uitofp i32 %i to double
@@ -26,8 +24,7 @@ define double @ucvtf_bitcast_f32_to_f64(float %f) nounwind {
 define half @scvtf_bitcast_f32_to_f16(float %f) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f32_to_f16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    scvtf h0, w8
+; CHECK-NEXT:    scvtf h0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = sitofp i32 %i to half
@@ -37,8 +34,7 @@ define half @scvtf_bitcast_f32_to_f16(float %f) nounwind {
 define half @ucvtf_bitcast_f32_to_f16(float %f) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f32_to_f16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    ucvtf h0, w8
+; CHECK-NEXT:    ucvtf h0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = uitofp i32 %i to half
@@ -48,8 +44,7 @@ define half @ucvtf_bitcast_f32_to_f16(float %f) nounwind {
 define float @scvtf_bitcast_f64_to_f32(double %d) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f64_to_f32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    scvtf s0, x8
+; CHECK-NEXT:    scvtf s0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = sitofp i64 %i to float
@@ -59,8 +54,7 @@ define float @scvtf_bitcast_f64_to_f32(double %d) nounwind {
 define float @ucvtf_bitcast_f64_to_f32(double %d) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f64_to_f32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    ucvtf s0, x8
+; CHECK-NEXT:    ucvtf s0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = uitofp i64 %i to float
@@ -70,8 +64,7 @@ define float @ucvtf_bitcast_f64_to_f32(double %d) nounwind {
 define half @scvtf_bitcast_f64_to_f16(double %d) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f64_to_f16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    scvtf h0, x8
+; CHECK-NEXT:    scvtf h0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = sitofp i64 %i to half
@@ -81,8 +74,7 @@ define half @scvtf_bitcast_f64_to_f16(double %d) nounwind {
 define half @ucvtf_bitcast_f64_to_f16(double %d) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f64_to_f16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    ucvtf h0, x8
+; CHECK-NEXT:    ucvtf h0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = uitofp i64 %i to half
@@ -92,8 +84,7 @@ define half @ucvtf_bitcast_f64_to_f16(double %d) nounwind {
 define float @scvtf_bitcast_f32_to_f32(float %f) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f32_to_f32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    scvtf s0, w8
+; CHECK-NEXT:    scvtf s0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = sitofp i32 %i to float
@@ -103,8 +94,7 @@ define float @scvtf_bitcast_f32_to_f32(float %f) nounwind {
 define float @ucvtf_bitcast_f32_to_f32(float %f) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f32_to_f32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov w8, s0
-; CHECK-NEXT:    ucvtf s0, w8
+; CHECK-NEXT:    ucvtf s0, s0
 ; CHECK-NEXT:    ret
   %i = bitcast float %f to i32
   %r = uitofp i32 %i to float
@@ -114,8 +104,7 @@ define float @ucvtf_bitcast_f32_to_f32(float %f) nounwind {
 define double @scvtf_bitcast_f64_to_f64(double %d) nounwind {
 ; CHECK-LABEL: scvtf_bitcast_f64_to_f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    scvtf d0, x8
+; CHECK-NEXT:    scvtf d0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = sitofp i64 %i to double
@@ -125,8 +114,7 @@ define double @scvtf_bitcast_f64_to_f64(double %d) nounwind {
 define double @ucvtf_bitcast_f64_to_f64(double %d) nounwind {
 ; CHECK-LABEL: ucvtf_bitcast_f64_to_f64:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    fmov x8, d0
-; CHECK-NEXT:    ucvtf d0, x8
+; CHECK-NEXT:    ucvtf d0, d0
 ; CHECK-NEXT:    ret
   %i = bitcast double %d to i64
   %r = uitofp i64 %i to double

>From bf83b602f7a49fc9d274ac63a31475ff6202d03f Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Tue, 6 Jan 2026 10:31:28 +0000
Subject: [PATCH 3/3] fixup! [AArch64][llvm] Add codegen for simd fpcvt
 intrinsics

Minor CR comments fixes
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.td                   | 4 ++--
 ...arm64-cvtf-simd-intrinsics.ll => arm64-cvtf-simd-fptoi.ll} | 0
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename llvm/test/CodeGen/AArch64/{arm64-cvtf-simd-intrinsics.ll => arm64-cvtf-simd-fptoi.ll} (100%)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index f120f1c1e72f8..a26219074a908 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6573,8 +6573,8 @@ multiclass IntegerToFPSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
   def : Pat<(f64 (OpN (i64 (bitconvert (f64 FPR64:$Rn))))),
             (!cast<Instruction>(INST # v1i64) FPR64:$Rn)>;
 }
-defm : IntegerToFPSIMDScalarPatterns<sint_to_fp, "SCVTF">;
-defm : IntegerToFPSIMDScalarPatterns<uint_to_fp, "UCVTF">;
+defm : IntegerToFPSIMDScalarPatterns<any_sint_to_fp, "SCVTF">;
+defm : IntegerToFPSIMDScalarPatterns<any_uint_to_fp, "UCVTF">;
 
 // Floating-point conversion patterns.
 multiclass FPToIntegerSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
diff --git a/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll b/llvm/test/CodeGen/AArch64/arm64-cvtf-simd-fptoi.ll
similarity index 100%
rename from llvm/test/CodeGen/AArch64/arm64-cvtf-simd-intrinsics.ll
rename to llvm/test/CodeGen/AArch64/arm64-cvtf-simd-fptoi.ll



More information about the llvm-commits mailing list