[llvm-commits] [llvm] r147940 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Chandler Carruth chandlerc at gmail.com
Wed Jan 11 01:35:03 PST 2012


Author: chandlerc
Date: Wed Jan 11 03:35:02 2012
New Revision: 147940

URL: http://llvm.org/viewvc/llvm-project?rev=147940&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=147940&r1=147939&r2=147940&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Jan 11 03:35:02 2012
@@ -863,35 +863,24 @@
 //   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 @@
   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 @@
     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 @@
       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





More information about the llvm-commits mailing list