[llvm] r343387 - [X86][SSE] LowerScalarImmediateShift - remove 32-bit vXi64 special case handling.

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 29 10:36:22 PDT 2018


Author: rksimon
Date: Sat Sep 29 10:36:22 2018
New Revision: 343387

URL: http://llvm.org/viewvc/llvm-project?rev=343387&view=rev
Log:
[X86][SSE] LowerScalarImmediateShift - remove 32-bit vXi64 special case handling.

This is all handled generally by getTargetConstantBitsFromNode now

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

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=343387&r1=343386&r2=343387&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Sep 29 10:36:22 2018
@@ -23515,147 +23515,83 @@ static SDValue LowerScalarImmediateShift
   // Optimize shl/srl/sra with constant shift amount.
   APInt UndefElts;
   SmallVector<APInt, 8> EltBits;
-  if (getTargetConstantBitsFromNode(Amt, EltSizeInBits, UndefElts, EltBits,
-                                    true, false)) {
-    int SplatIndex = -1;
-    for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
-      if (UndefElts[i])
-        continue;
-      if (0 <= SplatIndex && EltBits[i] != EltBits[SplatIndex])
-        return SDValue();
-      SplatIndex = i;
-    }
-    if (SplatIndex < 0)
+  if (!getTargetConstantBitsFromNode(Amt, EltSizeInBits, UndefElts, EltBits,
+                                     true, false))
+    return SDValue();
+
+  int SplatIndex = -1;
+  for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+    if (UndefElts[i])
+      continue;
+    if (0 <= SplatIndex && EltBits[i] != EltBits[SplatIndex])
       return SDValue();
-
-    uint64_t ShiftAmt = EltBits[SplatIndex].getZExtValue();
-    if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode()))
-      return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG);
-
-    // i64 SRA needs to be performed as partial shifts.
-    if (((!Subtarget.hasXOP() && VT == MVT::v2i64) ||
-         (Subtarget.hasInt256() && VT == MVT::v4i64)) &&
-        Op.getOpcode() == ISD::SRA)
-      return ArithmeticShiftRight64(ShiftAmt);
-
-    if (VT == MVT::v16i8 || (Subtarget.hasInt256() && VT == MVT::v32i8) ||
-        VT == MVT::v64i8) {
-      unsigned NumElts = VT.getVectorNumElements();
-      MVT ShiftVT = MVT::getVectorVT(MVT::i16, NumElts / 2);
-
-      // Simple i8 add case
-      if (Op.getOpcode() == ISD::SHL && ShiftAmt == 1)
-        return DAG.getNode(ISD::ADD, dl, VT, R, R);
-
-      // ashr(R, 7)  === cmp_slt(R, 0)
-      if (Op.getOpcode() == ISD::SRA && ShiftAmt == 7) {
-        SDValue Zeros = getZeroVector(VT, Subtarget, DAG, dl);
-        if (VT.is512BitVector()) {
-          assert(VT == MVT::v64i8 && "Unexpected element type!");
-          SDValue CMP = DAG.getSetCC(dl, MVT::v64i1, Zeros, R, ISD::SETGT);
-          return DAG.getNode(ISD::SIGN_EXTEND, dl, VT, CMP);
-        }
-        return DAG.getNode(X86ISD::PCMPGT, dl, VT, Zeros, R);
-      }
-
-      // XOP can shift v16i8 directly instead of as shift v8i16 + mask.
-      if (VT == MVT::v16i8 && Subtarget.hasXOP())
-        return SDValue();
-
-      if (Op.getOpcode() == ISD::SHL) {
-        // Make a large shift.
-        SDValue SHL = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ShiftVT, R,
-                                                 ShiftAmt, DAG);
-        SHL = DAG.getBitcast(VT, SHL);
-        // Zero out the rightmost bits.
-        return DAG.getNode(ISD::AND, dl, VT, SHL,
-                           DAG.getConstant(uint8_t(-1U << ShiftAmt), dl, VT));
-      }
-      if (Op.getOpcode() == ISD::SRL) {
-        // Make a large shift.
-        SDValue SRL = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ShiftVT, R,
-                                                 ShiftAmt, DAG);
-        SRL = DAG.getBitcast(VT, SRL);
-        // Zero out the leftmost bits.
-        return DAG.getNode(ISD::AND, dl, VT, SRL,
-                           DAG.getConstant(uint8_t(-1U) >> ShiftAmt, dl, VT));
-      }
-      if (Op.getOpcode() == ISD::SRA) {
-        // ashr(R, Amt) === sub(xor(lshr(R, Amt), Mask), Mask)
-        SDValue Res = DAG.getNode(ISD::SRL, dl, VT, R, Amt);
-
-        SDValue Mask = DAG.getConstant(128 >> ShiftAmt, dl, VT);
-        Res = DAG.getNode(ISD::XOR, dl, VT, Res, Mask);
-        Res = DAG.getNode(ISD::SUB, dl, VT, Res, Mask);
-        return Res;
-      }
-      llvm_unreachable("Unknown shift opcode.");
-    }
+    SplatIndex = i;
   }
+  if (SplatIndex < 0)
+    return SDValue();
 
-  // Check cases (mainly 32-bit) where i64 is expanded into high and low parts.
-  // TODO: Replace constant extraction with getTargetConstantBitsFromNode.
-  if (!Subtarget.hasXOP() &&
-      (VT == MVT::v2i64 || (Subtarget.hasInt256() && VT == MVT::v4i64) ||
-       (Subtarget.hasAVX512() && VT == MVT::v8i64))) {
-
-    // AVX1 targets maybe extracting a 128-bit vector from a 256-bit constant.
-    unsigned SubVectorScale = 1;
-    if (Amt.getOpcode() == ISD::EXTRACT_SUBVECTOR) {
-      SubVectorScale =
-          Amt.getOperand(0).getValueSizeInBits() / Amt.getValueSizeInBits();
-      Amt = Amt.getOperand(0);
-    }
-
-    // Peek through any splat that was introduced for i64 shift vectorization.
-    int SplatIndex = -1;
-    if (ShuffleVectorSDNode *SVN = dyn_cast<ShuffleVectorSDNode>(Amt.getNode()))
-      if (SVN->isSplat()) {
-        SplatIndex = SVN->getSplatIndex();
-        Amt = Amt.getOperand(0);
-        assert(SplatIndex < (int)VT.getVectorNumElements() &&
-               "Splat shuffle referencing second operand");
+  uint64_t ShiftAmt = EltBits[SplatIndex].getZExtValue();
+  if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode()))
+    return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG);
+
+  // i64 SRA needs to be performed as partial shifts.
+  if (((!Subtarget.hasXOP() && VT == MVT::v2i64) ||
+       (Subtarget.hasInt256() && VT == MVT::v4i64)) &&
+      Op.getOpcode() == ISD::SRA)
+    return ArithmeticShiftRight64(ShiftAmt);
+
+  if (VT == MVT::v16i8 || (Subtarget.hasInt256() && VT == MVT::v32i8) ||
+      VT == MVT::v64i8) {
+    unsigned NumElts = VT.getVectorNumElements();
+    MVT ShiftVT = MVT::getVectorVT(MVT::i16, NumElts / 2);
+
+    // Simple i8 add case
+    if (Op.getOpcode() == ISD::SHL && ShiftAmt == 1)
+      return DAG.getNode(ISD::ADD, dl, VT, R, R);
+
+    // ashr(R, 7)  === cmp_slt(R, 0)
+    if (Op.getOpcode() == ISD::SRA && ShiftAmt == 7) {
+      SDValue Zeros = getZeroVector(VT, Subtarget, DAG, dl);
+      if (VT.is512BitVector()) {
+        assert(VT == MVT::v64i8 && "Unexpected element type!");
+        SDValue CMP = DAG.getSetCC(dl, MVT::v64i1, Zeros, R, ISD::SETGT);
+        return DAG.getNode(ISD::SIGN_EXTEND, dl, VT, CMP);
       }
+      return DAG.getNode(X86ISD::PCMPGT, dl, VT, Zeros, R);
+    }
 
-    if (Amt.getOpcode() != ISD::BITCAST ||
-        Amt.getOperand(0).getOpcode() != ISD::BUILD_VECTOR)
+    // XOP can shift v16i8 directly instead of as shift v8i16 + mask.
+    if (VT == MVT::v16i8 && Subtarget.hasXOP())
       return SDValue();
 
-    Amt = Amt.getOperand(0);
-    unsigned Ratio = Amt.getSimpleValueType().getVectorNumElements() /
-                     (SubVectorScale * VT.getVectorNumElements());
-    unsigned RatioInLog2 = Log2_32_Ceil(Ratio);
-    uint64_t ShiftAmt = 0;
-    unsigned BaseOp = (SplatIndex < 0 ? 0 : SplatIndex * Ratio);
-    for (unsigned i = 0; i != Ratio; ++i) {
-      ConstantSDNode *C = dyn_cast<ConstantSDNode>(Amt.getOperand(i + BaseOp));
-      if (!C)
-        return SDValue();
-      // 6 == Log2(64)
-      ShiftAmt |= C->getZExtValue() << (i * (1 << (6 - RatioInLog2)));
+    if (Op.getOpcode() == ISD::SHL) {
+      // Make a large shift.
+      SDValue SHL = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ShiftVT, R,
+                                               ShiftAmt, DAG);
+      SHL = DAG.getBitcast(VT, SHL);
+      // Zero out the rightmost bits.
+      return DAG.getNode(ISD::AND, dl, VT, SHL,
+                         DAG.getConstant(uint8_t(-1U << ShiftAmt), dl, VT));
     }
-
-    // Check remaining shift amounts (if not a splat).
-    if (SplatIndex < 0) {
-      for (unsigned i = Ratio; i != Amt.getNumOperands(); i += Ratio) {
-        uint64_t ShAmt = 0;
-        for (unsigned j = 0; j != Ratio; ++j) {
-          ConstantSDNode *C = dyn_cast<ConstantSDNode>(Amt.getOperand(i + j));
-          if (!C)
-            return SDValue();
-          // 6 == Log2(64)
-          ShAmt |= C->getZExtValue() << (j * (1 << (6 - RatioInLog2)));
-        }
-        if (ShAmt != ShiftAmt)
-          return SDValue();
-      }
+    if (Op.getOpcode() == ISD::SRL) {
+      // Make a large shift.
+      SDValue SRL = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ShiftVT, R,
+                                               ShiftAmt, DAG);
+      SRL = DAG.getBitcast(VT, SRL);
+      // Zero out the leftmost bits.
+      return DAG.getNode(ISD::AND, dl, VT, SRL,
+                         DAG.getConstant(uint8_t(-1U) >> ShiftAmt, dl, VT));
     }
-
-    if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode()))
-      return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG);
-
-    if (Op.getOpcode() == ISD::SRA)
-      return ArithmeticShiftRight64(ShiftAmt);
+    if (Op.getOpcode() == ISD::SRA) {
+      // ashr(R, Amt) === sub(xor(lshr(R, Amt), Mask), Mask)
+      SDValue Res = DAG.getNode(ISD::SRL, dl, VT, R, Amt);
+
+      SDValue Mask = DAG.getConstant(128 >> ShiftAmt, dl, VT);
+      Res = DAG.getNode(ISD::XOR, dl, VT, Res, Mask);
+      Res = DAG.getNode(ISD::SUB, dl, VT, Res, Mask);
+      return Res;
+    }
+    llvm_unreachable("Unknown shift opcode.");
   }
 
   return SDValue();




More information about the llvm-commits mailing list