From: Daniel Sanders Date: Tue, 19 Sep 2017 14:25:15 +0000 (+0000) Subject: [globalisel] Add a G_BSWAP instruction and support bswap using it. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68b21d6108df63d65d6735e9686d53cca844e37a;p=llvm [globalisel] Add a G_BSWAP instruction and support bswap using it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313633 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index aef088a1dfb..557c1dc15c6 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -118,6 +118,12 @@ def G_VAARG : Instruction { let mayStore = 1; } +def G_BSWAP : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ diff --git a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index a770951e726..f6da58ba796 100644 --- a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -70,6 +70,7 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. // Should be used on defs that subclass GIComplexOperandMatcher<>. diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 3ecb8b5f647..c2654be7bf4 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -427,12 +427,15 @@ HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT) /// Generic shufflevector. HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR) +/// Generic byte swap. +HANDLE_TARGET_OPCODE(G_BSWAP) + // TODO: Add more generic opcodes as we move along. /// Marker for the end of the generic opcode. /// This is used to check if an opcode is in the range of the /// generic opcodes. -HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_SHUFFLE_VECTOR) +HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BSWAP) /// BUILTIN_OP_END - This must be the last enum value in this list. /// The target-specific post-isel opcode values start here. diff --git a/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/lib/Target/AArch64/AArch64LegalizerInfo.cpp index e28e43acba1..380668d7bd8 100644 --- a/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -44,6 +44,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() { for (auto Ty : {s1, s8}) setAction({G_PHI, Ty}, WidenScalar); + for (auto Ty : { s32, s64 }) + setAction({G_BSWAP, Ty}, Legal); + for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) { // These operations naturally get the right answer when used on // GPR32, even if the actual type is narrower. diff --git a/test/CodeGen/AArch64/GlobalISel/select-bswap.mir b/test/CodeGen/AArch64/GlobalISel/select-bswap.mir new file mode 100644 index 00000000000..56a964f106c --- /dev/null +++ b/test/CodeGen/AArch64/GlobalISel/select-bswap.mir @@ -0,0 +1,60 @@ +# RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s + +--- | + target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + + define void @bswap_s32() { ret void } + define void @bswap_s64() { ret void } +... + +--- +# CHECK-LABEL: name: bswap_s32 +name: bswap_s32 +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32, preferred-register: '' } +# CHECK-NEXT: - { id: 1, class: gpr32, preferred-register: '' } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = REVWr %0 +# CHECK: %w0 = COPY %1 +body: | + bb.0: + liveins: %w0 + + %0(s32) = COPY %w0 + %1(s32) = G_BSWAP %0 + %w0 = COPY %1 +... + +--- +# CHECK-LABEL: name: bswap_s64 +name: bswap_s64 +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr64, preferred-register: '' } +# CHECK-NEXT: - { id: 1, class: gpr64, preferred-register: '' } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %x0 +# CHECK: %1 = REVXr %0 +# CHECK: %x0 = COPY %1 +body: | + bb.0: + liveins: %x0 + + %0(s64) = COPY %x0 + %1(s64) = G_BSWAP %0 + %x0 = COPY %1 +...