// Fold this packed vector shift into a build vector if SrcOp is a
// vector of Constants or UNDEFs.
if (ISD::isBuildVectorOfConstantSDNodes(SrcOp.getNode())) {
- SmallVector<SDValue, 8> Elts;
- unsigned NumElts = SrcOp->getNumOperands();
-
+ unsigned ShiftOpc;
switch (Opc) {
default: llvm_unreachable("Unknown opcode!");
case X86ISD::VSHLI:
- for (unsigned i = 0; i != NumElts; ++i) {
- SDValue CurrentOp = SrcOp->getOperand(i);
- if (CurrentOp->isUndef()) {
- // Must produce 0s in the correct bits.
- Elts.push_back(DAG.getConstant(0, dl, ElementType));
- continue;
- }
- auto *ND = cast<ConstantSDNode>(CurrentOp);
- const APInt &C = ND->getAPIntValue();
- Elts.push_back(DAG.getConstant(C.shl(ShiftAmt), dl, ElementType));
- }
+ ShiftOpc = ISD::SHL;
break;
case X86ISD::VSRLI:
- for (unsigned i = 0; i != NumElts; ++i) {
- SDValue CurrentOp = SrcOp->getOperand(i);
- if (CurrentOp->isUndef()) {
- // Must produce 0s in the correct bits.
- Elts.push_back(DAG.getConstant(0, dl, ElementType));
- continue;
- }
- auto *ND = cast<ConstantSDNode>(CurrentOp);
- const APInt &C = ND->getAPIntValue();
- Elts.push_back(DAG.getConstant(C.lshr(ShiftAmt), dl, ElementType));
- }
+ ShiftOpc = ISD::SRL;
break;
case X86ISD::VSRAI:
- for (unsigned i = 0; i != NumElts; ++i) {
- SDValue CurrentOp = SrcOp->getOperand(i);
- if (CurrentOp->isUndef()) {
- // All shifted in bits must be the same so use 0.
- Elts.push_back(DAG.getConstant(0, dl, ElementType));
- continue;
- }
- auto *ND = cast<ConstantSDNode>(CurrentOp);
- const APInt &C = ND->getAPIntValue();
- Elts.push_back(DAG.getConstant(C.ashr(ShiftAmt), dl, ElementType));
- }
+ ShiftOpc = ISD::SRA;
break;
}
- return DAG.getBuildVector(VT, dl, Elts);
+ SDValue Amt = DAG.getConstant(ShiftAmt, dl, VT);
+ if (SDValue C = DAG.FoldConstantArithmetic(ShiftOpc, dl, VT, {SrcOp, Amt}))
+ return C;
}
return DAG.getNode(Opc, dl, VT, SrcOp,