[llvm-commits] [llvm] r127034 - in /llvm/trunk: lib/Target/Mips/MipsISelDAGToDAG.cpp lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/Mips/MipsInstrInfo.td test/CodeGen/Mips/divrem.ll
Bruno Cardoso Lopes
bruno.cardoso at gmail.com
Fri Mar 4 13:03:24 PST 2011
Author: bruno
Date: Fri Mar 4 15:03:24 2011
New Revision: 127034
URL: http://llvm.org/viewvc/llvm-project?rev=127034&view=rev
Log:
Improve div/rem node handling on mips. Patch by Akira Hatanaka
Added:
llvm/trunk/test/CodeGen/Mips/divrem.ll
Modified:
llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
llvm/trunk/lib/Target/Mips/MipsISelLowering.h
llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=127034&r1=127033&r2=127034&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Fri Mar 4 15:03:24 2011
@@ -362,20 +362,18 @@
/// Mul/Div with two results
case ISD::SDIVREM:
case ISD::UDIVREM:
+ break;
case ISD::SMUL_LOHI:
case ISD::UMUL_LOHI: {
SDValue Op1 = Node->getOperand(0);
SDValue Op2 = Node->getOperand(1);
unsigned Op;
- if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI)
- Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
- else
- Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
+ Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
- SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2);
+ SDNode *Mul = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2);
- SDValue InFlag = SDValue(MulDiv, 0);
+ SDValue InFlag = SDValue(Mul, 0);
SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32,
MVT::Glue, InFlag);
InFlag = SDValue(Lo,1);
@@ -415,23 +413,8 @@
case ISD::SREM:
case ISD::UREM:
case ISD::SDIV:
- case ISD::UDIV: {
- SDValue Op1 = Node->getOperand(0);
- SDValue Op2 = Node->getOperand(1);
-
- unsigned Op, MOp;
- if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) {
- Op = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu);
- MOp = Mips::MFLO;
- } else {
- Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
- MOp = Mips::MFHI;
- }
- SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2);
-
- SDValue InFlag = SDValue(Node, 0);
- return CurDAG->getMachineNode(MOp, dl, MVT::i32, InFlag);
- }
+ case ISD::UDIV:
+ break;
// Get target GOT address.
case ISD::GLOBAL_OFFSET_TABLE:
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=127034&r1=127033&r2=127034&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Mar 4 15:03:24 2011
@@ -50,6 +50,8 @@
case MipsISD::MAddu : return "MipsISD::MAddu";
case MipsISD::MSub : return "MipsISD::MSub";
case MipsISD::MSubu : return "MipsISD::MSubu";
+ case MipsISD::DivRem : return "MipsISD::DivRem";
+ case MipsISD::DivRemU : return "MipsISD::DivRemU";
default : return NULL;
}
}
@@ -110,6 +112,11 @@
setOperationAction(ISD::AND, MVT::i32, Custom);
setOperationAction(ISD::OR, MVT::i32, Custom);
+ setOperationAction(ISD::SDIV, MVT::i32, Expand);
+ setOperationAction(ISD::SREM, MVT::i32, Expand);
+ setOperationAction(ISD::UDIV, MVT::i32, Expand);
+ setOperationAction(ISD::UREM, MVT::i32, Expand);
+
// Operations not directly supported by Mips.
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
@@ -163,6 +170,8 @@
setTargetDAGCombine(ISD::ADDE);
setTargetDAGCombine(ISD::SUBE);
+ setTargetDAGCombine(ISD::SDIVREM);
+ setTargetDAGCombine(ISD::UDIVREM);
setStackPointerRegisterToSaveRestore(Mips::SP);
computeRegisterProperties();
@@ -349,6 +358,40 @@
return SDValue();
}
+static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const MipsSubtarget* Subtarget) {
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
+ unsigned opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem :
+ MipsISD::DivRemU;
+ DebugLoc dl = N->getDebugLoc();
+
+ SDValue DivRem = DAG.getNode(opc, dl, MVT::Glue,
+ N->getOperand(0), N->getOperand(1));
+ SDValue InChain = DAG.getEntryNode();
+ SDValue InGlue = DivRem;
+
+ // insert MFLO
+ if (N->hasAnyUseOfValue(0)) {
+ SDValue CopyFromLo = DAG.getCopyFromReg(InChain, dl, Mips::LO, MVT::i32,
+ InGlue);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo);
+ InChain = CopyFromLo.getValue(1);
+ InGlue = CopyFromLo.getValue(2);
+ }
+
+ // insert MFHI
+ if (N->hasAnyUseOfValue(1)) {
+ SDValue CopyFromHi = DAG.getCopyFromReg(InChain, dl,
+ Mips::HI, MVT::i32, InGlue);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi);
+ }
+
+ return SDValue();
+}
+
SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
const {
SelectionDAG &DAG = DCI.DAG;
@@ -360,6 +403,9 @@
return PerformADDECombine(N, DAG, DCI, Subtarget);
case ISD::SUBE:
return PerformSUBECombine(N, DAG, DCI, Subtarget);
+ case ISD::SDIVREM:
+ case ISD::UDIVREM:
+ return PerformDivRemCombine(N, DAG, DCI, Subtarget);
}
return SDValue();
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=127034&r1=127033&r2=127034&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Fri Mar 4 15:03:24 2011
@@ -62,7 +62,11 @@
MAdd,
MAddu,
MSub,
- MSubu
+ MSubu,
+
+ // DivRem(u)
+ DivRem,
+ DivRemU
};
}
Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=127034&r1=127033&r2=127034&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Fri Mar 4 15:03:24 2011
@@ -30,7 +30,9 @@
[SDTCisVT<0, i32>, SDTCisSameAs<0, 1>,
SDTCisSameAs<1, 2>,
SDTCisSameAs<2, 3>]>;
-
+def SDT_MipsDivRem : SDTypeProfile<0, 2,
+ [SDTCisVT<0, i32>,
+ SDTCisSameAs<0, 1>]>;
// Call
def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
@@ -67,6 +69,12 @@
def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub,
[SDNPOptInGlue, SDNPOutGlue]>;
+// DivRem(u) nodes
+def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsDivRem,
+ [SDNPOutGlue]>;
+def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem,
+ [SDNPOutGlue]>;
+
//===----------------------------------------------------------------------===//
// Mips Instruction Predicate Definitions.
//===----------------------------------------------------------------------===//
@@ -283,9 +291,16 @@
}
// Mul, Div
-class MulDiv<bits<6> func, string instr_asm, InstrItinClass itin>:
- FR<0x00, func, (outs), (ins CPURegs:$a, CPURegs:$b),
- !strconcat(instr_asm, "\t$a, $b"), [], itin>;
+let Defs = [HI, LO] in {
+ class Mul<bits<6> func, string instr_asm, InstrItinClass itin>:
+ FR<0x00, func, (outs), (ins CPURegs:$a, CPURegs:$b),
+ !strconcat(instr_asm, "\t$a, $b"), [], itin>;
+
+ class Div<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>:
+ FR<0x00, func, (outs), (ins CPURegs:$a, CPURegs:$b),
+ !strconcat(instr_asm, "\t$$zero, $a, $b"),
+ [(op CPURegs:$a, CPURegs:$b)], itin>;
+}
// Move from Hi/Lo
class MoveFromLOHI<bits<6> func, string instr_asm>:
@@ -452,12 +467,10 @@
"jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
/// Multiply and Divide Instructions.
-let Defs = [HI, LO] in {
- def MULT : MulDiv<0x18, "mult", IIImul>;
- def MULTu : MulDiv<0x19, "multu", IIImul>;
- def DIV : MulDiv<0x1a, "div", IIIdiv>;
- def DIVu : MulDiv<0x1b, "divu", IIIdiv>;
-}
+def MULT : Mul<0x18, "mult", IIImul>;
+def MULTu : Mul<0x19, "multu", IIImul>;
+def SDIV : Div<MipsDivRem, 0x1a, "div", IIIdiv>;
+def UDIV : Div<MipsDivRemU, 0x1b, "divu", IIIdiv>;
let Defs = [HI] in
def MTHI : MoveToLOHI<0x11, "mthi">;
Added: llvm/trunk/test/CodeGen/Mips/divrem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/divrem.ll?rev=127034&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/divrem.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/divrem.ll Fri Mar 4 15:03:24 2011
@@ -0,0 +1,51 @@
+; RUN: llc -march=mips < %s | FileCheck %s
+
+; CHECK: div $zero,
+define i32 @sdiv1(i32 %a0, i32 %a1) nounwind readnone {
+entry:
+ %div = sdiv i32 %a0, %a1
+ ret i32 %div
+}
+
+; CHECK: div $zero,
+define i32 @srem1(i32 %a0, i32 %a1) nounwind readnone {
+entry:
+ %rem = srem i32 %a0, %a1
+ ret i32 %rem
+}
+
+; CHECK: divu $zero,
+define i32 @udiv1(i32 %a0, i32 %a1) nounwind readnone {
+entry:
+ %div = udiv i32 %a0, %a1
+ ret i32 %div
+}
+
+; CHECK: divu $zero,
+define i32 @urem1(i32 %a0, i32 %a1) nounwind readnone {
+entry:
+ %rem = urem i32 %a0, %a1
+ ret i32 %rem
+}
+
+; CHECK: div $zero,
+define i32 @sdivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind {
+entry:
+ %rem = srem i32 %a0, %a1
+ store i32 %rem, i32* %r, align 4, !tbaa !0
+ %div = sdiv i32 %a0, %a1
+ ret i32 %div
+}
+
+; CHECK: divu $zero,
+define i32 @udivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind {
+entry:
+ %rem = urem i32 %a0, %a1
+ store i32 %rem, i32* %r, align 4, !tbaa !0
+ %div = udiv i32 %a0, %a1
+ ret i32 %div
+}
+
+!0 = metadata !{metadata !"int", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
More information about the llvm-commits
mailing list