Skip to content

[AArch64][GlobalISel] Select SHL({Z|S}EXT, DUP Imm) into {U|S}HLL Imm #96782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,13 @@ def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{
let ParserMatchClass = Imm1_7Operand;
}

// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
def imm32_0_7 : Operand<i32>, ImmLeaf<i32, [{
return ((uint32_t)Imm) < 8;
}]> {
let ParserMatchClass = Imm0_7Operand;
}

// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
return ((uint32_t)Imm) < 16;
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -8129,6 +8129,20 @@ def : Pat<(v4i32 (concat_vectors (v2i32 V64:$Rd),
(SHRNv4i32_shift (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
V128:$Rn, vecshiftR32Narrow:$imm)>;

def : Pat<(shl (v8i16 (zext (v8i8 V64:$Rm))), (v8i16 (AArch64dup (i32 imm32_0_7:$size)))),
(USHLLv8i8_shift V64:$Rm, (i32 imm32_0_7:$size))>;
def : Pat<(shl (v4i32 (zext (v4i16 V64:$Rm))), (v4i32 (AArch64dup (i32 imm32_0_15:$size)))),
(USHLLv4i16_shift V64:$Rm, (i32 imm32_0_15:$size))>;
def : Pat<(shl (v2i64 (zext (v2i32 V64:$Rm))), (v2i64 (AArch64dup (i64 imm0_31:$size)))),
(USHLLv2i32_shift V64:$Rm, (trunc_imm imm0_31:$size))>;

def : Pat<(shl (v8i16 (sext (v8i8 V64:$Rm))), (v8i16 (AArch64dup (i32 imm32_0_7:$size)))),
(SSHLLv8i8_shift V64:$Rm, (i32 imm32_0_7:$size))>;
def : Pat<(shl (v4i32 (sext (v4i16 V64:$Rm))), (v4i32 (AArch64dup (i32 imm32_0_15:$size)))),
(SSHLLv4i16_shift V64:$Rm, (i32 imm32_0_15:$size))>;
def : Pat<(shl (v2i64 (sext (v2i32 V64:$Rm))), (v2i64 (AArch64dup (i64 imm0_31:$size)))),
(SSHLLv2i32_shift V64:$Rm, (trunc_imm imm0_31:$size))>;

// Vector sign and zero extensions are implemented with SSHLL and USSHLL.
// Anyexts are implemented as zexts.
def : Pat<(v8i16 (sext (v8i8 V64:$Rn))), (SSHLLv8i8_shift V64:$Rn, (i32 0))>;
Expand Down
108 changes: 36 additions & 72 deletions llvm/test/CodeGen/AArch64/neon-shift-left-long.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,10 @@
; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI

define <8 x i16> @test_sshll_v8i8(<8 x i8> %a) {
; CHECK-SD-LABEL: test_sshll_v8i8:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.8h, v0.8b, #3
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_sshll_v8i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: shl v0.8h, v0.8h, #3
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_sshll_v8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.8h, v0.8b, #3
; CHECK-NEXT: ret
%1 = sext <8 x i8> %a to <8 x i16>
%tmp = shl <8 x i16> %1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
ret <8 x i16> %tmp
Expand All @@ -36,16 +30,10 @@ define <8 x i16> @test_sshll_v8i8_big(<8 x i8> %a) {
}

define <4 x i32> @test_sshll_v4i16(<4 x i16> %a) {
; CHECK-SD-LABEL: test_sshll_v4i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.4s, v0.4h, #9
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_sshll_v4i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #9
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_sshll_v4i16:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.4s, v0.4h, #9
; CHECK-NEXT: ret
%1 = sext <4 x i16> %a to <4 x i32>
%tmp = shl <4 x i32> %1, <i32 9, i32 9, i32 9, i32 9>
ret <4 x i32> %tmp
Expand All @@ -69,16 +57,10 @@ define <4 x i32> @test_sshll_v4i16_big(<4 x i16> %a) {
}

define <2 x i64> @test_sshll_v2i32(<2 x i32> %a) {
; CHECK-SD-LABEL: test_sshll_v2i32:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.2d, v0.2s, #19
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_sshll_v2i32:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
; CHECK-GI-NEXT: shl v0.2d, v0.2d, #19
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_sshll_v2i32:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.2d, v0.2s, #19
; CHECK-NEXT: ret
%1 = sext <2 x i32> %a to <2 x i64>
%tmp = shl <2 x i64> %1, <i64 19, i64 19>
ret <2 x i64> %tmp
Expand All @@ -102,16 +84,10 @@ define <2 x i64> @test_sshll_v2i32_big(<2 x i32> %a) {
}

define <8 x i16> @test_ushll_v8i8(<8 x i8> %a) {
; CHECK-SD-LABEL: test_ushll_v8i8:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #3
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_ushll_v8i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: shl v0.8h, v0.8h, #3
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_ushll_v8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.8h, v0.8b, #3
; CHECK-NEXT: ret
%1 = zext <8 x i8> %a to <8 x i16>
%tmp = shl <8 x i16> %1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
ret <8 x i16> %tmp
Expand All @@ -129,16 +105,10 @@ define <8 x i16> @test_ushll_v8i8_big(<8 x i8> %a) {
}

define <4 x i32> @test_ushll_v4i16(<4 x i16> %a) {
; CHECK-SD-LABEL: test_ushll_v4i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #9
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_ushll_v4i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #9
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_ushll_v4i16:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.4s, v0.4h, #9
; CHECK-NEXT: ret
%1 = zext <4 x i16> %a to <4 x i32>
%tmp = shl <4 x i32> %1, <i32 9, i32 9, i32 9, i32 9>
ret <4 x i32> %tmp
Expand All @@ -156,16 +126,10 @@ define <4 x i32> @test_ushll_v4i16_big(<4 x i16> %a) {
}

define <2 x i64> @test_ushll_v2i32(<2 x i32> %a) {
; CHECK-SD-LABEL: test_ushll_v2i32:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.2d, v0.2s, #19
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_ushll_v2i32:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.2d, v0.2s, #0
; CHECK-GI-NEXT: shl v0.2d, v0.2d, #19
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_ushll_v2i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.2d, v0.2s, #19
; CHECK-NEXT: ret
%1 = zext <2 x i32> %a to <2 x i64>
%tmp = shl <2 x i64> %1, <i64 19, i64 19>
ret <2 x i64> %tmp
Expand All @@ -190,8 +154,8 @@ define <8 x i16> @test_sshll2_v16i8(<16 x i8> %a) {
;
; CHECK-GI-LABEL: test_sshll2_v16i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll2 v0.8h, v0.16b, #0
; CHECK-GI-NEXT: shl v0.8h, v0.8h, #3
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #3
; CHECK-GI-NEXT: ret
%1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
%2 = sext <8 x i8> %1 to <8 x i16>
Expand Down Expand Up @@ -225,8 +189,8 @@ define <4 x i32> @test_sshll2_v8i16(<8 x i16> %a) {
;
; CHECK-GI-LABEL: test_sshll2_v8i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll2 v0.4s, v0.8h, #0
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #9
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: sshll v0.4s, v0.4h, #9
; CHECK-GI-NEXT: ret
%1 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
%2 = sext <4 x i16> %1 to <4 x i32>
Expand Down Expand Up @@ -260,8 +224,8 @@ define <2 x i64> @test_sshll2_v4i32(<4 x i32> %a) {
;
; CHECK-GI-LABEL: test_sshll2_v4i32:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll2 v0.2d, v0.4s, #0
; CHECK-GI-NEXT: shl v0.2d, v0.2d, #19
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #19
; CHECK-GI-NEXT: ret
%1 = shufflevector <4 x i32> %a, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%2 = sext <2 x i32> %1 to <2 x i64>
Expand Down Expand Up @@ -295,8 +259,8 @@ define <8 x i16> @test_ushll2_v16i8(<16 x i8> %a) {
;
; CHECK-GI-LABEL: test_ushll2_v16i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll2 v0.8h, v0.16b, #0
; CHECK-GI-NEXT: shl v0.8h, v0.8h, #3
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: ushll v0.8h, v0.8b, #3
; CHECK-GI-NEXT: ret
%1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
%2 = zext <8 x i8> %1 to <8 x i16>
Expand Down Expand Up @@ -324,8 +288,8 @@ define <4 x i32> @test_ushll2_v8i16(<8 x i16> %a) {
;
; CHECK-GI-LABEL: test_ushll2_v8i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll2 v0.4s, v0.8h, #0
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #9
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #9
; CHECK-GI-NEXT: ret
%1 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
%2 = zext <4 x i16> %1 to <4 x i32>
Expand Down Expand Up @@ -353,8 +317,8 @@ define <2 x i64> @test_ushll2_v4i32(<4 x i32> %a) {
;
; CHECK-GI-LABEL: test_ushll2_v4i32:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll2 v0.2d, v0.4s, #0
; CHECK-GI-NEXT: shl v0.2d, v0.2d, #19
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: ushll v0.2d, v0.2s, #19
; CHECK-GI-NEXT: ret
%1 = shufflevector <4 x i32> %a, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%2 = zext <2 x i32> %1 to <2 x i64>
Expand Down
Loading