From 30e67ce7934bab156f374b02d8451bed7a5c5402 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. llvm-svn: 278410 --- .../include/llvm/CodeGen/GlobalISel/IRTranslator.h | 23 ++++++++++----- llvm/include/llvm/Target/GenericOpcodes.td | 21 +++++++++++++ llvm/include/llvm/Target/TargetOpcodes.def | 9 ++++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 34 ++++++++++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 2c0662a..59f1e07 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/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/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index d963f62..ade3577 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/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/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index c8997f6..4fe56d0 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/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/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index ef1f6fd..68ac9fa 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/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 +} -- 2.7.4