Migrate X86 and ARM from using X86ISD::{,I}DIV and ARMISD::MULHILO{U,S} to
use ISD::{S,U}DIVREM and ISD::{S,U}MUL_HIO. Move the lowering code
associated with these operators into target-independent in LegalizeDAG.cpp
and TargetLowering.cpp.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42762 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 6305073..869e68b 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -154,26 +154,41 @@
setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand);
}
- // Divide and remainder are lowered to use div or idiv in legalize in
- // order to expose the intermediate computations to trivial CSE. This is
- // most noticeable when both x/y and x%y are being computed; they can be
- // done with a single div or idiv.
- setOperationAction(ISD::SDIV , MVT::i8 , Custom);
- setOperationAction(ISD::UDIV , MVT::i8 , Custom);
- setOperationAction(ISD::SREM , MVT::i8 , Custom);
- setOperationAction(ISD::UREM , MVT::i8 , Custom);
- setOperationAction(ISD::SDIV , MVT::i16 , Custom);
- setOperationAction(ISD::UDIV , MVT::i16 , Custom);
- setOperationAction(ISD::SREM , MVT::i16 , Custom);
- setOperationAction(ISD::UREM , MVT::i16 , Custom);
- setOperationAction(ISD::SDIV , MVT::i32 , Custom);
- setOperationAction(ISD::UDIV , MVT::i32 , Custom);
- setOperationAction(ISD::SREM , MVT::i32 , Custom);
- setOperationAction(ISD::UREM , MVT::i32 , Custom);
- setOperationAction(ISD::SDIV , MVT::i64 , Custom);
- setOperationAction(ISD::UDIV , MVT::i64 , Custom);
- setOperationAction(ISD::SREM , MVT::i64 , Custom);
- setOperationAction(ISD::UREM , MVT::i64 , Custom);
+ // Scalar integer multiply, multiply-high, divide, and remainder are
+ // lowered to use operations that produce two results, to match the
+ // available instructions. This exposes the two-result form to trivial
+ // CSE, which is able to combine x/y and x%y into a single instruction,
+ // for example. The single-result multiply instructions are introduced
+ // in X86ISelDAGToDAG.cpp, after CSE, for uses where the the high part
+ // is not needed.
+ setOperationAction(ISD::MUL , MVT::i8 , Expand);
+ setOperationAction(ISD::MULHS , MVT::i8 , Expand);
+ setOperationAction(ISD::MULHU , MVT::i8 , Expand);
+ setOperationAction(ISD::SDIV , MVT::i8 , Expand);
+ setOperationAction(ISD::UDIV , MVT::i8 , Expand);
+ setOperationAction(ISD::SREM , MVT::i8 , Expand);
+ setOperationAction(ISD::UREM , MVT::i8 , Expand);
+ setOperationAction(ISD::MUL , MVT::i16 , Expand);
+ setOperationAction(ISD::MULHS , MVT::i16 , Expand);
+ setOperationAction(ISD::MULHU , MVT::i16 , Expand);
+ setOperationAction(ISD::SDIV , MVT::i16 , Expand);
+ setOperationAction(ISD::UDIV , MVT::i16 , Expand);
+ setOperationAction(ISD::SREM , MVT::i16 , Expand);
+ setOperationAction(ISD::UREM , MVT::i16 , Expand);
+ setOperationAction(ISD::MUL , MVT::i32 , Expand);
+ setOperationAction(ISD::MULHS , MVT::i32 , Expand);
+ setOperationAction(ISD::MULHU , MVT::i32 , Expand);
+ setOperationAction(ISD::SDIV , MVT::i32 , Expand);
+ setOperationAction(ISD::UDIV , MVT::i32 , Expand);
+ setOperationAction(ISD::SREM , MVT::i32 , Expand);
+ setOperationAction(ISD::UREM , MVT::i32 , Expand);
+ setOperationAction(ISD::MUL , MVT::i64 , Expand);
+ setOperationAction(ISD::MULHS , MVT::i64 , Expand);
+ setOperationAction(ISD::MULHU , MVT::i64 , Expand);
+ setOperationAction(ISD::SDIV , MVT::i64 , Expand);
+ setOperationAction(ISD::UDIV , MVT::i64 , Expand);
+ setOperationAction(ISD::SREM , MVT::i64 , Expand);
+ setOperationAction(ISD::UREM , MVT::i64 , Expand);
setOperationAction(ISD::BR_JT , MVT::Other, Expand);
setOperationAction(ISD::BRCOND , MVT::Other, Custom);
@@ -449,6 +464,10 @@
setOperationAction(ISD::FPOWI, (MVT::ValueType)VT, Expand);
setOperationAction(ISD::FSQRT, (MVT::ValueType)VT, Expand);
setOperationAction(ISD::FCOPYSIGN, (MVT::ValueType)VT, Expand);
+ setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand);
+ setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand);
+ setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand);
+ setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand);
}
if (Subtarget->hasMMX()) {
@@ -3398,22 +3417,6 @@
return DAG.getNode(ISD::MERGE_VALUES, VTs, 2, &Ops[0], Ops.size());
}
-SDOperand X86TargetLowering::LowerIntegerDivOrRem(SDOperand Op, SelectionDAG &DAG) {
- unsigned Opcode = Op.getOpcode();
- MVT::ValueType NVT = Op.getValueType();
- bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM;
- bool isDiv = Opcode == ISD::SDIV || Opcode == ISD::UDIV;
- unsigned Opc = isSigned ? X86ISD::IDIV : X86ISD::DIV;
-
- SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) };
- SDOperand DR = DAG.getNode(Opc, DAG.getVTList(NVT, NVT), Ops, 2);
-
- if (isDiv)
- return DR;
-
- return SDOperand(DR.Val, 1);
-}
-
SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getOperand(0).getValueType() <= MVT::i64 &&
Op.getOperand(0).getValueType() >= MVT::i16 &&
@@ -4545,10 +4548,6 @@
case ISD::SHL_PARTS:
case ISD::SRA_PARTS:
case ISD::SRL_PARTS: return LowerShift(Op, DAG);
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::SREM:
- case ISD::UREM: return LowerIntegerDivOrRem(Op, DAG);
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
case ISD::FABS: return LowerFABS(Op, DAG);
@@ -4620,8 +4619,6 @@
case X86ISD::TLSADDR: return "X86ISD::TLSADDR";
case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER";
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
- case X86ISD::DIV: return "X86ISD::DIV";
- case X86ISD::IDIV: return "X86ISD::IDIV";
}
}