[llvm] [AArch64][GlobalISel] Remove fallbacks for fpcvt intrinsics with 16-bit operands (PR #179693)

Joshua Rodriguez via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 17 02:13:27 PST 2026


https://github.com/JoshdRod updated https://github.com/llvm/llvm-project/pull/179693

>From 7fe8de514703d6e31f1d4351bc8aeee357c73434 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Wed, 4 Feb 2026 15:34:46 +0000
Subject: [PATCH 1/6] [AArch64][GlobalISel] Include GlobalISel fallbacks in
 scalar f16 -> i16 intrinsics test

---
 .../CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll  | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
index ab502508fadbd..30a6488f78ecf 100644
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
@@ -1,10 +1,23 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=aarch64 -global-isel=0 -mattr=+v8.2a,+fullfp16  | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64 -mattr=+v8.2a,+fullfp16  | FileCheck %s --check-prefixes=CHECK,CHECK-SD
+; RUN: llc < %s -mtriple=aarch64 -global-isel --global-isel-abort=2 -mattr=+v8.2a,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
 ; Test f16 -> i16 NEON intrinics, currently only supported in SDAG.
 ; Should be merged with fp16_intrinsic_scalar_1op.ll once there is
 ; support in GlSel.
 
+; CHECK-GI:    warning: Instruction selection used fallback path for fcvtzs_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtzu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtas_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtau_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtms_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtmu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtns_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtnu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtps_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtpu_intrinsic_i16
+
+
 declare i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtas.i16.f16(half)

>From 06f35e79836c4b6a85cbbecb5bfaf024532dda1f Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Fri, 6 Feb 2026 10:11:44 +0000
Subject: [PATCH 2/6] [AArch64][GloballISel] Put result of fp16 -> s16 convert
 intrinsic on fpr

Previously, RegBankSelect would place the result of an fp16 -> s16 conversion intrinsic on a gpr. This would cause Instruction Selection to fail, as there are no 16-bit gprs.
Floating point convert intrinsics affected:
fcvtnu / fcvtns
fcvtau / fcvtas
fcvtmu / fcvtms
fcvtpu / fcvtps
---
 .../AArch64/GISel/AArch64RegisterBankInfo.cpp       | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index f8b5739d1d13a..2e6e8722ee0e8 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -1240,12 +1240,13 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
       }
       TypeSize DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
       TypeSize SrcSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, TRI);
-      if (((DstSize == SrcSize) || STI.hasFeature(AArch64::FeatureFPRCVT)) &&
-          all_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
-                 [&](const MachineInstr &UseMI) {
-                   return onlyUsesFP(UseMI, MRI, TRI) ||
-                          prefersFPUse(UseMI, MRI, TRI);
-                 }))
+      if ((DstSize == 16) ||
+          (((DstSize == SrcSize) || STI.hasFeature(AArch64::FeatureFPRCVT)) &&
+           all_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
+                  [&](const MachineInstr &UseMI) {
+                    return onlyUsesFP(UseMI, MRI, TRI) ||
+                           prefersFPUse(UseMI, MRI, TRI);
+                  })))
         OpRegBankIdx[0] = PMI_FirstFPR;
       else
         OpRegBankIdx[0] = PMI_FirstGPR;

>From a815330f276e292d28728c58b1463f1bb4509d47 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Fri, 6 Feb 2026 11:27:55 +0000
Subject: [PATCH 3/6] [AArch64][GlobalIsel] Update test checks

---
 llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
index 30a6488f78ecf..0069edc2fcb2c 100644
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
@@ -8,15 +8,6 @@
 
 ; CHECK-GI:    warning: Instruction selection used fallback path for fcvtzs_intrinsic_i16
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtzu_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtas_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtau_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtms_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtmu_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtns_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtnu_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtps_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtpu_intrinsic_i16
-
 
 declare i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half)

>From eefef323dbb5fe7c84bb6d019e07a4a25b601bc0 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 10 Feb 2026 15:40:23 +0000
Subject: [PATCH 4/6] [AArch64][GlobalISel] Legalise FCVTZ<U/S> intrinsics to
 G_FPTO<U/S>I_SAT

At the Instruction Selection stage, the AArch64 patterns match this G_GPTOUI_SAT node to the FCVTZU intrinsic. Hence, we must legalise the ACLE intrinsic to this node.
---
 llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 4 ++++
 llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll | 3 ---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 62f8237dc3b6b..06f853354c342 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -2015,6 +2015,10 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_U);
   case Intrinsic::aarch64_neon_uqxtn:
     return LowerUnaryOp(TargetOpcode::G_TRUNC_USAT_U);
+  case Intrinsic::aarch64_neon_fcvtzu:
+    return LowerUnaryOp(TargetOpcode::G_FPTOUI_SAT);
+  case Intrinsic::aarch64_neon_fcvtzs:
+    return LowerUnaryOp(TargetOpcode::G_FPTOSI_SAT);
 
   case Intrinsic::vector_reverse:
     // TODO: Add support for vector_reverse
diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
index 0069edc2fcb2c..a7640e79997cc 100644
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
@@ -6,9 +6,6 @@
 ; Should be merged with fp16_intrinsic_scalar_1op.ll once there is
 ; support in GlSel.
 
-; CHECK-GI:    warning: Instruction selection used fallback path for fcvtzs_intrinsic_i16
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtzu_intrinsic_i16
-
 declare i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtas.i16.f16(half)

>From 7855a95d9981254f7eaff8fba561cfab46442839 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Wed, 4 Feb 2026 15:34:46 +0000
Subject: [PATCH 5/6] [AArch64][GloballISel] Put result of fp16 -> s16 convert
 intrinsic on fpr

Previously, RegBankSelect would place the result of an fp16 -> s16 conversion intrinsic on a gpr. This would cause Instruction Selection to fail, as there are no 16-bit gprs.
Floating point convert intrinsics affected:
fcvtnu / fcvtns
fcvtau / fcvtas
fcvtmu / fcvtms
fcvtpu / fcvtps
---
 .../CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll     | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
index a7640e79997cc..30a6488f78ecf 100644
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
@@ -6,6 +6,18 @@
 ; Should be merged with fp16_intrinsic_scalar_1op.ll once there is
 ; support in GlSel.
 
+; CHECK-GI:    warning: Instruction selection used fallback path for fcvtzs_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtzu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtas_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtau_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtms_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtmu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtns_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtnu_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtps_intrinsic_i16
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtpu_intrinsic_i16
+
+
 declare i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half)
 declare i16 @llvm.aarch64.neon.fcvtas.i16.f16(half)

>From c9ca2195ea91b5a96985a7f5ce9ab8201468c1b8 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 17 Feb 2026 10:01:23 +0000
Subject: [PATCH 6/6] [AArch64][GlobalISel] Merge SDAG check into GlobalISel
 check

As GlobalISel no longer fails to lower these intrinsics, and SDAG and GI generated code is identical, the two test checks can safely be merged into one.
---
 llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
index 30a6488f78ecf..9260695d851fe 100644
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
@@ -1,10 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=aarch64 -mattr=+v8.2a,+fullfp16  | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc < %s -mtriple=aarch64 -global-isel --global-isel-abort=2 -mattr=+v8.2a,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
-
-; Test f16 -> i16 NEON intrinics, currently only supported in SDAG.
-; Should be merged with fp16_intrinsic_scalar_1op.ll once there is
-; support in GlSel.
+; RUN: llc < %s -mtriple=aarch64 -global-isel --global-isel-abort=2 -mattr=+v8.2a,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK
 
 ; CHECK-GI:    warning: Instruction selection used fallback path for fcvtzs_intrinsic_i16
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for fcvtzu_intrinsic_i16



More information about the llvm-commits mailing list