diff options
author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-08-18 15:17:01 +0000 |
---|---|---|
committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-08-18 15:17:01 +0000 |
commit | 13db94540ca2647e6ee9577910f1fc2c1aedf32b (patch) | |
tree | 1dc62abac8cc380adfcef8512138fa54d380a885 | |
parent | 5b112845daf87b34530d3a2c06463bca7c6768ae (diff) | |
download | bcm5719-llvm-13db94540ca2647e6ee9577910f1fc2c1aedf32b.tar.gz bcm5719-llvm-13db94540ca2647e6ee9577910f1fc2c1aedf32b.zip |
[GlobalISel] Add support for DIV/REM.
llvm-svn: 279073
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h | 18 | ||||
-rw-r--r-- | llvm/include/llvm/Target/GenericOpcodes.td | 32 | ||||
-rw-r--r-- | llvm/include/llvm/Target/TargetOpcodes.def | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/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 21a0a85e12d..62c76e99122 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<AllocaInst>(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 4221b82886e..79a76579562 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 9f485c6b542..6e5a5a6f48b 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 18c38fb6816..d2ecf3a104e 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]] |