summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2019-01-25 05:11:34 +0000
committerAlex Bradbury <asb@lowrisc.org>2019-01-25 05:11:34 +0000
commit456d3798d600840319f7ffc9de37a4e578d3bab0 (patch)
tree4f67046930c5356687ae4db45e4fb7e5859bc980 /llvm/lib/Target/RISCV/RISCVISelLowering.cpp
parent38cd9acbb9ea3c0b0886584e45930a357c419821 (diff)
downloadbcm5719-llvm-456d3798d600840319f7ffc9de37a4e578d3bab0.tar.gz
bcm5719-llvm-456d3798d600840319f7ffc9de37a4e578d3bab0.zip
[RISCV] Custom-legalise i32 SDIV/UDIV/UREM on RV64M
Follow the same custom legalisation strategy as used in D57085 for variable-length shifts (see that patch summary for more discussion). Although we may lose out on some late-stage DAG combines, I think this custom legalisation strategy is ultimately easier to reason about. There are some codegen changes in rv64m-exhaustive-w-insts.ll but they are all neutral in terms of the number of instructions. Differential Revision: https://reviews.llvm.org/D57096 llvm-svn: 352171
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp58
1 files changed, 28 insertions, 30 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4bbdd860bd1..79385de07dd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -80,7 +80,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
if (Subtarget.is64Bit()) {
- setTargetDAGCombine(ISD::ANY_EXTEND);
setOperationAction(ISD::SHL, MVT::i32, Custom);
setOperationAction(ISD::SRA, MVT::i32, Custom);
setOperationAction(ISD::SRL, MVT::i32, Custom);
@@ -96,6 +95,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::UREM, XLenVT, Expand);
}
+ if (Subtarget.is64Bit() && Subtarget.hasStdExtM()) {
+ setOperationAction(ISD::SDIV, MVT::i32, Custom);
+ setOperationAction(ISD::UDIV, MVT::i32, Custom);
+ setOperationAction(ISD::UREM, MVT::i32, Custom);
+ }
+
setOperationAction(ISD::SDIVREM, XLenVT, Expand);
setOperationAction(ISD::UDIVREM, XLenVT, Expand);
setOperationAction(ISD::SMUL_LOHI, XLenVT, Expand);
@@ -524,6 +529,12 @@ static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
return RISCVISD::SRAW;
case ISD::SRL:
return RISCVISD::SRLW;
+ case ISD::SDIV:
+ return RISCVISD::DIVW;
+ case ISD::UDIV:
+ return RISCVISD::DIVUW;
+ case ISD::UREM:
+ return RISCVISD::REMUW;
}
}
@@ -558,46 +569,24 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
return;
Results.push_back(customLegalizeToWOp(N, DAG));
break;
- }
-}
-
-// Returns true if the given node is an sdiv, udiv, or urem with non-constant
-// operands.
-static bool isVariableSDivUDivURem(SDValue Val) {
- switch (Val.getOpcode()) {
- default:
- return false;
case ISD::SDIV:
case ISD::UDIV:
case ISD::UREM:
- return Val.getOperand(0).getOpcode() != ISD::Constant &&
- Val.getOperand(1).getOpcode() != ISD::Constant;
+ assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
+ Subtarget.hasStdExtM() && "Unexpected custom legalisation");
+ if (N->getOperand(0).getOpcode() == ISD::Constant ||
+ N->getOperand(1).getOpcode() == ISD::Constant)
+ return;
+ Results.push_back(customLegalizeToWOp(N, DAG));
+ break;
}
}
SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
- SelectionDAG &DAG = DCI.DAG;
-
switch (N->getOpcode()) {
default:
break;
- case ISD::ANY_EXTEND: {
- // If any-extending an i32 sdiv/udiv/urem to i64, then instead sign-extend
- // in order to increase the chance of being able to select the
- // divw/divuw/remuw instructions.
- SDValue Src = N->getOperand(0);
- if (N->getValueType(0) != MVT::i64 || Src.getValueType() != MVT::i32)
- break;
- if (!(Subtarget.hasStdExtM() && isVariableSDivUDivURem(Src)))
- break;
- SDLoc DL(N);
- // Don't add the new node to the DAGCombiner worklist, in order to avoid
- // an infinite cycle due to SimplifyDemandedBits converting the
- // SIGN_EXTEND back to ANY_EXTEND.
- return DCI.CombineTo(N, DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Src),
- false);
- }
case RISCVISD::SplitF64: {
// If the input to SplitF64 is just BuildPairF64 then the operation is
// redundant. Instead, use BuildPairF64's operands directly.
@@ -633,6 +622,9 @@ unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode(
case RISCVISD::SLLW:
case RISCVISD::SRAW:
case RISCVISD::SRLW:
+ case RISCVISD::DIVW:
+ case RISCVISD::DIVUW:
+ case RISCVISD::REMUW:
// TODO: As the result is sign-extended, this is conservatively correct. A
// more precise answer could be calculated for SRAW depending on known
// bits in the shift amount.
@@ -1736,6 +1728,12 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
return "RISCVISD::SRAW";
case RISCVISD::SRLW:
return "RISCVISD::SRLW";
+ case RISCVISD::DIVW:
+ return "RISCVISD::DIVW";
+ case RISCVISD::DIVUW:
+ return "RISCVISD::DIVUW";
+ case RISCVISD::REMUW:
+ return "RISCVISD::REMUW";
}
return nullptr;
}
OpenPOWER on IntegriCloud