From 13db94540ca2647e6ee9577910f1fc2c1aedf32b Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Thu, 18 Aug 2016 15:17:01 +0000 Subject: [PATCH] [GlobalISel] Add support for DIV/REM. llvm-svn: 279073 --- .../include/llvm/CodeGen/GlobalISel/IRTranslator.h | 18 +++++++-- llvm/include/llvm/Target/GenericOpcodes.td | 32 ++++++++++++++++ llvm/include/llvm/Target/TargetOpcodes.def | 12 ++++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 44 ++++++++++++++++++++++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 21a0a85..62c76e9 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -171,6 +171,20 @@ private: bool translateXor(const User &U) { return translateBinaryOp(TargetOpcode::G_XOR, U); } + + bool translateUDiv(const User &U) { + return translateBinaryOp(TargetOpcode::G_UDIV, U); + } + bool translateSDiv(const User &U) { + return translateBinaryOp(TargetOpcode::G_SDIV, U); + } + bool translateURem(const User &U) { + return translateBinaryOp(TargetOpcode::G_UREM, U); + } + bool translateSRem(const User &U) { + return translateBinaryOp(TargetOpcode::G_SREM, U); + } + bool translateAlloca(const User &U) { return translateStaticAlloca(cast(U)); } @@ -215,11 +229,7 @@ private: bool translateFAdd(const User &U) { return false; } bool translateFSub(const User &U) { return false; } bool translateFMul(const User &U) { return false; } - bool translateUDiv(const User &U) { return false; } - bool translateSDiv(const User &U) { return false; } bool translateFDiv(const User &U) { return false; } - bool translateURem(const User &U) { return false; } - bool translateSRem(const User &U) { return false; } bool translateFRem(const User &U) { return false; } bool translateGetElementPtr(const User &U) { return false; } bool translateFence(const User &U) { return false; } diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 4221b82..79a7657 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -107,6 +107,38 @@ def G_MUL : Instruction { let isCommutable = 1; } +// Generic signed division. +def G_SDIV : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 0; +} + +// Generic unsigned division. +def G_UDIV : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 0; +} + +// Generic signed remainder. +def G_SREM : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 0; +} + +// Generic unsigned remainder. +def G_UREM : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 0; +} + // Generic addition consuming and producing a carry flag. def G_ADDE : Instruction { let OutOperandList = (outs unknown:$dst, unknown:$carry_out); diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index 9f485c6..6e5a5a6 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/include/llvm/Target/TargetOpcodes.def @@ -173,6 +173,18 @@ HANDLE_TARGET_OPCODE(G_SUB) // Generic multiply instruction. HANDLE_TARGET_OPCODE(G_MUL) +// Generic signed division instruction. +HANDLE_TARGET_OPCODE(G_SDIV) + +// Generic unsigned division instruction. +HANDLE_TARGET_OPCODE(G_UDIV) + +// Generic signed remainder instruction. +HANDLE_TARGET_OPCODE(G_SREM) + +// Generic unsigned remainder instruction. +HANDLE_TARGET_OPCODE(G_UREM) + /// Generic bitwise and instruction. HANDLE_TARGET_OPCODE(G_AND) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 18c38fb..d2ecf3a1 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -459,6 +459,50 @@ define i32 @test_ashr(i32 %arg1, i32 %arg2) { ret i32 %res } +; CHECK-LABEL: name: test_sdiv +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SDIV s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_sdiv(i32 %arg1, i32 %arg2) { + %res = sdiv i32 %arg1, %arg2 + ret i32 %res +} + +; CHECK-LABEL: name: test_udiv +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_UDIV s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_udiv(i32 %arg1, i32 %arg2) { + %res = udiv i32 %arg1, %arg2 + ret i32 %res +} + +; CHECK-LABEL: name: test_srem +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SREM s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_srem(i32 %arg1, i32 %arg2) { + %res = srem i32 %arg1, %arg2 + ret i32 %res +} + +; CHECK-LABEL: name: test_urem +; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 +; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 +; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_UREM s32 [[ARG1]], [[ARG2]] +; CHECK-NEXT: %w0 = COPY [[RES]] +; CHECK-NEXT: RET_ReallyLR implicit %w0 +define i32 @test_urem(i32 %arg1, i32 %arg2) { + %res = urem i32 %arg1, %arg2 + ret i32 %res +} + ; CHECK-LABEL: name: test_constant_null ; CHECK: [[NULL:%[0-9]+]](64) = G_CONSTANT p0 0 ; CHECK: %x0 = COPY [[NULL]] -- 2.7.4