summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-06-30 12:22:55 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-06-30 12:22:55 +0000
commitfae337704eb0ba7a75a567ca7ddb0ac8cb2415d9 (patch)
tree866f7405ae1f85f4fe77de1a69b6c76ed17bb253 /llvm/lib/CodeGen/SelectionDAG
parent14cd1997f13c811a0b4aef8c792e6e47a00d60f4 (diff)
downloadbcm5719-llvm-fae337704eb0ba7a75a567ca7ddb0ac8cb2415d9.tar.gz
bcm5719-llvm-fae337704eb0ba7a75a567ca7ddb0ac8cb2415d9.zip
[DAGCombiner] Handle correctly non-splat power of 2 -1 divisor (PR37119)
The combine added in commit 329525 overlooked the case where one, but not all, of the divisor elements is -1, -1 is the only power of two value for which the sdiv expansion recipe breaks. Thanks to @zvi for the original patch. Differential Revision: https://reviews.llvm.org/D45806 llvm-svn: 336048
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp16
1 files changed, 9 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8bc99e1a962..7c372c7ce43 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3051,11 +3051,8 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
auto IsPowerOfTwo = [](ConstantSDNode *C) {
if (C->isNullValue() || C->isOpaque())
return false;
- if (C->getAPIntValue().isAllOnesValue())
- return false;
if (C->getAPIntValue().isMinSignedValue())
return false;
-
if (C->getAPIntValue().isPowerOf2())
return true;
if ((-C->getAPIntValue()).isPowerOf2())
@@ -3095,6 +3092,15 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Add, C1);
AddToWorklist(Sra.getNode());
+ // Special case: (sdiv X, 1) -> X
+ // Special Case: (sdiv X, -1) -> 0-X
+ SDValue One = DAG.getConstant(1, DL, VT);
+ SDValue AllOnes = DAG.getAllOnesConstant(DL, VT);
+ SDValue IsOne = DAG.getSetCC(DL, CCVT, N1, One, ISD::SETEQ);
+ SDValue IsAllOnes = DAG.getSetCC(DL, CCVT, N1, AllOnes, ISD::SETEQ);
+ SDValue IsOneOrAllOnes = DAG.getNode(ISD::OR, DL, CCVT, IsOne, IsAllOnes);
+ Sra = DAG.getSelect(DL, VT, IsOneOrAllOnes, N0, Sra);
+
// If dividing by a positive value, we're done. Otherwise, the result must
// be negated.
SDValue Zero = DAG.getConstant(0, DL, VT);
@@ -3103,10 +3109,6 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
// FIXME: Use SELECT_CC once we improve SELECT_CC constant-folding.
SDValue IsNeg = DAG.getSetCC(DL, CCVT, N1, Zero, ISD::SETLT);
SDValue Res = DAG.getSelect(DL, VT, IsNeg, Sub, Sra);
- // Special case: (sdiv X, 1) -> X
- SDValue One = DAG.getConstant(1, DL, VT);
- SDValue IsOne = DAG.getSetCC(DL, CCVT, N1, One, ISD::SETEQ);
- Res = DAG.getSelect(DL, VT, IsOne, N0, Res);
return Res;
}
OpenPOWER on IntegriCloud