[llvm] [AArch64][GlobalISel] Added support for neon right shifts (PR #170832)
Joshua Rodriguez via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 12 08:03:01 PST 2025
https://github.com/JoshdRod updated https://github.com/llvm/llvm-project/pull/170832
>From df5a3947dfe05400c5e5b640dda048af4eb85a7e Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 25 Nov 2025 10:56:06 +0000
Subject: [PATCH 01/20] [AArch64][GlobalISel] Removed sqshl fallback occurring
for <1 x i64> operands
GISel now places sqshl operands on floating point registers. Generated code is slightly less efficient compared to SDAG.
---
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 1 +
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 70 ++++++++++++-------
2 files changed, 47 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 6b920f05227ad..acbec16b1cd22 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -483,6 +483,7 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_sqadd:
case Intrinsic::aarch64_neon_sqsub:
case Intrinsic::aarch64_crypto_sha1h:
+ case Intrinsic::aarch64_neon_sqshl:
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 d27e2e69f8605..88516bd16fdbd 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,11 +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 sqshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl1d
+; CHECK-GI: warning: Instruction selection used fallback path for uqshl1d
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl1d_constant
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl_scalar
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl_scalar_constant
@@ -155,24 +151,42 @@ define <1 x i64> @sqshl1d(ptr %A, ptr %B) nounwind {
}
define <1 x i64> @sqshl1d_constant(ptr %A) nounwind {
-; CHECK-LABEL: sqshl1d_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: sqshl d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: sqshl1d_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: sqshl d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sqshl1d_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: sqshl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.sqshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 1>)
ret <1 x i64> %tmp3
}
define i64 @sqshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: sqshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: sqshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: sqshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: sqshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sqshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: sqshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.sqshl.i64(i64 %tmp1, i64 %tmp2)
@@ -180,12 +194,21 @@ define i64 @sqshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @sqshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: sqshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: sqshl d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: sqshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: sqshl d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sqshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: sqshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.sqshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
@@ -2616,7 +2639,6 @@ define <4 x i32> @neon_sshl4s_wrong_ext_constant_shift(ptr %A) nounwind {
; CHECK-GI-NEXT: ret
%tmp1 = load <4 x i8>, ptr %A
%tmp2 = sext <4 x i8> %tmp1 to <4 x i32>
- %tmp3 = call <4 x i32> @llvm.aarch64.neon.sshl.v4i32(<4 x i32> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
ret <4 x i32> %tmp3
}
>From 71e4e0d66ec1eeb5c767188aa447c52247207029 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 25 Nov 2025 11:20:22 +0000
Subject: [PATCH 02/20] [AArch64][GlobalISel] Removed fallback for uqsh, uqrsh,
and sqrsh with <1 x i64> operands
GISel now places operands for these intrinsics on floating point registers. Generated code is slightly less efficient compared to SDAG.
---
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 3 +
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 185 +++++++++++-------
2 files changed, 119 insertions(+), 69 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index acbec16b1cd22..ff0321c8b41d1 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -484,6 +484,9 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_sqsub:
case Intrinsic::aarch64_crypto_sha1h:
case Intrinsic::aarch64_neon_sqshl:
+ case Intrinsic::aarch64_neon_uqshl:
+ case Intrinsic::aarch64_neon_sqrshl:
+ case Intrinsic::aarch64_neon_uqrshl:
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 88516bd16fdbd..43efb19dbf0f2 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,27 +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 uqshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqrshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqrshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqrshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for sqrshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqrshl1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqrshl1d_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqrshl_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for uqrshl_scalar_constant
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshr1d
+; CHECK-GI: warning: Instruction selection used fallback path for urshr1d
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshr_scalar
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshr1d
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshr_scalar
@@ -371,24 +351,42 @@ define <1 x i64> @uqshl1d(ptr %A, ptr %B) nounwind {
}
define <1 x i64> @uqshl1d_constant(ptr %A) nounwind {
-; CHECK-LABEL: uqshl1d_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: uqshl d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uqshl1d_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: uqshl d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uqshl1d_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: uqshl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.uqshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 1>)
ret <1 x i64> %tmp3
}
define i64 @uqshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: uqshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: uqshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uqshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: uqshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uqshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: uqshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.uqshl.i64(i64 %tmp1, i64 %tmp2)
@@ -396,12 +394,21 @@ define i64 @uqshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @uqshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: uqshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: uqshl d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uqshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: uqshl d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uqshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: uqshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.uqshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
@@ -905,13 +912,23 @@ define <1 x i64> @sqrshl1d_constant(ptr %A) nounwind {
}
define i64 @sqrshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: sqrshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: sqrshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: sqrshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: sqrshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sqrshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: sqrshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.sqrshl.i64(i64 %tmp1, i64 %tmp2)
@@ -919,14 +936,24 @@ define i64 @sqrshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @sqrshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: sqrshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: mov x8, #1 // =0x1
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: fmov d1, x8
-; CHECK-NEXT: sqrshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: sqrshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x9, [x0]
+; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: fmov d1, x8
+; CHECK-SD-NEXT: fmov d0, x9
+; CHECK-SD-NEXT: sqrshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sqrshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: sqrshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.sqrshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
@@ -1011,13 +1038,23 @@ define <1 x i64> @uqrshl1d_constant(ptr %A) nounwind {
}
define i64 @uqrshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: uqrshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: uqrshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uqrshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: uqrshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uqrshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: uqrshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.uqrshl.i64(i64 %tmp1, i64 %tmp2)
@@ -1025,14 +1062,24 @@ define i64 @uqrshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @uqrshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: uqrshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: mov x8, #1 // =0x1
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: fmov d1, x8
-; CHECK-NEXT: uqrshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uqrshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x9, [x0]
+; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: fmov d1, x8
+; CHECK-SD-NEXT: fmov d0, x9
+; CHECK-SD-NEXT: uqrshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uqrshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: uqrshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.uqrshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
>From 53c3c4bdf4c704a1d09915e643e30231a7211bc2 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 25 Nov 2025 13:55:32 +0000
Subject: [PATCH 03/20] [AArch64][GlobalISel] Updated arm64-vshift.ll to have
correct fallback lines
Check lines were previously expecting some fallbacks which no longer happen. This update fixes that.
---
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 172 ++++++++++++----------
1 file changed, 97 insertions(+), 75 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 43efb19dbf0f2..f8573e8ee0574 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,81 +2,103 @@
; 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 urshr1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for urshr_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshr1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srshr_scalar
-; CHECK-GI-NEXT: 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-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-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 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 ursra1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for ursra_scalar
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srsra1d
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for srsra_scalar
-; 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-NEXT: warning: Instruction selection used fallback path for sqshlu_zero_shift_amount
+; CHECK-GI: warning: Instruction selection used fallback path for srshl1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl1d_constant
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl_scalar
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl_scalar_constant
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl1d_constant
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl_scalar
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl_scalar_constant
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshr1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshr_scalar
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshr1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshr_scalar
+; CHECK-GI NEXT: 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 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 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 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 ursra1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for ursra_scalar
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srsra1d
+; CHECK-GI NEXT: warning: Instruction selection used fallback path for srsra_scalar
+; 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 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 80ef01ce6cdb45ca3a5c9187758a752536e806f3 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 25 Nov 2025 14:21:22 +0000
Subject: [PATCH 04/20] [AArch64][GlobalISel] Removed fallback for urshl/srshl
intrinsics with <1 x i64> operands
GISel now places urshl/srshl operands on floating point registers. Generated code is slightly less efficient compare to SDAG.
---
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 2 +
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 314 +++++++++++-------
llvm/test/CodeGen/AArch64/neon-addlv.ll | 27 +-
3 files changed, 220 insertions(+), 123 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index ff0321c8b41d1..652a31f4e65f2 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -483,6 +483,8 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_sqadd:
case Intrinsic::aarch64_neon_sqsub:
case Intrinsic::aarch64_crypto_sha1h:
+ case Intrinsic::aarch64_neon_srshl:
+ case Intrinsic::aarch64_neon_urshl:
case Intrinsic::aarch64_neon_sqshl:
case Intrinsic::aarch64_neon_uqshl:
case Intrinsic::aarch64_neon_sqrshl:
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index f8573e8ee0574..34843835d284a 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,19 +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 srshl1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl1d_constant
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl_scalar
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshl_scalar_constant
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl1d_constant
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl_scalar
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshl_scalar_constant
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshr1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for urshr_scalar
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshr1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srshr_scalar
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for sqshlu8b
+; 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
@@ -56,20 +44,6 @@
; 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 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
@@ -85,10 +59,6 @@
; 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 ursra1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for ursra_scalar
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srsra1d
-; CHECK-GI NEXT: warning: Instruction selection used fallback path for srsra_scalar
; 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
@@ -525,15 +495,23 @@ define <1 x i64> @srshl1d_constant(ptr %A) nounwind {
}
define i64 @srshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: srshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr x8, [x0]
-; CHECK-NEXT: ldr x9, [x1]
-; CHECK-NEXT: fmov d0, x8
-; CHECK-NEXT: fmov d1, x9
-; CHECK-NEXT: srshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: srshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.srshl.i64(i64 %tmp1, i64 %tmp2)
@@ -541,15 +519,24 @@ define i64 @srshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @srshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: srshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr x9, [x0]
-; CHECK-NEXT: mov w8, #1 // =0x1
-; CHECK-NEXT: fmov d1, x8
-; CHECK-NEXT: fmov d0, x9
-; CHECK-NEXT: srshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x9, [x0]
+; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: fmov d1, x8
+; CHECK-SD-NEXT: fmov d0, x9
+; CHECK-SD-NEXT: srshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.srshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
@@ -621,15 +608,23 @@ define <1 x i64> @urshl1d_constant(ptr %A) nounwind {
}
define i64 @urshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: urshl_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr x8, [x0]
-; CHECK-NEXT: ldr x9, [x1]
-; CHECK-NEXT: fmov d0, x8
-; CHECK-NEXT: fmov d1, x9
-; CHECK-NEXT: urshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: urshl_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x8, [x0]
+; CHECK-SD-NEXT: ldr x9, [x1]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: fmov d1, x9
+; CHECK-SD-NEXT: urshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: urshl_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: ldr d1, [x1]
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.urshl.i64(i64 %tmp1, i64 %tmp2)
@@ -637,15 +632,24 @@ define i64 @urshl_scalar(ptr %A, ptr %B) nounwind {
}
define i64 @urshl_scalar_constant(ptr %A) nounwind {
-; CHECK-LABEL: urshl_scalar_constant:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr x9, [x0]
-; CHECK-NEXT: mov w8, #1 // =0x1
-; CHECK-NEXT: fmov d1, x8
-; CHECK-NEXT: fmov d0, x9
-; CHECK-NEXT: urshl d0, d0, d1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: urshl_scalar_constant:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr x9, [x0]
+; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: fmov d1, x8
+; CHECK-SD-NEXT: fmov d0, x9
+; CHECK-SD-NEXT: urshl d0, d0, d1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: urshl_scalar_constant:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.urshl.i64(i64 %tmp1, i64 1)
ret i64 %tmp3
@@ -1256,23 +1260,40 @@ define <2 x i64> @urshr2d(ptr %A) nounwind {
}
define <1 x i64> @urshr1d(ptr %A) nounwind {
-; CHECK-LABEL: urshr1d:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: urshr d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: urshr1d:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: urshr d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: urshr1d:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 -1>)
ret <1 x i64> %tmp3
}
define i64 @urshr_scalar(ptr %A) nounwind {
-; CHECK-LABEL: urshr_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: urshr d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: urshr_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: urshr d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: urshr_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.urshl.i64(i64 %tmp1, i64 -1)
ret i64 %tmp3
@@ -1405,23 +1426,40 @@ define <2 x i64> @srshr2d(ptr %A) nounwind {
}
define <1 x i64> @srshr1d(ptr %A) nounwind {
-; CHECK-LABEL: srshr1d:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: srshr d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srshr1d:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: srshr d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srshr1d:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.srshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 -1>)
ret <1 x i64> %tmp3
}
define i64 @srshr_scalar(ptr %A) nounwind {
-; CHECK-LABEL: srshr_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: srshr d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srshr_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: srshr d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srshr_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.srshl.i64(i64 %tmp1, i64 -1)
ret i64 %tmp3
@@ -3381,12 +3419,24 @@ define <2 x i64> @ursra2d(ptr %A, ptr %B) nounwind {
}
define <1 x i64> @ursra1d(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: ursra1d:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d1, [x0]
-; CHECK-NEXT: ldr d0, [x1]
-; CHECK-NEXT: ursra d0, d1, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: ursra1d:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d1, [x0]
+; CHECK-SD-NEXT: ldr d0, [x1]
+; CHECK-SD-NEXT: ursra d0, d1, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: ursra1d:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: ldr x8, [x1]
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: add x8, x9, x8
+; CHECK-GI-NEXT: fmov d0, x8
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 -1>)
%tmp4 = load <1 x i64>, ptr %B
@@ -3395,13 +3445,24 @@ define <1 x i64> @ursra1d(ptr %A, ptr %B) nounwind {
}
define i64 @ursra_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: ursra_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: ursra d1, d0, #1
-; CHECK-NEXT: fmov x0, d1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: ursra_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: ldr d1, [x1]
+; CHECK-SD-NEXT: ursra d1, d0, #1
+; CHECK-SD-NEXT: fmov x0, d1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: ursra_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: ldr x8, [x1]
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: add x0, x9, x8
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.urshl.i64(i64 %tmp1, i64 -1)
%tmp4 = load i64, ptr %B
@@ -3571,12 +3632,24 @@ define <2 x i64> @srsra2d(ptr %A, ptr %B) nounwind {
}
define <1 x i64> @srsra1d(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: srsra1d:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d1, [x0]
-; CHECK-NEXT: ldr d0, [x1]
-; CHECK-NEXT: srsra d0, d1, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srsra1d:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d1, [x0]
+; CHECK-SD-NEXT: ldr d0, [x1]
+; CHECK-SD-NEXT: srsra d0, d1, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srsra1d:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: ldr x8, [x1]
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: add x8, x9, x8
+; CHECK-GI-NEXT: fmov d0, x8
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i64>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.srshl.v1i64(<1 x i64> %tmp1, <1 x i64> <i64 -1>)
%tmp4 = load <1 x i64>, ptr %B
@@ -3585,13 +3658,24 @@ define <1 x i64> @srsra1d(ptr %A, ptr %B) nounwind {
}
define i64 @srsra_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-LABEL: srsra_scalar:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr d0, [x0]
-; CHECK-NEXT: ldr d1, [x1]
-; CHECK-NEXT: srsra d1, d0, #1
-; CHECK-NEXT: fmov x0, d1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: srsra_scalar:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr d0, [x0]
+; CHECK-SD-NEXT: ldr d1, [x1]
+; CHECK-SD-NEXT: srsra d1, d0, #1
+; CHECK-SD-NEXT: fmov x0, d1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: srsra_scalar:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: ldr d0, [x0]
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: ldr x8, [x1]
+; CHECK-GI-NEXT: srshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: add x0, x9, x8
+; CHECK-GI-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp3 = call i64 @llvm.aarch64.neon.srshl.i64(i64 %tmp1, i64 -1)
%tmp4 = load i64, ptr %B
diff --git a/llvm/test/CodeGen/AArch64/neon-addlv.ll b/llvm/test/CodeGen/AArch64/neon-addlv.ll
index a747ee661adcd..a6d2dab8f5687 100644
--- a/llvm/test/CodeGen/AArch64/neon-addlv.ll
+++ b/llvm/test/CodeGen/AArch64/neon-addlv.ll
@@ -2,8 +2,6 @@
; RUN: llc -mtriple aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
; RUN: llc -mtriple aarch64-none-linux-gnu -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
-; CHECK-GI: warning: Instruction selection used fallback path for uaddlv_v8i8_urshr
-
declare <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8>) nounwind readnone
declare <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8>) nounwind readnone
declare <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16>) nounwind readnone
@@ -223,12 +221,25 @@ declare <8 x i8> @llvm.aarch64.neon.rshrn.v8i8(<8 x i16>, i32)
declare i64 @llvm.aarch64.neon.urshl.i64(i64, i64)
define <8 x i8> @uaddlv_v8i8_urshr(<8 x i8> %a) {
-; CHECK-LABEL: uaddlv_v8i8_urshr:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: uaddlv h0, v0.8b
-; CHECK-NEXT: urshr d0, d0, #3
-; CHECK-NEXT: dup v0.8b, v0.b[0]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: uaddlv_v8i8_urshr:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: uaddlv h0, v0.8b
+; CHECK-SD-NEXT: urshr d0, d0, #3
+; CHECK-SD-NEXT: dup v0.8b, v0.b[0]
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uaddlv_v8i8_urshr:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: uaddlv h0, v0.8b
+; CHECK-GI-NEXT: mov x8, #-3 // =0xfffffffffffffffd
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov w9, s0
+; CHECK-GI-NEXT: and w9, w9, #0xffff
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: urshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x8, d0
+; CHECK-GI-NEXT: dup v0.8b, w8
+; CHECK-GI-NEXT: ret
entry:
%vaddlv.i = tail call i32 @llvm.aarch64.neon.uaddlv.i32.v8i8(<8 x i8> %a)
%0 = and i32 %vaddlv.i, 65535
>From 7060138135143170161a24f9d3ef7ccbfc0ba393 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 16:59:35 +0000
Subject: [PATCH 05/20] [AArch64][GlobalISel] Updated test checks
---
llvm/test/CodeGen/AArch64/arm64-int-neon.ll | 12 +--
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 107 ++++++--------------
2 files changed, 36 insertions(+), 83 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
index f33d41b0dd6ef..ace179626f508 100644
--- a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
@@ -3,15 +3,7 @@
; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel -global-isel-abort=2 -mattr=+fprcvt,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
-; CHECK-GI: warning: Instruction selection used fallback path for test_sqrshl_s32
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_sqrshl_s64
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_sqshl_s32
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_sqshl_s64
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqrshl_s32
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqrshl_s64
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqshl_s32
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqshl_s64
-; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqadd_s32
+; CHECK-GI: warning: Instruction selection used fallback path for test_uqadd_s32
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_uqadd_s64
; 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
@@ -236,3 +228,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 34843835d284a..acfef179aabf8 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -142,23 +142,13 @@ define <1 x i64> @sqshl1d_constant(ptr %A) nounwind {
}
define i64 @sqshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-SD-LABEL: sqshl_scalar:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x8, [x0]
-; CHECK-SD-NEXT: ldr x9, [x1]
-; CHECK-SD-NEXT: fmov d0, x8
-; CHECK-SD-NEXT: fmov d1, x9
-; CHECK-SD-NEXT: sqshl d0, d0, d1
-; CHECK-SD-NEXT: fmov x0, d0
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: sqshl_scalar:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: ldr d0, [x0]
-; CHECK-GI-NEXT: ldr d1, [x1]
-; CHECK-GI-NEXT: sqshl d0, d0, d1
-; CHECK-GI-NEXT: fmov x0, d0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: sqshl_scalar:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sqshl d0, d0, d1
+; CHECK-NEXT: fmov x0, d0
+; CHECK-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.sqshl.i64(i64 %tmp1, i64 %tmp2)
@@ -362,23 +352,13 @@ define <1 x i64> @uqshl1d_constant(ptr %A) nounwind {
}
define i64 @uqshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-SD-LABEL: uqshl_scalar:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x8, [x0]
-; CHECK-SD-NEXT: ldr x9, [x1]
-; CHECK-SD-NEXT: fmov d0, x8
-; CHECK-SD-NEXT: fmov d1, x9
-; CHECK-SD-NEXT: uqshl d0, d0, d1
-; CHECK-SD-NEXT: fmov x0, d0
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: uqshl_scalar:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: ldr d0, [x0]
-; CHECK-GI-NEXT: ldr d1, [x1]
-; CHECK-GI-NEXT: uqshl d0, d0, d1
-; CHECK-GI-NEXT: fmov x0, d0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: uqshl_scalar:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: uqshl d0, d0, d1
+; CHECK-NEXT: fmov x0, d0
+; CHECK-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.uqshl.i64(i64 %tmp1, i64 %tmp2)
@@ -938,23 +918,13 @@ define <1 x i64> @sqrshl1d_constant(ptr %A) nounwind {
}
define i64 @sqrshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-SD-LABEL: sqrshl_scalar:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x8, [x0]
-; CHECK-SD-NEXT: ldr x9, [x1]
-; CHECK-SD-NEXT: fmov d0, x8
-; CHECK-SD-NEXT: fmov d1, x9
-; CHECK-SD-NEXT: sqrshl d0, d0, d1
-; CHECK-SD-NEXT: fmov x0, d0
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: sqrshl_scalar:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: ldr d0, [x0]
-; CHECK-GI-NEXT: ldr d1, [x1]
-; CHECK-GI-NEXT: sqrshl d0, d0, d1
-; CHECK-GI-NEXT: fmov x0, d0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: sqrshl_scalar:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sqrshl d0, d0, d1
+; CHECK-NEXT: fmov x0, d0
+; CHECK-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.sqrshl.i64(i64 %tmp1, i64 %tmp2)
@@ -964,10 +934,9 @@ define i64 @sqrshl_scalar(ptr %A, ptr %B) nounwind {
define i64 @sqrshl_scalar_constant(ptr %A) nounwind {
; CHECK-SD-LABEL: sqrshl_scalar_constant:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x9, [x0]
-; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: mov x8, #1 // =0x1
+; CHECK-SD-NEXT: ldr d0, [x0]
; CHECK-SD-NEXT: fmov d1, x8
-; CHECK-SD-NEXT: fmov d0, x9
; CHECK-SD-NEXT: sqrshl d0, d0, d1
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: ret
@@ -1064,23 +1033,13 @@ define <1 x i64> @uqrshl1d_constant(ptr %A) nounwind {
}
define i64 @uqrshl_scalar(ptr %A, ptr %B) nounwind {
-; CHECK-SD-LABEL: uqrshl_scalar:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x8, [x0]
-; CHECK-SD-NEXT: ldr x9, [x1]
-; CHECK-SD-NEXT: fmov d0, x8
-; CHECK-SD-NEXT: fmov d1, x9
-; CHECK-SD-NEXT: uqrshl d0, d0, d1
-; CHECK-SD-NEXT: fmov x0, d0
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: uqrshl_scalar:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: ldr d0, [x0]
-; CHECK-GI-NEXT: ldr d1, [x1]
-; CHECK-GI-NEXT: uqrshl d0, d0, d1
-; CHECK-GI-NEXT: fmov x0, d0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: uqrshl_scalar:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: uqrshl d0, d0, d1
+; CHECK-NEXT: fmov x0, d0
+; CHECK-NEXT: ret
%tmp1 = load i64, ptr %A
%tmp2 = load i64, ptr %B
%tmp3 = call i64 @llvm.aarch64.neon.uqrshl.i64(i64 %tmp1, i64 %tmp2)
@@ -1090,10 +1049,9 @@ define i64 @uqrshl_scalar(ptr %A, ptr %B) nounwind {
define i64 @uqrshl_scalar_constant(ptr %A) nounwind {
; CHECK-SD-LABEL: uqrshl_scalar_constant:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: ldr x9, [x0]
-; CHECK-SD-NEXT: mov w8, #1 // =0x1
+; CHECK-SD-NEXT: mov x8, #1 // =0x1
+; CHECK-SD-NEXT: ldr d0, [x0]
; CHECK-SD-NEXT: fmov d1, x8
-; CHECK-SD-NEXT: fmov d0, x9
; CHECK-SD-NEXT: uqrshl d0, d0, d1
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: ret
@@ -2746,6 +2704,7 @@ define <4 x i32> @neon_sshl4s_wrong_ext_constant_shift(ptr %A) nounwind {
; CHECK-GI-NEXT: ret
%tmp1 = load <4 x i8>, ptr %A
%tmp2 = sext <4 x i8> %tmp1 to <4 x i32>
+ %tmp3 = call <4 x i32> @llvm.aarch64.neon.sshl.v4i32(<4 x i32> %tmp2, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
ret <4 x i32> %tmp3
}
>From 0e901c97663b69c4724c9feede39bcd499daa076 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Fri, 5 Dec 2025 16:48:20 +0000
Subject: [PATCH 06/20] [AArch64][GlobalISel] Removed constant shift fallbacks
for ushl and sshl neon intrinsics
---
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 2 +
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 123 ++++++++++++------
2 files changed, 85 insertions(+), 40 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 652a31f4e65f2..4d3d0811b1524 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -489,6 +489,8 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_uqshl:
case Intrinsic::aarch64_neon_sqrshl:
case Intrinsic::aarch64_neon_uqrshl:
+ case Intrinsic::aarch64_neon_ushl:
+ case Intrinsic::aarch64_neon_sshl:
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 acfef179aabf8..9743639d99d9b 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -54,11 +54,6 @@
; 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
@@ -2535,13 +2530,22 @@ define <2 x i64> @neon_ushll2d_constant_shift(ptr %A) nounwind {
}
define <1 x i64> @neon_ushl_vscalar_constant_shift(ptr %A) nounwind {
-; CHECK-LABEL: neon_ushl_vscalar_constant_shift:
-; CHECK: // %bb.0:
-; CHECK-NEXT: movi v0.2d, #0000000000000000
-; CHECK-NEXT: ldr s1, [x0]
-; CHECK-NEXT: zip1 v0.2s, v1.2s, v0.2s
-; CHECK-NEXT: shl d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: neon_ushl_vscalar_constant_shift:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: movi v0.2d, #0000000000000000
+; CHECK-SD-NEXT: ldr s1, [x0]
+; CHECK-SD-NEXT: zip1 v0.2s, v1.2s, v0.2s
+; CHECK-SD-NEXT: shl d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: neon_ushl_vscalar_constant_shift:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr w9, [x0]
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: ushl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i32>, ptr %A
%tmp2 = zext <1 x i32> %tmp1 to <1 x i64>
%tmp3 = call <1 x i64> @llvm.aarch64.neon.ushl.v1i64(<1 x i64> %tmp2, <1 x i64> <i64 1>)
@@ -2549,13 +2553,23 @@ define <1 x i64> @neon_ushl_vscalar_constant_shift(ptr %A) nounwind {
}
define i64 @neon_ushl_scalar_constant_shift(ptr %A) nounwind {
-; CHECK-LABEL: neon_ushl_scalar_constant_shift:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr w8, [x0]
-; CHECK-NEXT: fmov d0, x8
-; CHECK-NEXT: shl d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: neon_ushl_scalar_constant_shift:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr w8, [x0]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: shl d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: neon_ushl_scalar_constant_shift:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr w9, [x0]
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: ushl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i32, ptr %A
%tmp2 = zext i32 %tmp1 to i64
%tmp3 = call i64 @llvm.aarch64.neon.ushl.i64(i64 %tmp2, i64 1)
@@ -2809,13 +2823,22 @@ define <2 x i64> @neon_sshll2d_constant_shift(ptr %A) nounwind {
}
define <1 x i64> @neon_sshll_vscalar_constant_shift(ptr %A) nounwind {
-; CHECK-LABEL: neon_sshll_vscalar_constant_shift:
-; CHECK: // %bb.0:
-; CHECK-NEXT: movi v0.2d, #0000000000000000
-; CHECK-NEXT: ldr s1, [x0]
-; CHECK-NEXT: zip1 v0.2s, v1.2s, v0.2s
-; CHECK-NEXT: shl d0, d0, #1
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: neon_sshll_vscalar_constant_shift:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: movi v0.2d, #0000000000000000
+; CHECK-SD-NEXT: ldr s1, [x0]
+; CHECK-SD-NEXT: zip1 v0.2s, v1.2s, v0.2s
+; CHECK-SD-NEXT: shl d0, d0, #1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: neon_sshll_vscalar_constant_shift:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr w9, [x0]
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: sshl d0, d0, d1
+; CHECK-GI-NEXT: ret
%tmp1 = load <1 x i32>, ptr %A
%tmp2 = zext <1 x i32> %tmp1 to <1 x i64>
%tmp3 = call <1 x i64> @llvm.aarch64.neon.sshl.v1i64(<1 x i64> %tmp2, <1 x i64> <i64 1>)
@@ -2823,13 +2846,23 @@ define <1 x i64> @neon_sshll_vscalar_constant_shift(ptr %A) nounwind {
}
define i64 @neon_sshll_scalar_constant_shift(ptr %A) nounwind {
-; CHECK-LABEL: neon_sshll_scalar_constant_shift:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr w8, [x0]
-; CHECK-NEXT: fmov d0, x8
-; CHECK-NEXT: shl d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: neon_sshll_scalar_constant_shift:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr w8, [x0]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: shl d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: neon_sshll_scalar_constant_shift:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr w9, [x0]
+; CHECK-GI-NEXT: mov w8, #1 // =0x1
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: sshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i32, ptr %A
%tmp2 = zext i32 %tmp1 to i64
%tmp3 = call i64 @llvm.aarch64.neon.sshl.i64(i64 %tmp2, i64 1)
@@ -2837,13 +2870,23 @@ define i64 @neon_sshll_scalar_constant_shift(ptr %A) nounwind {
}
define i64 @neon_sshll_scalar_constant_shift_m1(ptr %A) nounwind {
-; CHECK-LABEL: neon_sshll_scalar_constant_shift_m1:
-; CHECK: // %bb.0:
-; CHECK-NEXT: ldr w8, [x0]
-; CHECK-NEXT: fmov d0, x8
-; CHECK-NEXT: sshr d0, d0, #1
-; CHECK-NEXT: fmov x0, d0
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: neon_sshll_scalar_constant_shift_m1:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: ldr w8, [x0]
+; CHECK-SD-NEXT: fmov d0, x8
+; CHECK-SD-NEXT: sshr d0, d0, #1
+; CHECK-SD-NEXT: fmov x0, d0
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: neon_sshll_scalar_constant_shift_m1:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: ldr w9, [x0]
+; CHECK-GI-NEXT: mov x8, #-1 // =0xffffffffffffffff
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: sshl d0, d0, d1
+; CHECK-GI-NEXT: fmov x0, d0
+; CHECK-GI-NEXT: ret
%tmp1 = load i32, ptr %A
%tmp2 = zext i32 %tmp1 to i64
%tmp3 = call i64 @llvm.aarch64.neon.sshl.i64(i64 %tmp2, i64 -1)
>From 2177ce8816a425f400340c37206f494edf76ca0f Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Tue, 9 Dec 2025 09:47:32 +0000
Subject: [PATCH 07/20] [AArch64][GlobalISel] Cleaned up test checks
---
llvm/test/CodeGen/AArch64/arm64-int-neon.ll | 2 --
llvm/test/CodeGen/AArch64/neon-addlv.ll | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
index ace179626f508..e8ae8a3e53c9b 100644
--- a/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-int-neon.ll
@@ -228,5 +228,3 @@ 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/neon-addlv.ll b/llvm/test/CodeGen/AArch64/neon-addlv.ll
index a6d2dab8f5687..1897570ad2542 100644
--- a/llvm/test/CodeGen/AArch64/neon-addlv.ll
+++ b/llvm/test/CodeGen/AArch64/neon-addlv.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc -mtriple aarch64-none-linux-gnu -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+; RUN: llc -mtriple aarch64-none-linux-gnu -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
declare <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8>) nounwind readnone
declare <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8>) nounwind readnone
>From 74f88e80b88b68d8058fb7171803a2147f2b1a78 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Thu, 27 Nov 2025 15:34:40 +0000
Subject: [PATCH 08/20] [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 <josh.rodriguez at arm.com>
Date: Wed, 3 Dec 2025 16:44:30 +0000
Subject: [PATCH 09/20] [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 <josh.rodriguez at arm.com>
Date: Wed, 3 Dec 2025 16:54:42 +0000
Subject: [PATCH 10/20] [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 <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 11:09:04 +0000
Subject: [PATCH 11/20] [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 <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 11:36:46 +0000
Subject: [PATCH 12/20] [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 <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 14:27:47 +0000
Subject: [PATCH 13/20] [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 <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 15:19:35 +0000
Subject: [PATCH 14/20] [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 <josh.rodriguez at arm.com>
Date: Thu, 4 Dec 2025 16:36:19 +0000
Subject: [PATCH 15/20] [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 <josh.rodriguez at arm.com>
Date: Tue, 9 Dec 2025 10:34:35 +0000
Subject: [PATCH 16/20] [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: {
>From 45126ab7e3e62c0753f614557d953a8bc9529c56 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Wed, 10 Dec 2025 15:32:18 +0000
Subject: [PATCH 17/20] [AArch64][GlobalISel] Refactored Legaliser Changes
Early returns implemented where possible, in order to reduce
indentation.
---
.../AArch64/GISel/AArch64LegalizerInfo.cpp | 137 +++++++++---------
1 file changed, 68 insertions(+), 69 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 8951ccfbd3352..002c31fb39c2c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1858,82 +1858,82 @@ 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()});
- // 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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
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;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+ // 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();
+ return true;
}
case Intrinsic::aarch64_neon_sqshlu: {
// Check if last operand is constant vector dup
@@ -1945,9 +1945,8 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
.addImm(shiftAmount->getSExtValue());
MI.eraseFromParent();
return true;
- } else {
- return false;
}
+ return false;
}
case Intrinsic::aarch64_neon_abs: {
// Lower the intrinsic to G_ABS.
@@ -2598,4 +2597,4 @@ bool AArch64LegalizerInfo::legalizeFptrunc(MachineInstr &MI,
MRI.replaceRegWith(Dst, Fin);
MI.eraseFromParent();
return true;
-}
\ No newline at end of file
+}
>From 125fd3ea6c9109f983d07a0128d72ed2ec077186 Mon Sep 17 00:00:00 2001
From: Joshua Rodriguez <josh.rodriguez at arm.com>
Date: Thu, 11 Dec 2025 18:23:01 +0000
Subject: [PATCH 18/20] [GlobalISel][AArch64] Added support for sli/sri
intrinsics (#171448)
sli intrinsic now lowers correctly for all vector types.
---
llvm/lib/Target/AArch64/AArch64InstrGISel.td | 15 +++
.../AArch64/GISel/AArch64LegalizerInfo.cpp | 14 ++
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 4 +
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 126 +++++++++++++++---
4 files changed, 143 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 75354e4098fb4..48aee9ce7344b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -270,6 +270,18 @@ def G_URSHR: AArch64GenericInstruction {
let hasSideEffects = 0;
}
+def G_SLI: AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
+ let hasSideEffects = 0;
+}
+
+def G_SRI: AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
+ 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 {
@@ -322,6 +334,9 @@ def : GINodeEquiv<G_SQSHLU, AArch64sqshlui>;
def : GINodeEquiv<G_SRSHR, AArch64srshri>;
def : GINodeEquiv<G_URSHR, AArch64urshri>;
+def : GINodeEquiv<G_SLI, AArch64vsli>;
+def : GINodeEquiv<G_SRI, AArch64vsri>;
+
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 002c31fb39c2c..03386c829122a 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1948,6 +1948,20 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
}
return false;
}
+ case Intrinsic::aarch64_neon_vsli: {
+ MIB.buildInstr(
+ AArch64::G_SLI, {MI.getOperand(0)},
+ {MI.getOperand(2), MI.getOperand(3), MI.getOperand(4).getImm()});
+ MI.eraseFromParent();
+ break;
+ }
+ case Intrinsic::aarch64_neon_vsri: {
+ MIB.buildInstr(
+ AArch64::G_SRI, {MI.getOperand(0)},
+ {MI.getOperand(2), MI.getOperand(3), MI.getOperand(4).getImm()});
+ MI.eraseFromParent();
+ break;
+ }
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 84bc3f1e14a7a..44f8fd8ad6d35 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -575,6 +575,8 @@ bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
case TargetOpcode::G_LROUND:
case TargetOpcode::G_LLROUND:
case AArch64::G_PMULL:
+ case AArch64::G_SLI:
+ case AArch64::G_SRI:
return true;
case TargetOpcode::G_INTRINSIC:
switch (cast<GIntrinsic>(MI).getIntrinsicID()) {
@@ -613,6 +615,8 @@ bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
case TargetOpcode::G_INSERT_VECTOR_ELT:
case TargetOpcode::G_BUILD_VECTOR:
case TargetOpcode::G_BUILD_VECTOR_TRUNC:
+ case AArch64::G_SLI:
+ case AArch64::G_SRI:
return true;
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
switch (cast<GIntrinsic>(MI).getIntrinsicID()) {
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index a316a4bc543b5..29c06b8fa228c 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -2,16 +2,6 @@
; 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 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:
; CHECK: // %bb.0:
@@ -4288,6 +4278,110 @@ declare <8 x i16> @llvm.aarch64.neon.vsli.v8i16(<8 x i16>, <8 x i16>, i32) nounw
declare <4 x i32> @llvm.aarch64.neon.vsli.v4i32(<4 x i32>, <4 x i32>, i32) nounwind readnone
declare <2 x i64> @llvm.aarch64.neon.vsli.v2i64(<2 x i64>, <2 x i64>, i32) nounwind readnone
+define <8 x i8> @sri8b(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri8b:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sri v0.8b, v1.8b, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <8 x i8>, ptr %A
+ %tmp2 = load <8 x i8>, ptr %B
+ %tmp3 = call <8 x i8> @llvm.aarch64.neon.vsri.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2, i32 1)
+ ret <8 x i8> %tmp3
+}
+
+define <4 x i16> @sri4h(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri4h:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sri v0.4h, v1.4h, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <4 x i16>, ptr %A
+ %tmp2 = load <4 x i16>, ptr %B
+ %tmp3 = call <4 x i16> @llvm.aarch64.neon.vsri.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2, i32 1)
+ ret <4 x i16> %tmp3
+}
+
+define <2 x i32> @sri2s(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri2s:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sri v0.2s, v1.2s, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <2 x i32>, ptr %A
+ %tmp2 = load <2 x i32>, ptr %B
+ %tmp3 = call <2 x i32> @llvm.aarch64.neon.vsri.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2, i32 1)
+ ret <2 x i32> %tmp3
+}
+
+define <1 x i64> @sri1d(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri1d:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: ldr d1, [x1]
+; CHECK-NEXT: sri d0, d1, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <1 x i64>, ptr %A
+ %tmp2 = load <1 x i64>, ptr %B
+ %tmp3 = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> %tmp1, <1 x i64> %tmp2, i32 1)
+ ret <1 x i64> %tmp3
+}
+
+define <16 x i8> @sri16b(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri16b:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: ldr q1, [x1]
+; CHECK-NEXT: sri v0.16b, v1.16b, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <16 x i8>, ptr %A
+ %tmp2 = load <16 x i8>, ptr %B
+ %tmp3 = call <16 x i8> @llvm.aarch64.neon.vsri.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2, i32 1)
+ ret <16 x i8> %tmp3
+}
+
+define <8 x i16> @sri8h(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri8h:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: ldr q1, [x1]
+; CHECK-NEXT: sri v0.8h, v1.8h, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <8 x i16>, ptr %A
+ %tmp2 = load <8 x i16>, ptr %B
+ %tmp3 = call <8 x i16> @llvm.aarch64.neon.vsri.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2, i32 1)
+ ret <8 x i16> %tmp3
+}
+
+define <4 x i32> @sri4s(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri4s:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: ldr q1, [x1]
+; CHECK-NEXT: sri v0.4s, v1.4s, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <4 x i32>, ptr %A
+ %tmp2 = load <4 x i32>, ptr %B
+ %tmp3 = call <4 x i32> @llvm.aarch64.neon.vsri.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2, i32 1)
+ ret <4 x i32> %tmp3
+}
+
+define <2 x i64> @sri2d(ptr %A, ptr %B) nounwind {
+; CHECK-LABEL: sri2d:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: ldr q1, [x1]
+; CHECK-NEXT: sri v0.2d, v1.2d, #1
+; CHECK-NEXT: ret
+ %tmp1 = load <2 x i64>, ptr %A
+ %tmp2 = load <2 x i64>, ptr %B
+ %tmp3 = call <2 x i64> @llvm.aarch64.neon.vsri.v2i64(<2 x i64> %tmp1, <2 x i64> %tmp2, i32 1)
+ ret <2 x i64> %tmp3
+}
+
define <1 x i64> @ashr_v1i64(<1 x i64> %a, <1 x i64> %b) {
; CHECK-SD-LABEL: ashr_v1i64:
; CHECK-SD: // %bb.0:
@@ -4532,9 +4626,9 @@ define <4 x i16> @lshr_trunc_v4i64_v4i16(<4 x i64> %a) {
;
; CHECK-GI-LABEL: lshr_trunc_v4i64_v4i16:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI270_0
+; CHECK-GI-NEXT: adrp x8, .LCPI278_0
; CHECK-GI-NEXT: uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI270_0]
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI278_0]
; CHECK-GI-NEXT: uzp1 v2.4s, v2.4s, v2.4s
; CHECK-GI-NEXT: neg v1.4s, v2.4s
; CHECK-GI-NEXT: ushl v0.4s, v0.4s, v1.4s
@@ -4573,9 +4667,9 @@ define <4 x i16> @ashr_trunc_v4i64_v4i16(<4 x i64> %a) {
;
; CHECK-GI-LABEL: ashr_trunc_v4i64_v4i16:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI272_0
+; CHECK-GI-NEXT: adrp x8, .LCPI280_0
; CHECK-GI-NEXT: uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI272_0]
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI280_0]
; CHECK-GI-NEXT: uzp1 v2.4s, v2.4s, v2.4s
; CHECK-GI-NEXT: neg v1.4s, v2.4s
; CHECK-GI-NEXT: sshl v0.4s, v0.4s, v1.4s
@@ -4613,9 +4707,9 @@ define <4 x i16> @shl_trunc_v4i64_v4i16(<4 x i64> %a) {
;
; CHECK-GI-LABEL: shl_trunc_v4i64_v4i16:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI274_0
+; CHECK-GI-NEXT: adrp x8, .LCPI282_0
; CHECK-GI-NEXT: uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI274_0]
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI282_0]
; CHECK-GI-NEXT: uzp1 v1.4s, v2.4s, v2.4s
; CHECK-GI-NEXT: xtn v0.4h, v0.4s
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
>From 610176b4e0859adeefbd75867136441f65168498 Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Fri, 12 Dec 2025 11:49:01 +0000
Subject: [PATCH 19/20] [AArch64][GlobalISel] Formatting changes
---
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 6 +++---
llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 03386c829122a..982bb00d973dd 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1937,12 +1937,12 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
}
case Intrinsic::aarch64_neon_sqshlu: {
// Check if last operand is constant vector dup
- auto shiftAmount = isConstantOrConstantSplatVector(
+ auto ShiftAmount = isConstantOrConstantSplatVector(
*MRI.getVRegDef(MI.getOperand(3).getReg()), MRI);
- if (shiftAmount) {
+ 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());
+ .addImm(ShiftAmount->getSExtValue());
MI.eraseFromParent();
return true;
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 44f8fd8ad6d35..533789100c98d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -476,13 +476,11 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_facge:
case Intrinsic::aarch64_neon_facgt:
case Intrinsic::aarch64_neon_fabd:
- case Intrinsic::aarch64_sisd_fabd:
case Intrinsic::aarch64_neon_sqrdmlah:
case Intrinsic::aarch64_neon_sqrdmlsh:
case Intrinsic::aarch64_neon_sqrdmulh:
case Intrinsic::aarch64_neon_sqadd:
case Intrinsic::aarch64_neon_sqsub:
- case Intrinsic::aarch64_crypto_sha1h:
case Intrinsic::aarch64_neon_srshl:
case Intrinsic::aarch64_neon_urshl:
case Intrinsic::aarch64_neon_sqshl:
@@ -497,10 +495,12 @@ static bool isFPIntrinsic(const MachineRegisterInfo &MRI,
case Intrinsic::aarch64_neon_sqrshrun:
case Intrinsic::aarch64_neon_uqshrn:
case Intrinsic::aarch64_neon_uqrshrn:
+ case Intrinsic::aarch64_crypto_sha1h:
case Intrinsic::aarch64_crypto_sha1c:
case Intrinsic::aarch64_crypto_sha1p:
case Intrinsic::aarch64_crypto_sha1m:
case Intrinsic::aarch64_sisd_fcvtxn:
+ case Intrinsic::aarch64_sisd_fabd:
return true;
case Intrinsic::aarch64_neon_saddlv: {
const LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
>From fcc7cd1d7116693aec26ac599fb349b0baa8de0a Mon Sep 17 00:00:00 2001
From: Josh Rodriguez <josh.rodriguez at arm.com>
Date: Fri, 12 Dec 2025 16:01:57 +0000
Subject: [PATCH 20/20] [AArch64][GlobalISel] Renamed GI nodes describing
intrinsics with immediate offsets
In SDAG, nodes that expect an immediate offset end with _I. This is now reflected in GISel for the vector shifts.
---
llvm/lib/Target/AArch64/AArch64InstrGISel.td | 12 ++++++------
.../Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 8 ++++----
.../Target/AArch64/GISel/AArch64RegisterBankInfo.cpp | 2 +-
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 48aee9ce7344b..ba47a36be7307 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -252,19 +252,19 @@ def G_USDOT : AArch64GenericInstruction {
let hasSideEffects = 0;
}
-def G_SQSHLU : AArch64GenericInstruction {
+def G_SQSHLU_I : AArch64GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
let hasSideEffects = 0;
}
-def G_SRSHR: AArch64GenericInstruction {
+def G_SRSHR_I: AArch64GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
let hasSideEffects = 0;
}
-def G_URSHR: AArch64GenericInstruction {
+def G_URSHR_I: AArch64GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
let hasSideEffects = 0;
@@ -330,9 +330,9 @@ def : GINodeEquiv<G_UDOT, AArch64udot>;
def : GINodeEquiv<G_SDOT, AArch64sdot>;
def : GINodeEquiv<G_USDOT, AArch64usdot>;
-def : GINodeEquiv<G_SQSHLU, AArch64sqshlui>;
-def : GINodeEquiv<G_SRSHR, AArch64srshri>;
-def : GINodeEquiv<G_URSHR, AArch64urshri>;
+def : GINodeEquiv<G_SQSHLU_I, AArch64sqshlui>;
+def : GINodeEquiv<G_SRSHR_I, AArch64srshri>;
+def : GINodeEquiv<G_URSHR_I, AArch64urshri>;
def : GINodeEquiv<G_SLI, AArch64vsli>;
def : GINodeEquiv<G_SRI, AArch64vsri>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 982bb00d973dd..b60bdc7763153 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1888,7 +1888,7 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
return false;
// Create right shift instruction. Get v. register the output is written
// to
- auto Shr = MIB.buildInstr(AArch64::G_SRSHR,
+ auto Shr = MIB.buildInstr(AArch64::G_SRSHR_I,
{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
@@ -1901,7 +1901,7 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
return false;
// Create right shift instruction. Get v. register the output is written
// to
- auto Shr = MIB.buildInstr(AArch64::G_SRSHR,
+ auto Shr = MIB.buildInstr(AArch64::G_SRSHR_I,
{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
@@ -1914,7 +1914,7 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
return false;
// Create right shift instruction. Get v. register the output is written
// to
- auto Shr = MIB.buildInstr(AArch64::G_URSHR,
+ auto Shr = MIB.buildInstr(AArch64::G_URSHR_I,
{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
@@ -1941,7 +1941,7 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
*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)})
+ MIB.buildInstr(AArch64::G_SQSHLU_I, {MI.getOperand(0)}, {MI.getOperand(2)})
.addImm(ShiftAmount->getSExtValue());
MI.eraseFromParent();
return true;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 533789100c98d..2373dcf1ed4ab 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -1084,7 +1084,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// Index needs to be a GPR.
OpRegBankIdx[2] = PMI_FirstGPR;
break;
- case AArch64::G_SQSHLU:
+ case AArch64::G_SQSHLU_I:
// Destination and source need to be FPRs.
OpRegBankIdx[0] = PMI_FirstFPR;
OpRegBankIdx[1] = PMI_FirstFPR;
More information about the llvm-commits
mailing list