diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-06-30 12:22:55 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-06-30 12:22:55 +0000 |
commit | fae337704eb0ba7a75a567ca7ddb0ac8cb2415d9 (patch) | |
tree | 866f7405ae1f85f4fe77de1a69b6c76ed17bb253 /llvm/lib/CodeGen/SelectionDAG | |
parent | 14cd1997f13c811a0b4aef8c792e6e47a00d60f4 (diff) | |
download | bcm5719-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.cpp | 16 |
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; } |