diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -669,6 +669,9 @@ .scalarize(1); getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).lower(); + // TODO: Custom lowering for v2s32, v4s32, v2s64. + getActionDefinitionsBuilder(G_BITREVERSE).legalFor({s32, s64, v8s8, v16s8}); + getActionDefinitionsBuilder(G_SHUFFLE_VECTOR) .legalIf([=](const LegalityQuery &Query) { const LLT &DstTy = Query.Types[0]; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitreverse.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitreverse.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitreverse.mir @@ -0,0 +1,68 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple aarch64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s + +... +--- +name: s32_legal +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: s32_legal + ; CHECK: %copy:_(s32) = COPY $w0 + ; CHECK: %bitreverse:_(s32) = G_BITREVERSE %copy + ; CHECK: $w0 = COPY %bitreverse(s32) + ; CHECK: RET_ReallyLR implicit $w0 + %copy:_(s32) = COPY $w0 + %bitreverse:_(s32) = G_BITREVERSE %copy + $w0 = COPY %bitreverse + RET_ReallyLR implicit $w0 +... +--- +name: s64_legal +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: s64_legal + ; CHECK: %copy:_(s64) = COPY $x0 + ; CHECK: %bitreverse:_(s64) = G_BITREVERSE %copy + ; CHECK: $x0 = COPY %bitreverse(s64) + ; CHECK: RET_ReallyLR implicit $x0 + %copy:_(s64) = COPY $x0 + %bitreverse:_(s64) = G_BITREVERSE %copy + $x0 = COPY %bitreverse + RET_ReallyLR implicit $x0 +... +--- +name: v8s8_legal +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: v8s8_legal + ; CHECK: %vec:_(<8 x s8>) = G_IMPLICIT_DEF + ; CHECK: %bitreverse:_(<8 x s8>) = G_BITREVERSE %vec + ; CHECK: $x0 = COPY %bitreverse(<8 x s8>) + ; CHECK: RET_ReallyLR implicit $x0 + %vec:_(<8 x s8>) = G_IMPLICIT_DEF + %bitreverse:_(<8 x s8>) = G_BITREVERSE %vec + $x0 = COPY %bitreverse + RET_ReallyLR implicit $x0 +... +--- +name: v16s8_legal +tracksRegLiveness: true +body: | + bb.0: + liveins: $q0 + ; CHECK-LABEL: name: v16s8_legal + ; CHECK: %vec:_(<16 x s8>) = G_IMPLICIT_DEF + ; CHECK: %bitreverse:_(<16 x s8>) = G_BITREVERSE %vec + ; CHECK: $q0 = COPY %bitreverse(<16 x s8>) + ; CHECK: RET_ReallyLR implicit $q0 + %vec:_(<16 x s8>) = G_IMPLICIT_DEF + %bitreverse:_(<16 x s8>) = G_BITREVERSE %vec + $q0 = COPY %bitreverse + RET_ReallyLR implicit $q0 +... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -558,8 +558,8 @@ # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_BITREVERSE (opcode {{[0-9]+}}): 1 type index, 0 imm indices -# 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: 1, OK +# DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FCEIL (opcode {{[0-9]+}}): 1 type index, 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 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitreverse.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitreverse.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitreverse.mir @@ -0,0 +1,88 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple aarch64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s + +... +--- +name: s32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + + ; CHECK-LABEL: name: s32 + ; CHECK: liveins: $w0 + ; CHECK: %copy:gpr32 = COPY $w0 + ; CHECK: %bitreverse:gpr32 = RBITWr %copy + ; CHECK: $w0 = COPY %bitreverse + ; CHECK: RET_ReallyLR implicit $w0 + %copy:gpr(s32) = COPY $w0 + %bitreverse:gpr(s32) = G_BITREVERSE %copy + $w0 = COPY %bitreverse(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: s64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + + ; CHECK-LABEL: name: s64 + ; CHECK: liveins: $x0 + ; CHECK: %copy:gpr64 = COPY $x0 + ; CHECK: %bitreverse:gpr64 = RBITXr %copy + ; CHECK: $x0 = COPY %bitreverse + ; CHECK: RET_ReallyLR implicit $x0 + %copy:gpr(s64) = COPY $x0 + %bitreverse:gpr(s64) = G_BITREVERSE %copy + $x0 = COPY %bitreverse(s64) + RET_ReallyLR implicit $x0 + +... +--- +name: v8s8_legal +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + + ; CHECK-LABEL: name: v8s8_legal + ; CHECK: liveins: $x0 + ; CHECK: %vec:fpr64 = IMPLICIT_DEF + ; CHECK: %bitreverse:fpr64 = RBITv8i8 %vec + ; CHECK: $x0 = COPY %bitreverse + ; CHECK: RET_ReallyLR implicit $x0 + %vec:fpr(<8 x s8>) = G_IMPLICIT_DEF + %bitreverse:fpr(<8 x s8>) = G_BITREVERSE %vec + $x0 = COPY %bitreverse(<8 x s8>) + RET_ReallyLR implicit $x0 + +... +--- +name: v16s8_legal +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $q0 + + ; CHECK-LABEL: name: v16s8_legal + ; CHECK: liveins: $q0 + ; CHECK: %vec:fpr128 = IMPLICIT_DEF + ; CHECK: %bitreverse:fpr128 = RBITv16i8 %vec + ; CHECK: $q0 = COPY %bitreverse + ; CHECK: RET_ReallyLR implicit $q0 + %vec:fpr(<16 x s8>) = G_IMPLICIT_DEF + %bitreverse:fpr(<16 x s8>) = G_BITREVERSE %vec + $q0 = COPY %bitreverse(<16 x s8>) + RET_ReallyLR implicit $q0 + +...