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

>From 74f88e80b88b68d8058fb7171803a2147f2b1a78 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 27 Nov 2025 15:34:40 +0000
Subject: [PATCH 1/9] [AArch64][GlobalISel] Removed fallback for sqshlu
 intrinsic

Added G_SQSHLU node, which lowers the llvm ir intrinsic aarch64_neon_sqshlu to 
the machine intrinsic sqshlu. Generated code is slightly less efficient compare 
to SDAG.
---
 llvm/lib/Target/AArch64/AArch64InstrGISel.td  |  8 +++
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    | 12 +++++
 .../AArch64/GISel/AArch64RegisterBankInfo.cpp |  9 ++++
 llvm/test/CodeGen/AArch64/arm64-vshift.ll     | 49 ++++++++++---------
 4 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td 
b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 7d99786830e3d..7469a081d9787 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -252,6 +252,12 @@ def G_USDOT : AArch64GenericInstruction {
   let hasSideEffects = 0;
 }
 
+def G_SQSHLU : AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+}
+
 // Generic instruction for the BSP pseudo. It is expanded into BSP, which
 // expands into BSL/BIT/BIF after register allocation.
 def G_BSP : AArch64GenericInstruction {
@@ -300,6 +306,8 @@ def : GINodeEquiv<G_UDOT, AArch64udot>;
 def : GINodeEquiv<G_SDOT, AArch64sdot>;
 def : GINodeEquiv<G_USDOT, AArch64usdot>;
 
+def : GINodeEquiv<G_SQSHLU, AArch64sqshlui>;
+
 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
 
 def : GINodeEquiv<G_AARCH64_PREFETCH, AArch64Prefetch>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 1025b2502211a..0010834e01894 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1857,6 +1857,18 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     return LowerBinOp(TargetOpcode::G_SAVGFLOOR);
   case Intrinsic::aarch64_neon_srhadd:
     return LowerBinOp(TargetOpcode::G_SAVGCEIL);
+  case Intrinsic::aarch64_neon_sqshlu: {
+    // Check if last operand is constant vector dup
+    auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
+    if (shiftAmount) {
+           // If so, create a new intrinsic with the correct shift amount
+           MIB.buildInstr(AArch64::G_SQSHLU, {MI.getOperand(0)}, 
{MI.getOperand(2)}).addImm(shiftAmount->getSExtValue());
+           MI.eraseFromParent();
+           return true;
+    } else {
+           return false;
+    }
+  }
   case Intrinsic::aarch64_neon_abs: {
     // Lower the intrinsic to G_ABS.
     MIB.buildInstr(TargetOpcode::G_ABS, {MI.getOperand(0)}, 
{MI.getOperand(2)});
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 4d3d0811b1524..adfc27b097a6c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -1074,6 +1074,15 @@ AArch64RegisterBankInfo::getInstrMapping(const 
MachineInstr &MI) const {
     // Index needs to be a GPR.
     OpRegBankIdx[2] = PMI_FirstGPR;
     break;
+  case AArch64::G_SQSHLU:
+    // Destination and source need to be FPRs.
+    OpRegBankIdx[0] = PMI_FirstFPR;
+    OpRegBankIdx[1] = PMI_FirstFPR;
+
+    // Shift Index needs to be a GPR.
+    OpRegBankIdx[2] = PMI_FirstGPR;
+    break;
+
   case TargetOpcode::G_INSERT_VECTOR_ELT:
     OpRegBankIdx[0] = PMI_FirstFPR;
     OpRegBankIdx[1] = PMI_FirstFPR;
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 9743639d99d9b..161b583c7ac05 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,17 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for sqshlu8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu2d
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu1d_constant
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu_i64_constant
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu_i32_constant
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn1s
+; CHECK-GI:    warning: Instruction selection used fallback path for sqshrn1s
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn8b
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn4h
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn2s
@@ -1496,23 +1486,38 @@ define <2 x i64> @sqshlu2d(ptr %A) nounwind {
 }
 
 define <1 x i64> @sqshlu1d_constant(ptr %A) nounwind {
-; CHECK-LABEL: sqshlu1d_constant:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    ldr d0, [x0]
-; CHECK-NEXT:    sqshlu d0, d0, #1
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: sqshlu1d_constant:
+; CHECK-SD:       // %bb.0:
+; CHECK-SD-NEXT:    ldr d0, [x0]
+; CHECK-SD-NEXT:    sqshlu d0, d0, #1
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: sqshlu1d_constant:
+; CHECK-GI:       // %bb.0:
+; CHECK-GI-NEXT:    ldr x8, [x0]
+; CHECK-GI-NEXT:    fmov d0, x8
+; CHECK-GI-NEXT:    sqshlu d0, d0, #1
+; CHECK-GI-NEXT:    ret
   %tmp1 = load <1 x i64>, ptr %A
   %tmp3 = call <1 x i64> @llvm.aarch64.neon.sqshlu.v1i64(<1 x i64> %tmp1, <1 x 
i64> <i64 1>)
   ret <1 x i64> %tmp3
 }
 
 define i64 @sqshlu_i64_constant(ptr %A) nounwind {
-; CHECK-LABEL: sqshlu_i64_constant:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    ldr d0, [x0]
-; CHECK-NEXT:    sqshlu d0, d0, #1
-; CHECK-NEXT:    fmov x0, d0
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: sqshlu_i64_constant:
+; CHECK-SD:       // %bb.0:
+; CHECK-SD-NEXT:    ldr d0, [x0]
+; CHECK-SD-NEXT:    sqshlu d0, d0, #1
+; CHECK-SD-NEXT:    fmov x0, d0
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: sqshlu_i64_constant:
+; CHECK-GI:       // %bb.0:
+; CHECK-GI-NEXT:    ldr x8, [x0]
+; CHECK-GI-NEXT:    fmov d0, x8
+; CHECK-GI-NEXT:    sqshlu d0, d0, #1
+; CHECK-GI-NEXT:    fmov x0, d0
+; CHECK-GI-NEXT:    ret
   %tmp1 = load i64, ptr %A
   %tmp3 = call i64 @llvm.aarch64.neon.sqshlu.i64(i64 %tmp1, i64 1)
   ret i64 %tmp3

>From 07e5e81b4afd02d31e1239be643977da1f988fad Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Wed, 3 Dec 2025 16:44:30 +0000
Subject: [PATCH 2/9] [AArch64][GlobalISel] Removed fallback from sqshrn
 intrinsic

In legalisation, the IR intrinsic is lowered to two GI instructions: a vector 
right shift (G_VASHR), and a truncate with saturation (G_TRUNC_SSAT_S). The 
result of the G_VASHR is the operand of the G_TRUNC_SSAT_S. Vectors that are 
treated as i64/i32 are dealt with in TableGen, so are not handled here.
---
 .../lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 11 +++++++++++
 .../Target/AArch64/GISel/AArch64RegisterBankInfo.cpp  |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll             | 10 +---------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 0010834e01894..d69e17fac6ba3 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1857,6 +1857,17 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     return LowerBinOp(TargetOpcode::G_SAVGFLOOR);
   case Intrinsic::aarch64_neon_srhadd:
     return LowerBinOp(TargetOpcode::G_SAVGCEIL);
+  case Intrinsic::aarch64_neon_sqshrn: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_VASHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
+    }
+    break;
+  }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index adfc27b097a6c..b9a50e4ff3ba8 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -491,6 +491,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_uqrshl:
   case Intrinsic::aarch64_neon_ushl:
   case Intrinsic::aarch64_neon_sshl:
+  case Intrinsic::aarch64_neon_sqshrn:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
   case Intrinsic::aarch64_crypto_sha1m:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 161b583c7ac05..cb557573b0659 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,14 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for sqshrn1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrn4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun1s
+; CHECK-GI:    warning: Instruction selection used fallback path for sqshrun1s
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun8b
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun4h
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun2s
@@ -53,7 +46,6 @@
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli8h
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli4s
 ; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli2d
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshlu_zero_shift_amount
 
 define <8 x i8> @sqshl8b(ptr %A, ptr %B) nounwind {
 ; CHECK-LABEL: sqshl8b:

>From bfdb761608e20a48c241fb1e393528987fde2048 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Wed, 3 Dec 2025 16:54:42 +0000
Subject: [PATCH 3/9] [AArch64][GlobalISel] Removed fallback from sqshrun
 intrinsic

In legalisation, the IR intrinsic is lowered to two GI instructions: a vector 
right shift (G_VASHR), and an unsigned truncate with saturation 
(G_TRUNC_SSAT_U). The result of the G_VASHR is the operand of the 
G_TRUNC_SSAT_U.
---
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    | 11 +++
 .../AArch64/GISel/AArch64RegisterBankInfo.cpp |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll     | 86 +++++++++----------
 3 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index d69e17fac6ba3..9e05fc3d60b98 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1868,6 +1868,17 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     }
     break;
   }
+  case Intrinsic::aarch64_neon_sqshrun: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_VASHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
+    }
+    break;
+  }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index b9a50e4ff3ba8..3490067d00e38 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -492,6 +492,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_ushl:
   case Intrinsic::aarch64_neon_sshl:
   case Intrinsic::aarch64_neon_sqshrn:
+  case Intrinsic::aarch64_neon_sqshrun:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
   case Intrinsic::aarch64_crypto_sha1m:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index cb557573b0659..9e8adabb671c6 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,50 +2,48 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for sqshrun1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqshrun4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn1s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
uqshrn4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli8b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli4h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli2s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli1d
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sli1d_imm0
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sli16b
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli8h
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli4s
-; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli2d
+; CHECK-GI:    warning: Instruction selection used fallback path for sqrshrn1s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn2s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn16b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun1s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun2s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun16b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn1s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn2s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn16b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn1s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn8b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn4h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn2s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn16b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn8h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn4s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_ushl_vscalar_constant_shift
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_ushl_scalar_constant_shift
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_vscalar_constant_shift
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_scalar_constant_shift
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_scalar_constant_shift_m1
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli8b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli4h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli2s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli1d
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sli1d_imm0
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sli16b
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli8h
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli4s
+; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli2d
 
 define <8 x i8> @sqshl8b(ptr %A, ptr %B) nounwind {
 ; CHECK-LABEL: sqshl8b:

>From 097c328e5947672a2331cf5387b9cd31d06c4450 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 4 Dec 2025 11:09:04 +0000
Subject: [PATCH 4/9] [AArch64][GlobalISel] Removed fallback for sqrshrn
 intrinsic

GISel now legalises sqrshrn into G_TRUNC_SSAT_S(G_SRSHR(vec, shift)).
---
 llvm/lib/Target/AArch64/AArch64InstrGISel.td      |  7 +++++++
 .../Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 15 +++++++++++++--
 .../AArch64/GISel/AArch64RegisterBankInfo.cpp     |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll         |  9 +--------
 4 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td 
b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 7469a081d9787..0c8cbc3b5b864 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -258,6 +258,12 @@ def G_SQSHLU : AArch64GenericInstruction {
   let hasSideEffects = 0;
 }
 
+def G_SRSHR: AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+}
+
 // Generic instruction for the BSP pseudo. It is expanded into BSP, which
 // expands into BSL/BIT/BIF after register allocation.
 def G_BSP : AArch64GenericInstruction {
@@ -307,6 +313,7 @@ def : GINodeEquiv<G_SDOT, AArch64sdot>;
 def : GINodeEquiv<G_USDOT, AArch64usdot>;
 
 def : GINodeEquiv<G_SQSHLU, AArch64sqshlui>;
+def : GINodeEquiv<G_SRSHR, AArch64srshri>;
 
 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 9e05fc3d60b98..b572e07793559 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1863,8 +1863,7 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
       // Create right shift instruction. Get v. register the output is written 
to
       auto Shr = MIB.buildInstr(AArch64::G_VASHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
-      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr});
-      MI.eraseFromParent();
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr}); 
MI.eraseFromParent();
     }
     break;
   }
@@ -1879,6 +1878,18 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     }
     break;
   }
+  case Intrinsic::aarch64_neon_sqrshrn: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_SRSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
+    }
+    break;
+  }
+
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 3490067d00e38..7c6477ee060e2 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -493,6 +493,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_sshl:
   case Intrinsic::aarch64_neon_sqshrn:
   case Intrinsic::aarch64_neon_sqshrun:
+  case Intrinsic::aarch64_neon_sqrshrn:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
   case Intrinsic::aarch64_crypto_sha1m:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 9e8adabb671c6..6f97ea32c9abd 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,14 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for sqrshrn1s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn2s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn16b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn8h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrn4s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun1s
+; CHECK-GI:    warning: Instruction selection used fallback path for sqrshrun1s
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8b
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4h
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun2s

>From 7620205b03448b943344bccd10efa9db96eb1911 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 4 Dec 2025 11:36:46 +0000
Subject: [PATCH 5/9] [AArch64][GlobalISel] Removed fallback for sqrshrun
 intrinsic

GlobalISel now legalises sqrshrun to G_TRUNC_SSAT_U(G_SRSHR(vec, shift)).
---
 .../Target/AArch64/GISel/AArch64LegalizerInfo.cpp    | 12 +++++++++++-
 .../Target/AArch64/GISel/AArch64RegisterBankInfo.cpp |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll            |  9 +--------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index b572e07793559..a7bc58e5db8db 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1889,7 +1889,17 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     }
     break;
   }
-
+  case Intrinsic::aarch64_neon_sqrshrun: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_SRSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
+    }
+    break;
+  }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 7c6477ee060e2..2fb07a188176f 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -494,6 +494,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_sqshrn:
   case Intrinsic::aarch64_neon_sqshrun:
   case Intrinsic::aarch64_neon_sqrshrn:
+  case Intrinsic::aarch64_neon_sqrshrun:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
   case Intrinsic::aarch64_crypto_sha1m:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 6f97ea32c9abd..5fcc33406572e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,14 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for sqrshrun1s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun2s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun16b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun8h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sqrshrun4s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn1s
+; CHECK-GI:    warning: Instruction selection used fallback path for uqrshrn1s
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8b
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4h
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn2s

>From 594e2c888602bcdb299652f44fdb288fd1534fc1 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 4 Dec 2025 14:27:47 +0000
Subject: [PATCH 6/9] [AArch64][GlobalISel] Removed fallback for uqrshrn
 intrinsic

GlobalISel now lowers uqrshrn to G_TRUNC_USATU(G_URSHR(vec, shift)).
---
 llvm/lib/Target/AArch64/AArch64InstrGISel.td          |  7 +++++++
 .../lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 11 +++++++++++
 .../Target/AArch64/GISel/AArch64RegisterBankInfo.cpp  |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll             |  9 +--------
 4 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td 
b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 0c8cbc3b5b864..75354e4098fb4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -264,6 +264,12 @@ def G_SRSHR: AArch64GenericInstruction {
   let hasSideEffects = 0;
 }
 
+def G_URSHR: AArch64GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+}
+
 // Generic instruction for the BSP pseudo. It is expanded into BSP, which
 // expands into BSL/BIT/BIF after register allocation.
 def G_BSP : AArch64GenericInstruction {
@@ -314,6 +320,7 @@ def : GINodeEquiv<G_USDOT, AArch64usdot>;
 
 def : GINodeEquiv<G_SQSHLU, AArch64sqshlui>;
 def : GINodeEquiv<G_SRSHR, AArch64srshri>;
+def : GINodeEquiv<G_URSHR, AArch64urshri>;
 
 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index a7bc58e5db8db..d73c47ce833d9 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1900,6 +1900,17 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     }
     break;
   }
+  case Intrinsic::aarch64_neon_uqrshrn: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_URSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_USAT_U, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
+    }
+    break;
+  }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 2fb07a188176f..345ae1e3472a0 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -495,6 +495,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_sqshrun:
   case Intrinsic::aarch64_neon_sqrshrn:
   case Intrinsic::aarch64_neon_sqrshrun:
+  case Intrinsic::aarch64_neon_uqrshrn:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
   case Intrinsic::aarch64_crypto_sha1m:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 5fcc33406572e..0bc86b1e9c61c 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,14 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for uqrshrn1s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn2s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn16b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn8h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqrshrn4s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn1s
+; CHECK-GI:    warning: Instruction selection used fallback path for uqshrn1s
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn8b
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn4h
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn2s

>From 290832ad47953a3b0bae5d4f085d54e2d8ea7768 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 4 Dec 2025 15:19:35 +0000
Subject: [PATCH 7/9] [AArch64][GlobalISel] Removed fallback for uqshrn
 intrinsic

GlobalISel now lowers uqshrn to G_TRUNC_USATU(VLSHR(vec, shift)).
---
 llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 10 ++++++++++
 .../Target/AArch64/GISel/AArch64RegisterBankInfo.cpp   |  1 +
 llvm/test/CodeGen/AArch64/arm64-vshift.ll              |  9 +--------
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index d73c47ce833d9..0c8472b759132 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1911,6 +1911,16 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     }
     break;
   }
+  case Intrinsic::aarch64_neon_uqshrn: {
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+    {
+      // Create right shift instruction. Get v. register the output is written 
to
+      auto Shr = MIB.buildInstr(AArch64::G_VLSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+      // Build the narrow intrinsic, taking in the v. register of the shift
+      MIB.buildInstr(TargetOpcode::G_TRUNC_USAT_U, {MI.getOperand(0)}, {Shr}); 
MI.eraseFromParent();
+    }
+    break;
+  }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
     auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 345ae1e3472a0..84bc3f1e14a7a 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -495,6 +495,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
   case Intrinsic::aarch64_neon_sqshrun:
   case Intrinsic::aarch64_neon_sqrshrn:
   case Intrinsic::aarch64_neon_sqrshrun:
+  case Intrinsic::aarch64_neon_uqshrn:
   case Intrinsic::aarch64_neon_uqrshrn:
   case Intrinsic::aarch64_crypto_sha1c:
   case Intrinsic::aarch64_crypto_sha1p:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 0bc86b1e9c61c..bd931461764c0 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,14 +2,7 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for uqshrn1s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn8b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn4h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn2s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn16b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn8h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
uqshrn4s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_ushl_vscalar_constant_shift
+; CHECK-GI:    warning: Instruction selection used fallback path for 
neon_ushl_vscalar_constant_shift
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_ushl_scalar_constant_shift
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_vscalar_constant_shift
 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_scalar_constant_shift

>From 9955779a115146a75469998712d6c4cf683d3d8d Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Thu, 4 Dec 2025 16:36:19 +0000
Subject: [PATCH 8/9] [AArch64][GlobalISel] Updated test checks

---
 llvm/test/CodeGen/AArch64/arm64-int-neon.ll |  3 ++-
 llvm/test/CodeGen/AArch64/arm64-vshift.ll   | 23 ++++++++-------------
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll 
b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
index e8ae8a3e53c9b..eb86728e6d22f 100644
--- a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
@@ -8,7 +8,6 @@
 ; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for 
test_uqsub_s32
 ; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for 
test_uqsub_s64
 ; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for 
test_sqdmulls_scalar
-
 define i32 @test_sqrshl_s32(float noundef %a){
 ; CHECK-LABEL: test_sqrshl_s32:
 ; CHECK:       // %bb.0: // %entry
@@ -228,3 +227,5 @@ define i64 @test_sqdmulls_scalar(float %A){
   %prod = call i64 @llvm.aarch64.neon.sqdmulls.scalar(i32  %cvt, i32  %cvt)
   ret i64 %prod
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add 
tests below this line:
+; CHECK-GI: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll 
b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index bd931461764c0..a316a4bc543b5 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,20 +2,15 @@
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s 
--check-prefixes=CHECK,CHECK-SD
 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 -global-isel-abort=2 2>&1 | 
FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
-; CHECK-GI:    warning: Instruction selection used fallback path for 
neon_ushl_vscalar_constant_shift
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_ushl_scalar_constant_shift
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_vscalar_constant_shift
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_scalar_constant_shift
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
neon_sshll_scalar_constant_shift_m1
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli8b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli4h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli2s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli1d
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sli1d_imm0
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for 
sli16b
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli8h
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli4s
-; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for sli2d
+; CHECK-GI:    warning: Instruction selection used fallback path for sli8b
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli4h
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli2s
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli1d
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sli1d_imm0
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for 
sli16b
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli8h
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli4s
+; CHECK-GI NEXT:    warning: Instruction selection used fallback path for sli2d
 
 define <8 x i8> @sqshl8b(ptr %A, ptr %B) nounwind {
 ; CHECK-LABEL: sqshl8b:

>From 71a95026812dd75f408c51026547b794af18dd47 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <[email protected]>
Date: Tue, 9 Dec 2025 10:34:35 +0000
Subject: [PATCH 9/9] [AArch64][GlobalISel] Fixed formatting

---
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    | 80 +++++++++++--------
 1 file changed, 48 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp 
b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 0c8472b759132..8951ccfbd3352 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1858,20 +1858,25 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
   case Intrinsic::aarch64_neon_srhadd:
     return LowerBinOp(TargetOpcode::G_SAVGCEIL);
   case Intrinsic::aarch64_neon_sqshrn: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_VASHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_VASHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
-      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr}); 
MI.eraseFromParent();
+      MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
     }
     break;
   }
   case Intrinsic::aarch64_neon_sqshrun: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_VASHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_VASHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
       MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {MI.getOperand(0)}, {Shr});
       MI.eraseFromParent();
@@ -1879,10 +1884,12 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     break;
   }
   case Intrinsic::aarch64_neon_sqrshrn: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_SRSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_SRSHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
       MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {MI.getOperand(0)}, {Shr});
       MI.eraseFromParent();
@@ -1890,10 +1897,12 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     break;
   }
   case Intrinsic::aarch64_neon_sqrshrun: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_SRSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_SRSHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
       MIB.buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {MI.getOperand(0)}, {Shr});
       MI.eraseFromParent();
@@ -1901,10 +1910,12 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     break;
   }
   case Intrinsic::aarch64_neon_uqrshrn: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_URSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_URSHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
       MIB.buildInstr(TargetOpcode::G_TRUNC_USAT_U, {MI.getOperand(0)}, {Shr});
       MI.eraseFromParent();
@@ -1912,25 +1923,30 @@ bool 
AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
     break;
   }
   case Intrinsic::aarch64_neon_uqshrn: {
-    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
-    {
-      // Create right shift instruction. Get v. register the output is written 
to
-      auto Shr = MIB.buildInstr(AArch64::G_VLSHR, 
{MRI.getType(MI.getOperand(2).getReg())}, {MI.getOperand(2), 
MI.getOperand(3).getImm()});
+    if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+      // Create right shift instruction. Get v. register the output is written
+      // to
+      auto Shr = MIB.buildInstr(AArch64::G_VLSHR,
+                                {MRI.getType(MI.getOperand(2).getReg())},
+                                {MI.getOperand(2), MI.getOperand(3).getImm()});
       // Build the narrow intrinsic, taking in the v. register of the shift
-      MIB.buildInstr(TargetOpcode::G_TRUNC_USAT_U, {MI.getOperand(0)}, {Shr}); 
MI.eraseFromParent();
+      MIB.buildInstr(TargetOpcode::G_TRUNC_USAT_U, {MI.getOperand(0)}, {Shr});
+      MI.eraseFromParent();
     }
     break;
   }
   case Intrinsic::aarch64_neon_sqshlu: {
     // Check if last operand is constant vector dup
-    auto shiftAmount = 
isConstantOrConstantSplatVector(*MRI.getVRegDef(MI.getOperand(3).getReg()), 
MRI);
+    auto shiftAmount = isConstantOrConstantSplatVector(
+        *MRI.getVRegDef(MI.getOperand(3).getReg()), MRI);
     if (shiftAmount) {
-           // If so, create a new intrinsic with the correct shift amount
-           MIB.buildInstr(AArch64::G_SQSHLU, {MI.getOperand(0)}, 
{MI.getOperand(2)}).addImm(shiftAmount->getSExtValue());
-           MI.eraseFromParent();
-           return true;
+      // If so, create a new intrinsic with the correct shift amount
+      MIB.buildInstr(AArch64::G_SQSHLU, {MI.getOperand(0)}, {MI.getOperand(2)})
+          .addImm(shiftAmount->getSExtValue());
+      MI.eraseFromParent();
+      return true;
     } else {
-           return false;
+      return false;
     }
   }
   case Intrinsic::aarch64_neon_abs: {

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to