[X86][SSE] LowerScalarImmediateShift - use getTargetConstantBitsFromNode to get immediate data

Don't just attempt to find a splat build vector.

First step towards getting rid of all the 32-bit special case code.

llvm-svn: 343383
This commit is contained in:
Simon Pilgrim 2018-09-29 16:40:35 +00:00
parent fb1b80191e
commit ae34ae12ef
1 changed files with 71 additions and 61 deletions

View File

@ -23422,6 +23422,7 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
SDLoc dl(Op); SDLoc dl(Op);
SDValue R = Op.getOperand(0); SDValue R = Op.getOperand(0);
SDValue Amt = Op.getOperand(1); SDValue Amt = Op.getOperand(1);
unsigned EltSizeInBits = VT.getScalarSizeInBits();
unsigned X86Opc = getTargetVShiftUniformOpcode(Op.getOpcode(), false); unsigned X86Opc = getTargetVShiftUniformOpcode(Op.getOpcode(), false);
auto ArithmeticShiftRight64 = [&](uint64_t ShiftAmt) { auto ArithmeticShiftRight64 = [&](uint64_t ShiftAmt) {
@ -23465,10 +23466,22 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
}; };
// Optimize shl/srl/sra with constant shift amount. // Optimize shl/srl/sra with constant shift amount.
if (auto *BVAmt = dyn_cast<BuildVectorSDNode>(Amt)) { APInt UndefElts;
if (auto *ShiftConst = BVAmt->getConstantSplatNode()) { SmallVector<APInt, 8> EltBits;
uint64_t ShiftAmt = ShiftConst->getZExtValue(); 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)
return SDValue();
uint64_t ShiftAmt = EltBits[SplatIndex].getZExtValue();
if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode())) if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode()))
return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG); return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG);
@ -23478,8 +23491,7 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
Op.getOpcode() == ISD::SRA) Op.getOpcode() == ISD::SRA)
return ArithmeticShiftRight64(ShiftAmt); return ArithmeticShiftRight64(ShiftAmt);
if (VT == MVT::v16i8 || if (VT == MVT::v16i8 || (Subtarget.hasInt256() && VT == MVT::v32i8) ||
(Subtarget.hasInt256() && VT == MVT::v32i8) ||
VT == MVT::v64i8) { VT == MVT::v64i8) {
unsigned NumElts = VT.getVectorNumElements(); unsigned NumElts = VT.getVectorNumElements();
MVT ShiftVT = MVT::getVectorVT(MVT::i16, NumElts / 2); MVT ShiftVT = MVT::getVectorVT(MVT::i16, NumElts / 2);
@ -23493,8 +23505,7 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
SDValue Zeros = getZeroVector(VT, Subtarget, DAG, dl); SDValue Zeros = getZeroVector(VT, Subtarget, DAG, dl);
if (VT.is512BitVector()) { if (VT.is512BitVector()) {
assert(VT == MVT::v64i8 && "Unexpected element type!"); assert(VT == MVT::v64i8 && "Unexpected element type!");
SDValue CMP = DAG.getSetCC(dl, MVT::v64i1, Zeros, R, SDValue CMP = DAG.getSetCC(dl, MVT::v64i1, Zeros, R, ISD::SETGT);
ISD::SETGT);
return DAG.getNode(ISD::SIGN_EXTEND, dl, VT, CMP); return DAG.getNode(ISD::SIGN_EXTEND, dl, VT, CMP);
} }
return DAG.getNode(X86ISD::PCMPGT, dl, VT, Zeros, R); return DAG.getNode(X86ISD::PCMPGT, dl, VT, Zeros, R);
@ -23506,8 +23517,8 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
if (Op.getOpcode() == ISD::SHL) { if (Op.getOpcode() == ISD::SHL) {
// Make a large shift. // Make a large shift.
SDValue SHL = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ShiftVT, SDValue SHL = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ShiftVT, R,
R, ShiftAmt, DAG); ShiftAmt, DAG);
SHL = DAG.getBitcast(VT, SHL); SHL = DAG.getBitcast(VT, SHL);
// Zero out the rightmost bits. // Zero out the rightmost bits.
return DAG.getNode(ISD::AND, dl, VT, SHL, return DAG.getNode(ISD::AND, dl, VT, SHL,
@ -23515,8 +23526,8 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
} }
if (Op.getOpcode() == ISD::SRL) { if (Op.getOpcode() == ISD::SRL) {
// Make a large shift. // Make a large shift.
SDValue SRL = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ShiftVT, SDValue SRL = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ShiftVT, R,
R, ShiftAmt, DAG); ShiftAmt, DAG);
SRL = DAG.getBitcast(VT, SRL); SRL = DAG.getBitcast(VT, SRL);
// Zero out the leftmost bits. // Zero out the leftmost bits.
return DAG.getNode(ISD::AND, dl, VT, SRL, return DAG.getNode(ISD::AND, dl, VT, SRL,
@ -23534,7 +23545,6 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
llvm_unreachable("Unknown shift opcode."); llvm_unreachable("Unknown shift opcode.");
} }
} }
}
// Check cases (mainly 32-bit) where i64 is expanded into high and low parts. // Check cases (mainly 32-bit) where i64 is expanded into high and low parts.
// TODO: Replace constant extraction with getTargetConstantBitsFromNode. // TODO: Replace constant extraction with getTargetConstantBitsFromNode.