summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-08-08 14:51:19 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-08-08 14:51:19 +0000
commit164e8b0b5cbbcd31dcc78d422e8e564cd1b356b1 (patch)
tree9852e5decf84e76f4d81c712c6f711d77c7da1a0 /llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
parent5c579572811fbe6a5523baa5fd9b2119c6ed92a9 (diff)
downloadbcm5719-llvm-164e8b0b5cbbcd31dcc78d422e8e564cd1b356b1.tar.gz
bcm5719-llvm-164e8b0b5cbbcd31dcc78d422e8e564cd1b356b1.zip
[TargetLowering] BuildUDIV - Add support for divide by one (PR38477)
Provide a pass-through of the numerator for divide by one cases - this is the same approach we take in DAGCombiner::visitSDIVLike. I investigated whether we could achieve this by magic MULHU/SRL values but nothing appeared to work as we don't have a way for MULHU(x,c) -> x llvm-svn: 339254
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp15
1 files changed, 8 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 7e4766c5445..7f0ab5325f7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -3569,7 +3569,6 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
auto BuildUDIVPattern = [](const APInt &Divisor, unsigned &PreShift,
APInt &Magic, unsigned &PostShift) {
- assert(!Divisor.isOneValue() && "UDIV by one not supported");
// FIXME: We should use a narrower constant when the upper
// bits are known to be zero.
APInt::mu magics = Divisor.magicu();
@@ -3586,7 +3585,7 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
Magic = magics.m;
- if (magics.a == 0) {
+ if (magics.a == 0 || Divisor.isOneValue()) {
assert(magics.s < Divisor.getBitWidth() &&
"We shouldn't generate an undefined shift!");
PostShift = magics.s;
@@ -3615,9 +3614,6 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
auto *C = dyn_cast<ConstantSDNode>(N1.getOperand(i));
if (!C || C->isNullValue() || C->getAPIntValue().getBitWidth() != EltBits)
return SDValue();
- // TODO: Handle udiv by one.
- if (C->isOne())
- return SDValue();
APInt MagicVal;
unsigned PreShiftVal, PostShiftVal;
bool SelNPQ = BuildUDIVPattern(C->getAPIntValue(), PreShiftVal, MagicVal,
@@ -3687,10 +3683,15 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
Created.push_back(NPQ.getNode());
Q = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q);
- Created.push_back(NPQ.getNode());
+ Created.push_back(Q.getNode());
}
- return DAG.getNode(ISD::SRL, dl, VT, Q, PostShift);
+ Q = DAG.getNode(ISD::SRL, dl, VT, Q, PostShift);
+ Created.push_back(Q.getNode());
+
+ SDValue One = DAG.getConstant(1, dl, VT);
+ SDValue IsOne = DAG.getSetCC(dl, VT, N1, One, ISD::SETEQ);
+ return DAG.getSelect(dl, VT, IsOne, N0, Q);
}
bool TargetLowering::
OpenPOWER on IntegriCloud