Skip to content

[GlobalISel][AArch64] Legalize G_EXTRACT_SUBVECTOR #112946

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
Oct 19, 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
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
def : GINodeEquiv<G_INSERT_VECTOR_ELT, vector_insert>;
def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
def : GINodeEquiv<G_BUILD_VECTOR, build_vector>;
def : GINodeEquiv<G_EXTRACT_SUBVECTOR, extract_subvector>;
def : GINodeEquiv<G_FCEIL, fceil>;
def : GINodeEquiv<G_FCOS, fcos>;
def : GINodeEquiv<G_FSIN, fsin>;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,11 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)

getActionDefinitionsBuilder({G_SCMP, G_UCMP}).lower();

getActionDefinitionsBuilder(G_EXTRACT_SUBVECTOR)
.legalFor({{v8s8, v16s8}, {v4s16, v8s16}, {v2s32, v4s32}})
.widenScalarOrEltToNextPow2(0)
.immIdx(0); // Inform verifier imm idx 0 is handled.
Copy link
Contributor

@arsenm arsenm Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

immIdx won't do anything here, just remove it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get verification errors before finding immIdx. G_MEMCPY and family also use it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verification errors? Do you mean the covered rule log?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 getLegacyLegalizerInfo().computeTables();
  verify(*ST.getInstrInfo());

Yes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the log was FAIL which was supposed to be OK for G_EXTRACT_SUBVECTOR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider that to be a bug in the verify


getLegacyLegalizerInfo().computeTables();
verify(*ST.getInstrInfo());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,8 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_EXTRACT_SUBVECTOR (opcode {{[0-9]+}}): 2 type indices, 1 imm index
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 1, OK
# DEBUG-NEXT: G_INSERT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
Expand Down
161 changes: 116 additions & 45 deletions llvm/test/CodeGen/AArch64/extract-subvec-combine.ll
Original file line number Diff line number Diff line change
@@ -1,62 +1,100 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK
; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI

define <2 x i32> @and_extract_zext_idx0(<4 x i16> %vec) nounwind {
; CHECK-LABEL: and_extract_zext_idx0:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: and_extract_zext_idx0:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_extract_zext_idx0:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: movi d1, #0x00ffff0000ffff
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-GI-NEXT: ret
%zext = zext <4 x i16> %vec to <4 x i32>
%extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
%and = and <2 x i32> %extract, <i32 65535, i32 65535>
ret <2 x i32> %and
}

define <4 x i16> @and_extract_sext_idx0(<8 x i8> %vec) nounwind {
; CHECK-LABEL: and_extract_sext_idx0:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: and_extract_sext_idx0:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_extract_sext_idx0:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: movi d1, #0xff00ff00ff00ff
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-GI-NEXT: ret
%sext = sext <8 x i8> %vec to <8 x i16>
%extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 0)
%and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
ret <4 x i16> %and
}

define <2 x i32> @and_extract_zext_idx2(<4 x i16> %vec) nounwind {
; CHECK-LABEL: and_extract_zext_idx2:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: and_extract_zext_idx2:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_extract_zext_idx2:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: movi d1, #0x00ffff0000ffff
; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-GI-NEXT: ret
%zext = zext <4 x i16> %vec to <4 x i32>
%extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 2)
%and = and <2 x i32> %extract, <i32 65535, i32 65535>
ret <2 x i32> %and
}

define <4 x i16> @and_extract_sext_idx4(<8 x i8> %vec) nounwind {
; CHECK-LABEL: and_extract_sext_idx4:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: and_extract_sext_idx4:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_extract_sext_idx4:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: movi d1, #0xff00ff00ff00ff
; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-GI-NEXT: ret
%sext = sext <8 x i8> %vec to <8 x i16>
%extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 4)
%and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
ret <4 x i16> %and
}

define <2 x i32> @sext_extract_zext_idx0(<4 x i16> %vec) nounwind {
; CHECK-LABEL: sext_extract_zext_idx0:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.4s, v0.4h, #0
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: sext_extract_zext_idx0:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.4s, v0.4h, #0
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sext_extract_zext_idx0:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: shl v0.2s, v0.2s, #16
; CHECK-GI-NEXT: sshr v0.2s, v0.2s, #16
; CHECK-GI-NEXT: ret
%zext = zext <4 x i16> %vec to <4 x i32>
%extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
%sext_inreg_step0 = shl <2 x i32> %extract, <i32 16, i32 16>
Expand All @@ -80,11 +118,18 @@ define <2 x i32> @sext_extract_zext_idx0_negtest(<4 x i16> %vec) nounwind {
}

define <4 x i16> @sext_extract_sext_idx0(<8 x i8> %vec) nounwind {
; CHECK-LABEL: sext_extract_sext_idx0:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: sext_extract_sext_idx0:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sext_extract_sext_idx0:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: shl v0.4h, v0.4h, #8
; CHECK-GI-NEXT: sshr v0.4h, v0.4h, #8
; CHECK-GI-NEXT: ret
%sext = sext <8 x i8> %vec to <8 x i16>
%extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 0)
%sext_inreg_step0 = shl <4 x i16> %extract, <i16 8, i16 8, i16 8, i16 8>
Expand All @@ -93,12 +138,20 @@ define <4 x i16> @sext_extract_sext_idx0(<8 x i8> %vec) nounwind {
}

define <2 x i32> @sext_extract_zext_idx2(<4 x i16> %vec) nounwind {
; CHECK-LABEL: sext_extract_zext_idx2:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.4s, v0.4h, #0
; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: sext_extract_zext_idx2:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.4s, v0.4h, #0
; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sext_extract_zext_idx2:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: shl v0.2s, v0.2s, #16
; CHECK-GI-NEXT: sshr v0.2s, v0.2s, #16
; CHECK-GI-NEXT: ret
%zext = zext <4 x i16> %vec to <4 x i32>
%extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 2)
%sext_inreg_step0 = shl <2 x i32> %extract, <i32 16, i32 16>
Expand All @@ -107,18 +160,36 @@ define <2 x i32> @sext_extract_zext_idx2(<4 x i16> %vec) nounwind {
}

define <4 x i16> @sext_extract_sext_idx4(<8 x i8> %vec) nounwind {
; CHECK-LABEL: sext_extract_sext_idx4:
; CHECK: // %bb.0:
; CHECK-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
; CHECK-SD-LABEL: sext_extract_sext_idx4:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sext_extract_sext_idx4:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: sshll v0.8h, v0.8b, #0
; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: shl v0.4h, v0.4h, #8
; CHECK-GI-NEXT: sshr v0.4h, v0.4h, #8
; CHECK-GI-NEXT: ret
%sext = sext <8 x i8> %vec to <8 x i16>
%extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 4)
%sext_inreg_step0 = shl <4 x i16> %extract, <i16 8, i16 8, i16 8, i16 8>
%sext_inreg = ashr <4 x i16> %sext_inreg_step0, <i16 8, i16 8, i16 8, i16 8>
ret <4 x i16> %sext_inreg
}

define <8 x i8> @sext_extract_idx(<16 x i8> %vec) nounwind {
; CHECK-LABEL: sext_extract_idx:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-NEXT: ret
%extract = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> %vec, i64 0)
ret <8 x i8> %extract
}

declare <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32>, i64)
declare <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16>, i64)
declare <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8>, i64)
Loading