[llvm] r363645 - [X86] Move code that shrinks immediates for ((x << C1) op C2) into a helper function. NFCI

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 17 21:23:58 PDT 2019


Author: ctopper
Date: Mon Jun 17 21:23:58 2019
New Revision: 363645

URL: http://llvm.org/viewvc/llvm-project?rev=363645&view=rev
Log:
[X86] Move code that shrinks immediates for ((x << C1) op C2) into a helper function. NFCI

Preliminary step for D59909

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=363645&r1=363644&r2=363645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Jun 17 21:23:58 2019
@@ -502,6 +502,7 @@ namespace {
     bool shrinkAndImmediate(SDNode *N);
     bool isMaskZeroExtended(SDNode *N) const;
     bool tryShiftAmountMod(SDNode *N);
+    bool tryShrinkShlLogicImm(SDNode *N);
     bool tryVPTESTM(SDNode *Root, SDValue Setcc, SDValue Mask);
 
     MachineSDNode *emitPCMPISTR(unsigned ROpc, unsigned MOpc, bool MayFoldLoad,
@@ -3567,6 +3568,119 @@ bool X86DAGToDAGISel::tryShiftAmountMod(
   return true;
 }
 
+bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *N) {
+  MVT NVT = N->getSimpleValueType(0);
+  unsigned Opcode = N->getOpcode();
+  SDLoc dl(N);
+
+  // For operations of the form (x << C1) op C2, check if we can use a smaller
+  // encoding for C2 by transforming it into (x op (C2>>C1)) << C1.
+  SDValue Shift = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+
+  ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
+  if (!Cst)
+    return false;
+
+  int64_t Val = Cst->getSExtValue();
+
+  // If we have an any_extend feeding the AND, look through it to see if there
+  // is a shift behind it. But only if the AND doesn't use the extended bits.
+  // FIXME: Generalize this to other ANY_EXTEND than i32 to i64?
+  bool FoundAnyExtend = false;
+  if (Shift.getOpcode() == ISD::ANY_EXTEND && Shift.hasOneUse() &&
+      Shift.getOperand(0).getSimpleValueType() == MVT::i32 &&
+      isUInt<32>(Val)) {
+    FoundAnyExtend = true;
+    Shift = Shift.getOperand(0);
+  }
+
+  if (Shift.getOpcode() != ISD::SHL || !Shift.hasOneUse())
+    return false;
+
+  // i8 is unshrinkable, i16 should be promoted to i32.
+  if (NVT != MVT::i32 && NVT != MVT::i64)
+    return false;
+
+  ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
+  if (!ShlCst)
+    return false;
+
+  uint64_t ShAmt = ShlCst->getZExtValue();
+
+  // Make sure that we don't change the operation by removing bits.
+  // This only matters for OR and XOR, AND is unaffected.
+  uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
+  if (Opcode != ISD::AND && (Val & RemovedBitsMask) != 0)
+    return false;
+
+  // Check the minimum bitwidth for the new constant.
+  // TODO: Using 16 and 8 bit operations is also possible for or32 & xor32.
+  auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
+    if (Opcode == ISD::AND) {
+      // AND32ri is the same as AND64ri32 with zext imm.
+      // Try this before sign extended immediates below.
+      ShiftedVal = (uint64_t)Val >> ShAmt;
+      if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
+        return true;
+      // Also swap order when the AND can become MOVZX.
+      if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
+        return true;
+    }
+    ShiftedVal = Val >> ShAmt;
+    if ((!isInt<8>(Val) && isInt<8>(ShiftedVal)) ||
+        (!isInt<32>(Val) && isInt<32>(ShiftedVal)))
+      return true;
+    if (Opcode != ISD::AND) {
+      // MOV32ri+OR64r/XOR64r is cheaper than MOV64ri64+OR64rr/XOR64rr
+      ShiftedVal = (uint64_t)Val >> ShAmt;
+      if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
+        return true;
+    }
+    return false;
+  };
+
+  int64_t ShiftedVal;
+  if (!CanShrinkImmediate(ShiftedVal))
+    return false;
+
+  // Ok, we can reorder to get a smaller immediate.
+
+  // But, its possible the original immediate allowed an AND to become MOVZX.
+  // Doing this late due to avoid the MakedValueIsZero call as late as
+  // possible.
+  if (Opcode == ISD::AND) {
+    // Find the smallest zext this could possibly be.
+    unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
+    ZExtWidth = PowerOf2Ceil(std::max(ZExtWidth, 8U));
+
+    // Figure out which bits need to be zero to achieve that mask.
+    APInt NeededMask = APInt::getLowBitsSet(NVT.getSizeInBits(),
+                                            ZExtWidth);
+    NeededMask &= ~Cst->getAPIntValue();
+
+    if (CurDAG->MaskedValueIsZero(N->getOperand(0), NeededMask))
+      return false;
+  }
+
+  SDValue X = Shift.getOperand(0);
+  if (FoundAnyExtend) {
+    SDValue NewX = CurDAG->getNode(ISD::ANY_EXTEND, dl, NVT, X);
+    insertDAGNode(*CurDAG, SDValue(N, 0), NewX);
+    X = NewX;
+  }
+
+  SDValue NewCst = CurDAG->getConstant(ShiftedVal, dl, NVT);
+  insertDAGNode(*CurDAG, SDValue(N, 0), NewCst);
+  SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, X, NewCst);
+  insertDAGNode(*CurDAG, SDValue(N, 0), NewBinOp);
+  SDValue NewSHL = CurDAG->getNode(ISD::SHL, dl, NVT, NewBinOp,
+                                   Shift.getOperand(1));
+  ReplaceNode(N, NewSHL.getNode());
+  SelectCode(NewSHL.getNode());
+  return true;
+}
+
 /// If the high bits of an 'and' operand are known zero, try setting the
 /// high bits of an 'and' constant operand to produce a smaller encoding by
 /// creating a small, sign-extended negative immediate rather than a large
@@ -4131,115 +4245,11 @@ void X86DAGToDAGISel::Select(SDNode *Nod
 
     LLVM_FALLTHROUGH;
   case ISD::OR:
-  case ISD::XOR: {
-
-    // For operations of the form (x << C1) op C2, check if we can use a smaller
-    // encoding for C2 by transforming it into (x op (C2>>C1)) << C1.
-    SDValue Shift = Node->getOperand(0);
-    SDValue N1 = Node->getOperand(1);
-
-    ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
-    if (!Cst)
-      break;
-
-    int64_t Val = Cst->getSExtValue();
-
-    // If we have an any_extend feeding the AND, look through it to see if there
-    // is a shift behind it. But only if the AND doesn't use the extended bits.
-    // FIXME: Generalize this to other ANY_EXTEND than i32 to i64?
-    bool FoundAnyExtend = false;
-    if (Shift.getOpcode() == ISD::ANY_EXTEND && Shift.hasOneUse() &&
-        Shift.getOperand(0).getSimpleValueType() == MVT::i32 &&
-        isUInt<32>(Val)) {
-      FoundAnyExtend = true;
-      Shift = Shift.getOperand(0);
-    }
-
-    if (Shift.getOpcode() != ISD::SHL || !Shift.hasOneUse())
-      break;
-
-    // i8 is unshrinkable, i16 should be promoted to i32.
-    if (NVT != MVT::i32 && NVT != MVT::i64)
-      break;
-
-    ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
-    if (!ShlCst)
-      break;
-
-    uint64_t ShAmt = ShlCst->getZExtValue();
-
-    // Make sure that we don't change the operation by removing bits.
-    // This only matters for OR and XOR, AND is unaffected.
-    uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
-    if (Opcode != ISD::AND && (Val & RemovedBitsMask) != 0)
-      break;
-
-    // Check the minimum bitwidth for the new constant.
-    // TODO: Using 16 and 8 bit operations is also possible for or32 & xor32.
-    auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
-      if (Opcode == ISD::AND) {
-        // AND32ri is the same as AND64ri32 with zext imm.
-        // Try this before sign extended immediates below.
-        ShiftedVal = (uint64_t)Val >> ShAmt;
-        if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
-          return true;
-        // Also swap order when the AND can become MOVZX.
-        if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
-          return true;
-      }
-      ShiftedVal = Val >> ShAmt;
-      if ((!isInt<8>(Val) && isInt<8>(ShiftedVal)) ||
-          (!isInt<32>(Val) && isInt<32>(ShiftedVal)))
-        return true;
-      if (Opcode != ISD::AND) {
-        // MOV32ri+OR64r/XOR64r is cheaper than MOV64ri64+OR64rr/XOR64rr
-        ShiftedVal = (uint64_t)Val >> ShAmt;
-        if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
-          return true;
-      }
-      return false;
-    };
-
-    int64_t ShiftedVal;
-    if (!CanShrinkImmediate(ShiftedVal))
-      break;
-
-    // Ok, we can reorder to get a smaller immediate.
-
-    // But, its possible the original immediate allowed an AND to become MOVZX.
-    // Doing this late due to avoid the MakedValueIsZero call as late as
-    // possible.
-    if (Opcode == ISD::AND) {
-      // Find the smallest zext this could possibly be.
-      unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
-      ZExtWidth = PowerOf2Ceil(std::max(ZExtWidth, 8U));
-
-      // Figure out which bits need to be zero to achieve that mask.
-      APInt NeededMask = APInt::getLowBitsSet(NVT.getSizeInBits(),
-                                              ZExtWidth);
-      NeededMask &= ~Cst->getAPIntValue();
-
-      if (CurDAG->MaskedValueIsZero(Node->getOperand(0), NeededMask))
-        break;
-    }
-
-    SDValue X = Shift.getOperand(0);
-    if (FoundAnyExtend) {
-      SDValue NewX = CurDAG->getNode(ISD::ANY_EXTEND, dl, NVT, X);
-      insertDAGNode(*CurDAG, SDValue(Node, 0), NewX);
-      X = NewX;
-    }
+  case ISD::XOR:
+    if (tryShrinkShlLogicImm(Node))
+      return;
+    break;
 
-    SDValue NewCst = CurDAG->getConstant(ShiftedVal, dl, NVT);
-    insertDAGNode(*CurDAG, SDValue(Node, 0), NewCst);
-    SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, X, NewCst);
-    insertDAGNode(*CurDAG, SDValue(Node, 0), NewBinOp);
-    SDValue NewSHL = CurDAG->getNode(ISD::SHL, dl, NVT, NewBinOp,
-                                     Shift.getOperand(1));
-    ReplaceNode(Node, NewSHL.getNode());
-    SelectCode(NewSHL.getNode());
-    return;
-  }
   case X86ISD::SMUL:
     // i16/i32/i64 are handled with isel patterns.
     if (NVT != MVT::i8)




More information about the llvm-commits mailing list