[llvm] r238757 - [mips][FastISel] Implement srem/urem and sdiv/udiv instructions.
Vasileios Kalintiris
Vasileios.Kalintiris at imgtec.com
Mon Jun 1 09:17:37 PDT 2015
Author: vkalintiris
Date: Mon Jun 1 11:17:37 2015
New Revision: 238757
URL: http://llvm.org/viewvc/llvm-project?rev=238757&view=rev
Log:
[mips][FastISel] Implement srem/urem and sdiv/udiv instructions.
Summary: Implement the LLVM assembly urem/srem and sdiv/udiv instructions in MIPS FastISel.
Based on a patch by Reed Kotler.
Test Plan:
srem1.ll
div1.ll
test-suite at O0/O2 for mips32 r1/r2
Reviewers: dsanders, rkotler
Subscribers: llvm-commits, rfuhler
Differential Revision: http://reviews.llvm.org/D7028
Added:
llvm/trunk/test/CodeGen/Mips/Fast-ISel/div1.ll
llvm/trunk/test/CodeGen/Mips/Fast-ISel/rem1.ll
Modified:
llvm/trunk/lib/Target/Mips/MipsFastISel.cpp
Modified: llvm/trunk/lib/Target/Mips/MipsFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsFastISel.cpp?rev=238757&r1=238756&r2=238757&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp Mon Jun 1 11:17:37 2015
@@ -103,6 +103,7 @@ private:
bool selectTrunc(const Instruction *I);
bool selectIntExt(const Instruction *I);
bool selectShift(const Instruction *I);
+ bool selectDivRem(const Instruction *I, unsigned ISDOpcode);
// Utility helper routines.
bool isTypeLegal(Type *Ty, MVT &VT);
@@ -1471,6 +1472,50 @@ unsigned MipsFastISel::emitIntExt(MVT Sr
return Success ? DestReg : 0;
}
+bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {
+ EVT DestEVT = TLI.getValueType(I->getType(), true);
+ if (!DestEVT.isSimple())
+ return false;
+
+ MVT DestVT = DestEVT.getSimpleVT();
+ if (DestVT != MVT::i32)
+ return false;
+
+ unsigned DivOpc;
+ switch (ISDOpcode) {
+ default:
+ return false;
+ case ISD::SDIV:
+ case ISD::SREM:
+ DivOpc = Mips::SDIV;
+ break;
+ case ISD::UDIV:
+ case ISD::UREM:
+ DivOpc = Mips::UDIV;
+ break;
+ }
+
+ unsigned Src0Reg = getRegForValue(I->getOperand(0));
+ unsigned Src1Reg = getRegForValue(I->getOperand(1));
+ if (!Src0Reg || !Src1Reg)
+ return false;
+
+ emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
+ emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
+
+ unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
+ if (!ResultReg)
+ return false;
+
+ unsigned MFOpc = (ISDOpcode == ISD::SREM || ISDOpcode == ISD::UREM)
+ ? Mips::MFHI
+ : Mips::MFLO;
+ emitInst(MFOpc, ResultReg);
+
+ updateValueMap(I, ResultReg);
+ return true;
+}
+
bool MipsFastISel::selectShift(const Instruction *I) {
MVT RetVT;
@@ -1556,6 +1601,22 @@ bool MipsFastISel::fastSelectInstruction
return selectLoad(I);
case Instruction::Store:
return selectStore(I);
+ case Instruction::SDiv:
+ if (!selectBinaryOp(I, ISD::SDIV))
+ return selectDivRem(I, ISD::SDIV);
+ return true;
+ case Instruction::UDiv:
+ if (!selectBinaryOp(I, ISD::UDIV))
+ return selectDivRem(I, ISD::UDIV);
+ return true;
+ case Instruction::SRem:
+ if (!selectBinaryOp(I, ISD::SREM))
+ return selectDivRem(I, ISD::SREM);
+ return true;
+ case Instruction::URem:
+ if (!selectBinaryOp(I, ISD::UREM))
+ return selectDivRem(I, ISD::UREM);
+ return true;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
Added: llvm/trunk/test/CodeGen/Mips/Fast-ISel/div1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/Fast-ISel/div1.ll?rev=238757&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/Fast-ISel/div1.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/div1.ll Mon Jun 1 11:17:37 2015
@@ -0,0 +1,55 @@
+; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \
+; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \
+; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
+
+ at sj = global i32 200000, align 4
+ at sk = global i32 -47, align 4
+ at uj = global i32 200000, align 4
+ at uk = global i32 43, align 4
+ at si = common global i32 0, align 4
+ at ui = common global i32 0, align 4
+
+define void @divs() {
+ ; CHECK-LABEL: divs:
+
+ ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp)
+ ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp)
+ ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25
+ ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(si)($[[GOT]])
+ ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(sk)($[[GOT]])
+ ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(sj)($[[GOT]])
+ ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]])
+ ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]])
+ ; CHECK-DAG: div $zero, $[[J]], $[[K]]
+ ; CHECK_DAG: teq $[[K]], $zero, 7
+ ; CHECK-DAG: mflo $[[RESULT:[0-9]+]]
+ ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]])
+ %1 = load i32, i32* @sj, align 4
+ %2 = load i32, i32* @sk, align 4
+ %div = sdiv i32 %1, %2
+ store i32 %div, i32* @si, align 4
+ ret void
+}
+
+define void @divu() {
+ ; CHECK-LABEL: divu:
+
+ ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp)
+ ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp)
+ ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25
+ ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(ui)($[[GOT]])
+ ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(uk)($[[GOT]])
+ ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(uj)($[[GOT]])
+ ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]])
+ ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]])
+ ; CHECK-DAG: divu $zero, $[[J]], $[[K]]
+ ; CHECK_DAG: teq $[[K]], $zero, 7
+ ; CHECK-DAG: mflo $[[RESULT:[0-9]+]]
+ ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]])
+ %1 = load i32, i32* @uj, align 4
+ %2 = load i32, i32* @uk, align 4
+ %div = udiv i32 %1, %2
+ store i32 %div, i32* @ui, align 4
+ ret void
+}
Added: llvm/trunk/test/CodeGen/Mips/Fast-ISel/rem1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/Fast-ISel/rem1.ll?rev=238757&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/Fast-ISel/rem1.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/rem1.ll Mon Jun 1 11:17:37 2015
@@ -0,0 +1,56 @@
+; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \
+; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \
+; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
+
+ at sj = global i32 200, align 4
+ at sk = global i32 -47, align 4
+ at uj = global i32 200, align 4
+ at uk = global i32 43, align 4
+ at si = common global i32 0, align 4
+ at ui = common global i32 0, align 4
+
+define void @rems() {
+ ; CHECK-LABEL: rems:
+
+ ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp)
+ ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp)
+ ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25
+ ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(si)($[[GOT]])
+ ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(sk)($[[GOT]])
+ ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(sj)($[[GOT]])
+ ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]])
+ ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]])
+ ; CHECK-DAG: div $zero, $[[J]], $[[K]]
+ ; CHECK_DAG: teq $[[K]], $zero, 7
+ ; CHECK-DAG: mfhi $[[RESULT:[0-9]+]]
+ ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]])
+ %1 = load i32, i32* @sj, align 4
+ %2 = load i32, i32* @sk, align 4
+ %rem = srem i32 %1, %2
+ store i32 %rem, i32* @si, align 4
+ ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @remu() {
+ ; CHECK-LABEL: remu:
+
+ ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp)
+ ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp)
+ ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25
+ ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(ui)($[[GOT]])
+ ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(uk)($[[GOT]])
+ ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(uj)($[[GOT]])
+ ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]])
+ ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]])
+ ; CHECK-DAG: divu $zero, $[[J]], $[[K]]
+ ; CHECK_DAG: teq $[[K]], $zero, 7
+ ; CHECK-DAG: mfhi $[[RESULT:[0-9]+]]
+ ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]])
+ %1 = load i32, i32* @uj, align 4
+ %2 = load i32, i32* @uk, align 4
+ %rem = urem i32 %1, %2
+ store i32 %rem, i32* @ui, align 4
+ ret void
+}
More information about the llvm-commits
mailing list