[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 04:04:05 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/8] [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/8] [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/8] [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/8] [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/8] [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/8] [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

>From a83ecd5603fcdedf93ebff008430f390d52852a0 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 17 Feb 2026 11:56:29 +0000
Subject: [PATCH 7/8] [AArch64][GlobalISel] Move fp16 -> i16 test checks into
 fp16 test file

fp16 -> i16 checks were previously placed in a separate file due to GlobalISel being unable to select the intrinsics.
Now, place these tests into the master file.
---
 .../AArch64/fp16_i16_intrinsic_scalar.ll      | 136 ------------------
 .../AArch64/fp16_intrinsic_scalar_1op.ll      | 110 ++++++++++++++
 2 files changed, 110 insertions(+), 136 deletions(-)
 delete mode 100644 llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll

diff --git a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll b/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
deleted file mode 100644
index 9260695d851fe..0000000000000
--- a/llvm/test/CodeGen/AArch64/fp16_i16_intrinsic_scalar.ll
+++ /dev/null
@@ -1,136 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; 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
-; 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)
-declare i16 @llvm.aarch64.neon.fcvtau.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtms.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtmu.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtns.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtnu.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtps.i16.f16(half)
-declare i16 @llvm.aarch64.neon.fcvtpu.i16.f16(half)
-
-
-define i16 @fcvtzs_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtzs_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtzs h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtzu_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtzu_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtzu h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtas_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtas_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtas h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtas.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtau_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtau_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtau h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtau.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtms_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtms_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtms h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtms.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtmu_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtmu_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtmu h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtmu.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtns_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtns_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtns h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtns.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtnu_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtnu_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtnu h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtnu.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtps_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtps_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtps h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtps.i16.f16(half %a)
-  ret i16 %fcvt
-}
-
-define i16 @fcvtpu_intrinsic_i16(half %a) {
-; CHECK-LABEL: fcvtpu_intrinsic_i16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvtpu h0, h0
-; CHECK-NEXT:    fmov w0, s0
-; CHECK-NEXT:    ret
-entry:
-  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtpu.i16.f16(half %a)
-  ret i16 %fcvt
-}
diff --git a/llvm/test/CodeGen/AArch64/fp16_intrinsic_scalar_1op.ll b/llvm/test/CodeGen/AArch64/fp16_intrinsic_scalar_1op.ll
index b056460153b29..5ccf7b1adc3a7 100644
--- a/llvm/test/CodeGen/AArch64/fp16_intrinsic_scalar_1op.ll
+++ b/llvm/test/CodeGen/AArch64/fp16_intrinsic_scalar_1op.ll
@@ -196,6 +196,17 @@ entry:
   ret i64 %0
 }
 
+define i16 @fcvtzu_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtzu_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzu h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtzu.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define i32 @fcvtzu_intrinsic_i32(half %a) {
 ; CHECK-LABEL: fcvtzu_intrinsic_i32:
 ; CHECK:       // %bb.0: // %entry
@@ -216,6 +227,17 @@ entry:
   ret i64 %fcvt
 }
 
+define i16 @fcvtzs_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtzs_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtzs.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define i32 @fcvtzs_intrinsic_i32(half %a) {
 ; CHECK-LABEL: fcvtzs_intrinsic_i32:
 ; CHECK:       // %bb.0: // %entry
@@ -236,6 +258,17 @@ entry:
   ret i64 %fcvt
 }
 
+define i16 @fcvtas_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtas_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtas h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtas.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t19(half %a) {
 ; CHECK-LABEL: t19:
 ; CHECK:       // %bb.0: // %entry
@@ -257,6 +290,17 @@ entry:
   ret i64 %vcvtah_s64_f16
 }
 
+define i16 @fcvtau_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtau_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtau h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtau.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t22(half %a) {
 ; CHECK-LABEL: t22:
 ; CHECK:       // %bb.0: // %entry
@@ -278,6 +322,17 @@ entry:
   ret i64 %vcvtah_u64_f16
 }
 
+define i16 @fcvtms_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtms_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtms h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtms.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t25(half %a) {
 ; CHECK-LABEL: t25:
 ; CHECK:       // %bb.0: // %entry
@@ -299,6 +354,17 @@ entry:
   ret i64 %vcvtmh_s64_f16
 }
 
+define i16 @fcvtmu_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtmu_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtmu h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtmu.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t28(half %a) {
 ; CHECK-LABEL: t28:
 ; CHECK:       // %bb.0: // %entry
@@ -320,6 +386,17 @@ entry:
   ret i64 %vcvtmh_u64_f16
 }
 
+define i16 @fcvtns_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtns_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtns h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtns.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t31(half %a) {
 ; CHECK-LABEL: t31:
 ; CHECK:       // %bb.0: // %entry
@@ -341,6 +418,17 @@ entry:
   ret i64 %vcvtnh_s64_f16
 }
 
+define i16 @fcvtnu_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtnu_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtnu h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtnu.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t34(half %a) {
 ; CHECK-LABEL: t34:
 ; CHECK:       // %bb.0: // %entry
@@ -362,6 +450,17 @@ entry:
   ret i64 %vcvtnh_u64_f16
 }
 
+define i16 @fcvtps_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtps_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtps h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtps.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t37(half %a) {
 ; CHECK-LABEL: t37:
 ; CHECK:       // %bb.0: // %entry
@@ -383,6 +482,17 @@ entry:
   ret i64 %vcvtph_s64_f16
 }
 
+define i16 @fcvtpu_intrinsic_i16(half %a) {
+; CHECK-LABEL: fcvtpu_intrinsic_i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtpu h0, h0
+; CHECK-NEXT:    fmov w0, s0
+; CHECK-NEXT:    ret
+entry:
+  %fcvt = tail call i16 @llvm.aarch64.neon.fcvtpu.i16.f16(half %a)
+  ret i16 %fcvt
+}
+
 define dso_local i16 @t40(half %a) {
 ; CHECK-LABEL: t40:
 ; CHECK:       // %bb.0: // %entry

>From 96f2a59b1e23e69ed6788449412959aeffef2c42 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 17 Feb 2026 12:03:47 +0000
Subject: [PATCH 8/8] [AArch64][GlobalISel] Remove unnecessary brackets

---
 llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 2e6e8722ee0e8..6874a881fd859 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -1240,8 +1240,8 @@ 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 == 16) ||
-          (((DstSize == SrcSize) || STI.hasFeature(AArch64::FeatureFPRCVT)) &&
+      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) ||



More information about the llvm-commits mailing list