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
