diff options
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 59 | 
1 files changed, 44 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 34be54db23b..3d51a43a8c9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -298,7 +298,9 @@ namespace {      SDValue visitMUL(SDNode *N);      SDValue useDivRem(SDNode *N);      SDValue visitSDIV(SDNode *N); +    SDValue visitSDIVLike(SDValue N0, SDValue N1, SDNode *N);      SDValue visitUDIV(SDNode *N); +    SDValue visitUDIVLike(SDValue N0, SDValue N1, SDNode *N);      SDValue visitREM(SDNode *N);      SDValue visitMULHU(SDNode *N);      SDValue visitMULHS(SDNode *N); @@ -3010,7 +3012,6 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {    SDValue N1 = N->getOperand(1);    EVT VT = N->getValueType(0);    EVT CCVT = getSetCCResultType(VT); -  unsigned BitWidth = VT.getScalarSizeInBits();    // fold vector ops    if (VT.isVector()) @@ -3047,6 +3048,28 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {    if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))      return DAG.getNode(ISD::UDIV, DL, N1.getValueType(), N0, N1); +  if (SDValue V = visitSDIVLike(N0, N1, N)) +    return V; + +  // sdiv, srem -> sdivrem +  // If the divisor is constant, then return DIVREM only if isIntDivCheap() is +  // true.  Otherwise, we break the simplification logic in visitREM(). +  AttributeList Attr = DAG.getMachineFunction().getFunction().getAttributes(); +  if (!N1C || TLI.isIntDivCheap(N->getValueType(0), Attr)) +    if (SDValue DivRem = useDivRem(N)) +        return DivRem; + +  return SDValue(); +} + +SDValue DAGCombiner::visitSDIVLike(SDValue N0, SDValue N1, SDNode *N) { +  SDLoc DL(N); +  EVT VT = N->getValueType(0); +  EVT CCVT = getSetCCResultType(VT); +  unsigned BitWidth = VT.getScalarSizeInBits(); + +  ConstantSDNode *N1C = isConstOrConstSplat(N1); +    // Helper for determining whether a value is a power-2 constant scalar or a    // vector of such elements.    auto IsPowerOfTwo = [](ConstantSDNode *C) { @@ -3119,13 +3142,6 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {      if (SDValue Op = BuildSDIV(N))        return Op; -  // sdiv, srem -> sdivrem -  // If the divisor is constant, then return DIVREM only if isIntDivCheap() is -  // true.  Otherwise, we break the simplification logic in visitREM(). -  if (!N1C || TLI.isIntDivCheap(N->getValueType(0), Attr)) -    if (SDValue DivRem = useDivRem(N)) -        return DivRem; -    return SDValue();  } @@ -3155,6 +3171,26 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {    if (SDValue NewSel = foldBinOpIntoSelect(N))      return NewSel; +  if (SDValue V = visitUDIVLike(N0, N1, N)) +    return V; + +  // sdiv, srem -> sdivrem +  // If the divisor is constant, then return DIVREM only if isIntDivCheap() is +  // true.  Otherwise, we break the simplification logic in visitREM(). +  AttributeList Attr = DAG.getMachineFunction().getFunction().getAttributes(); +  if (!N1C || TLI.isIntDivCheap(N->getValueType(0), Attr)) +    if (SDValue DivRem = useDivRem(N)) +        return DivRem; + +  return SDValue(); +} + +SDValue DAGCombiner::visitUDIVLike(SDValue N0, SDValue N1, SDNode *N) { +  SDLoc DL(N); +  EVT VT = N->getValueType(0); + +  ConstantSDNode *N1C = isConstOrConstSplat(N1); +    // fold (udiv x, (1 << c)) -> x >>u c    if (isConstantOrConstantVector(N1, /*NoOpaques*/ true) &&        DAG.isKnownToBeAPowerOfTwo(N1)) { @@ -3190,13 +3226,6 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {      if (SDValue Op = BuildUDIV(N))        return Op; -  // sdiv, srem -> sdivrem -  // If the divisor is constant, then return DIVREM only if isIntDivCheap() is -  // true.  Otherwise, we break the simplification logic in visitREM(). -  if (!N1C || TLI.isIntDivCheap(N->getValueType(0), Attr)) -    if (SDValue DivRem = useDivRem(N)) -        return DivRem; -    return SDValue();  }  | 

