[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