[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