diff options
| author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-06-12 21:51:49 +0000 | 
|---|---|---|
| committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-06-12 21:51:49 +0000 | 
| commit | 82d284c1d28b2694acc461efec09e12193ce1b7d (patch) | |
| tree | b568e5f3c2b251c9e075f324dd6f7ecd1dcba3d8 /llvm/lib/CodeGen/SelectionDAG | |
| parent | 4eed6cc43369e2f29a9f4ddfe843fb126657923b (diff) | |
| download | bcm5719-llvm-82d284c1d28b2694acc461efec09e12193ce1b7d.tar.gz bcm5719-llvm-82d284c1d28b2694acc461efec09e12193ce1b7d.zip | |
[DAGCombiner] Recognize more patterns for ABS
Differential Revision: https://reviews.llvm.org/D47831
llvm-svn: 334553
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 34 | 
1 files changed, 27 insertions, 7 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0956cb519ef..614525b1f52 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2555,6 +2555,20 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {    if (N1.isUndef())      return N1; +  // fold Y = sra (X, size(X)-1); sub (xor (X, Y), Y) -> (abs X) +  if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) { +    if (N0.getOpcode() == ISD::XOR && N1.getOpcode() == ISD::SRA) { +      SDValue X0 = N0.getOperand(0), X1 = N0.getOperand(1); +      SDValue S0 = N1.getOperand(0); +      if ((X0 == S0 && X1 == N1) || (X0 == N1 && X1 == S0)) { +        unsigned OpSizeInBits = VT.getScalarSizeInBits(); +        if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1))) +          if (C->getAPIntValue() == (OpSizeInBits - 1)) +            return DAG.getNode(ISD::ABS, SDLoc(N), VT, S0); +      } +    } +  } +    // If the relocation model supports it, consider symbol offsets.    if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))      if (!LegalOperations && TLI.isOffsetFoldingLegal(GA)) { @@ -5660,13 +5674,19 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {    }    // fold Y = sra (X, size(X)-1); xor (add (X, Y), Y) -> (abs X) -  unsigned OpSizeInBits = VT.getScalarSizeInBits(); -  if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 && -      N1.getOpcode() == ISD::SRA && N1.getOperand(0) == N0.getOperand(0) && -      TLI.isOperationLegalOrCustom(ISD::ABS, VT)) { -    if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1))) -      if (C->getAPIntValue() == (OpSizeInBits - 1)) -        return DAG.getNode(ISD::ABS, SDLoc(N), VT, N0.getOperand(0)); +  if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) { +    SDValue A = N0.getOpcode() == ISD::ADD ? N0 : N1; +    SDValue S = N0.getOpcode() == ISD::SRA ? N0 : N1; +    if (A.getOpcode() == ISD::ADD && S.getOpcode() == ISD::SRA) { +      SDValue A0 = A.getOperand(0), A1 = A.getOperand(1); +      SDValue S0 = S.getOperand(0); +      if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0)) { +        unsigned OpSizeInBits = VT.getScalarSizeInBits(); +        if (ConstantSDNode *C = isConstOrConstSplat(S.getOperand(1))) +          if (C->getAPIntValue() == (OpSizeInBits - 1)) +            return DAG.getNode(ISD::ABS, SDLoc(N), VT, S0); +      } +    }    }    // fold (xor x, x) -> 0 | 

