diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2012-01-11 09:35:02 +0000 | 
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2012-01-11 09:35:02 +0000 | 
| commit | 3dbcda84789aa45d29ccc6629fe932ff536e9087 (patch) | |
| tree | c1d664c6b0b7e7e8b9d388f8122d25480536075f | |
| parent | aa01e6661aca3722b203a25270c39e3ecb2fc802 (diff) | |
| download | bcm5719-llvm-3dbcda84789aa45d29ccc6629fe932ff536e9087.tar.gz bcm5719-llvm-3dbcda84789aa45d29ccc6629fe932ff536e9087.zip | |
Unify the interface of the three mask+shift transform helpers, and
factor the differences that were hiding in one of them into its other
caller, the SRL handling code. No change in behavior.
llvm-svn: 147940
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 60 | 
1 files changed, 34 insertions, 26 deletions
| diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 326ee8765f7..7499182c275 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -863,35 +863,24 @@ static bool FoldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N,  //   andl $124, %rcx  //   addl (%rsi,%rcx), %eax  // +// Note that this function assumes the mask is provided as a mask *after* the +// value is shifted. The input chain may or may not match that, but computing +// such a mask is trivial.  static bool FoldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, +                                    uint64_t Mask, +                                    SDValue Shift, SDValue X,                                      X86ISelAddressMode &AM) { -  // Scale must not be used already. -  if (AM.IndexReg.getNode() != 0 || AM.Scale != 1) return true; - -  SDValue Shift = N; -  SDValue And = N.getOperand(0); -  if (N.getOpcode() != ISD::SRL) -    std::swap(Shift, And); -  if (Shift.getOpcode() != ISD::SRL || And.getOpcode() != ISD::AND || -      !Shift.hasOneUse() || -      !isa<ConstantSDNode>(Shift.getOperand(1)) || -      !isa<ConstantSDNode>(And.getOperand(1))) +  if (Shift.getOpcode() != ISD::SRL || !Shift.hasOneUse() || +      !isa<ConstantSDNode>(Shift.getOperand(1)))      return true; -  SDValue X = (N == Shift ? And.getOperand(0) : Shift.getOperand(0)); -  // We only handle up to 64-bit values here as those are what matter for -  // addressing mode optimizations. -  if (X.getValueSizeInBits() > 64) return true; - -  uint64_t Mask = And.getConstantOperandVal(1);    unsigned ShiftAmt = Shift.getConstantOperandVal(1);    unsigned MaskLZ = CountLeadingZeros_64(Mask);    unsigned MaskTZ = CountTrailingZeros_64(Mask);    // The amount of shift we're trying to fit into the addressing mode is taken -  // from the trailing zeros of the mask. If the mask is pre-shift, we subtract -  // the shift amount. -  int AMShiftAmt = MaskTZ - (N == Shift ? ShiftAmt : 0); +  // from the trailing zeros of the mask. +  unsigned AMShiftAmt = MaskTZ;    // There is nothing we can do here unless the mask is removing some bits.    // Also, the addressing mode can only represent shifts of 1, 2, or 3 bits. @@ -901,9 +890,8 @@ static bool FoldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N,    if (CountTrailingOnes_64(Mask >> MaskTZ) + MaskTZ + MaskLZ != 64) return true;    // Scale the leading zero count down based on the actual size of the value. -  // Also scale it down based on the size of the shift if it was applied -  // before the mask. -  MaskLZ -= (64 - X.getValueSizeInBits()) + (N == Shift ? 0 : ShiftAmt); +  // Also scale it down based on the size of the shift. +  MaskLZ -= (64 - X.getValueSizeInBits()) + ShiftAmt;    // The final check is to ensure that any masked out high bits of X are    // already known to be zero. Otherwise, the mask has a semantic impact @@ -1062,12 +1050,32 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,      break;      } -  case ISD::SRL: +  case ISD::SRL: { +    // Scale must not be used already. +    if (AM.IndexReg.getNode() != 0 || AM.Scale != 1) break; + +    SDValue And = N.getOperand(0); +    if (And.getOpcode() != ISD::AND) break; +    SDValue X = And.getOperand(0); + +    // We only handle up to 64-bit values here as those are what matter for +    // addressing mode optimizations. +    if (X.getValueSizeInBits() > 64) break; + +    // The mask used for the transform is expected to be post-shift, but we +    // found the shift first so just apply the shift to the mask before passing +    // it down. +    if (!isa<ConstantSDNode>(N.getOperand(1)) || +        !isa<ConstantSDNode>(And.getOperand(1))) +      break; +    uint64_t Mask = And.getConstantOperandVal(1) >> N.getConstantOperandVal(1); +      // Try to fold the mask and shift into the scale, and return false if we      // succeed. -    if (!FoldMaskAndShiftToScale(*CurDAG, N, AM)) +    if (!FoldMaskAndShiftToScale(*CurDAG, N, Mask, N, X, AM))        return false;      break; +  }    case ISD::SMUL_LOHI:    case ISD::UMUL_LOHI: @@ -1257,7 +1265,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,        return false;      // Try to fold the mask and shift directly into the scale. -    if (!FoldMaskAndShiftToScale(*CurDAG, N, AM)) +    if (!FoldMaskAndShiftToScale(*CurDAG, N, C2->getZExtValue(), Shift, X, AM))        return false;      // Try to swap the mask and shift to place shifts which can be done as | 

