From 814d8b30da978ea8c178eb95a080b3c1d3ce4c54 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 11 Aug 2016 21:01:13 +0000 Subject: [PATCH] GlobalISel: add translation support for shift operations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278410 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/GlobalISel/IRTranslator.h | 23 ++++++++----- include/llvm/Target/GenericOpcodes.td | 21 ++++++++++++ include/llvm/Target/TargetOpcodes.def | 9 +++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 34 +++++++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 2c0662aeadc..59f1e07db55 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -144,6 +144,12 @@ private: /// \pre \p U is a branch instruction. bool translateBr(const User &U); + /// Translate return (ret) instruction. + /// The target needs to implement CallLowering::lowerReturn for + /// this to succeed. + /// \pre \p U is a return instruction. + bool translateRet(const User &U); + bool translateAdd(const User &U) { return translateBinaryOp(TargetOpcode::G_ADD, U); } @@ -184,11 +190,15 @@ private: return translateCast(TargetOpcode::G_ZEXT, U); } - /// Translate return (ret) instruction. - /// The target needs to implement CallLowering::lowerReturn for - /// this to succeed. - /// \pre \p U is a return instruction. - bool translateRet(const User &U); + bool translateShl(const User &U) { + return translateBinaryOp(TargetOpcode::G_SHL, U); + } + bool translateLShr(const User &U) { + return translateBinaryOp(TargetOpcode::G_LSHR, U); + } + bool translateAShr(const User &U) { + return translateBinaryOp(TargetOpcode::G_ASHR, U); + } // Stubs to keep the compiler happy while we implement the rest of the // translation. @@ -208,9 +218,6 @@ private: bool translateURem(const User &U) { return false; } bool translateSRem(const User &U) { return false; } bool translateFRem(const User &U) { return false; } - bool translateShl(const User &U) { return false; } - bool translateLShr(const User &U) { return false; } - bool translateAShr(const User &U) { return false; } bool translateGetElementPtr(const User &U) { return false; } bool translateFence(const User &U) { return false; } bool translateAtomicCmpXchg(const User &U) { return false; } diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index d963f62efa0..ade3577199b 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -139,6 +139,27 @@ def G_XOR : Instruction { let isCommutable = 1; } +// Generic left-shift. +def G_SHL : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; +} + +// Generic logical right-shift. +def G_LSHR : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; +} + +// Generic arithmetic right-shift. +def G_ASHR : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Memory ops //------------------------------------------------------------------------------ diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index c8997f65d3c..4fe56d021da 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -238,6 +238,15 @@ HANDLE_TARGET_OPCODE(G_SEXT) // Generic zero extend HANDLE_TARGET_OPCODE(G_ZEXT) +// Generic left-shift +HANDLE_TARGET_OPCODE(G_SHL) + +// Generic logical right-shift +HANDLE_TARGET_OPCODE(G_LSHR) + +// Generic arithmetic right-shift +HANDLE_TARGET_OPCODE(G_ASHR) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index ef1f6fd444e..68ac9fa11e2 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -424,3 +424,37 @@ define i64 @test_zext(i32 %in) { %res = zext i32 %in to i64 ret i64 %res } + +; CHECK-LABEL: name: test_shl +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SHL s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_shl(i32 %arg1, i32 %arg2) { + %res = shl i32 %arg1, %arg2 + ret i32 %res +} + + +; CHECK-LABEL: name: test_lshr +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_LSHR s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_lshr(i32 %arg1, i32 %arg2) { + %res = lshr i32 %arg1, %arg2 + ret i32 %res +} + +; CHECK-LABEL: name: test_ashr +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_ASHR s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_ashr(i32 %arg1, i32 %arg2) { + %res = ashr i32 %arg1, %arg2 + ret i32 %res +}