[llvm] [AArch64][GlobalISel] Add pattern to prevent scalar uqxtn fallback (PR #201546)

Joshua Rodriguez via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 4 03:59:38 PDT 2026


https://github.com/JoshdRod created https://github.com/llvm/llvm-project/pull/201546

Previously, attempting to select the intrinsic @llvm.aarch64.neon.scalar.uqxtn would cause GlobalISel to fall back to SDAG.
This was both due to:
1. RegBankSelect placing the operands on gpr banks.
2. No instruction selection patterns for the intrinsic.
Add pattern, and fix RegBankSelect to place operands on the correct banks

>From dca92797f4426c3b15bcb363cbf912939574a67d Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Wed, 3 Jun 2026 13:56:24 +0000
Subject: [PATCH 1/3] [AArch64][GlobalISel] Place neon_scalar_uqxtn's operands
 on fpr

Previously, these operands would be on gpr, which neon intrinsics cannot handle.
To fix, place these operands on fpr.
This still doesn't seem to fix the issue - I assume we need some more patterns.
---
 llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 17350435ea0b8..ee9e57e705750 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -653,6 +653,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_uqrshrn:
   case Intrinsic::aarch64_neon_sqneg:
   case Intrinsic::aarch64_neon_sqabs:
+  case Intrinsic::aarch64_neon_scalar_uqxtn:
   case Intrinsic::aarch64_crypto_sha1h:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:

>From 3abf1f13327d22f2de380a214336a21599856537 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Wed, 3 Jun 2026 16:40:57 +0000
Subject: [PATCH 2/3] [AArch64][GlobalISel] Add pattern to select UQXTNv1i32

neon_scalar_uqxtn was failing instruction selection as there was no pattern matching it to UQXTN. Add that pattern.
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index f23ae6501b285..151cbd9bc5a7c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6696,6 +6696,9 @@ defm UQXTN  : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
 defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd", AArch64usqadd,
                                     int_aarch64_neon_usqadd>;
 
+def : Pat<(i32 (int_aarch64_neon_scalar_uqxtn (i64 FPR64:$Rn))),
+          (i32 (UQXTNv1i32 FPR64:$Rn))>;
+
 // ssub_sat(0, R) -> sqneg(R)
 def : Pat<(v16i8 (ssubsat immAllZerosV, V128:$reg)),
           (v16i8 (SQNEGv16i8 V128:$reg))>;

>From 8e9c60476d160adc4015e93174b2d2d4154740b9 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Thu, 4 Jun 2026 10:54:17 +0000
Subject: [PATCH 3/3] [AArch64][GlobalISel] Update test check

Add a GI run to the only test the checks scalar.uqxtn.
---
 llvm/test/CodeGen/AArch64/arm64-arith-saturating.ll | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/arm64-arith-saturating.ll b/llvm/test/CodeGen/AArch64/arm64-arith-saturating.ll
index 07c4dbcf41096..15812d2d52d40 100644
--- a/llvm/test/CodeGen/AArch64/arm64-arith-saturating.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-arith-saturating.ll
@@ -1,5 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=arm64-eabi -mcpu=cyclone | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-eabi -mcpu=cyclone | FileCheck %s --check-prefixes=CHECK
+; RUN: llc < %s -mtriple=arm64-eabi -mcpu=cyclone -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+
+; CHECK-GI: warning: Instruction selection used fallback path for vqmovund
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for vqmovnd_s
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqxtn_ins
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqxtun_insext
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for saddluse
 
 define i32 @qadds(<4 x i32> %b, <4 x i32> %c) nounwind readnone optsize ssp {
 ; CHECK-LABEL: qadds:



More information about the llvm-commits mailing list