Repository: llvm/llvm-project
File: llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp (C++)

Code before:

  // Everything else is considered legal.
  return Op;
}

static SDValue LowerVectorArith(SDValue Op, SelectionDAG &DAG) {
  SDLoc DL(Op);
  if (Op.getValueType() != MVT::v2i16)
    return Op;
  EVT EltVT = Op.getValueType().getVectorElementType();
  SmallVector<SDValue> VecElements;
  for (int I = 0, E = Op.getValueType().getVectorNumElements(); I < E; I++) {
    SmallVector<SDValue> ScalarArgs;
    llvm::transform(Op->ops(), std::back_inserter(ScalarArgs),
                    [&](const SDUse &O) {
                      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT,
                                         O.get(), DAG.getIntPtrConstant(I, DL));
                    });
    VecElements.push_back(DAG.getNode(Op.getOpcode(), DL, EltVT, ScalarArgs));
  }
  SDValue V =
      DAG.getNode(ISD::BUILD_VECTOR, DL, Op.getValueType(), VecElements);
  return V;
}

static SDValue lowerTcgen05St(SDValue Op, SelectionDAG &DAG) {
  SDNode *N = Op.getNode();
  SDLoc DL(N);
  SmallVector<SDValue, 32> Ops;

  // split the vector argument
  for (size_t I = 0; I < N->getNumOperands(); I++) {
    SDValue Val = N->getOperand(I);
    EVT ValVT = Val.getValueType();
    if (ValVT.isVector()) {
      EVT EltVT = ValVT.getVectorElementType();
      for (unsigned J = 0, NElts = ValVT.getVectorNumElements(); J < NElts; J++)
        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Val,
                                  DAG.getIntPtrConstant(J, DL)));
    } else
      Ops.push_back(Val);
  }

  MemIntrinsicSDNode *MemSD = cast<MemIntrinsicSDNode>(N);
  SDValue Tcgen05StNode =
      DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, DL, N->getVTList(), Ops,
                              MemSD->getMemoryVT(), MemSD->getMemOperand());

  return Tcgen05StNode;
}


Review comment (bug):
Do you think we should add a test case with debug-info?

From what I understand, for upstream, this has nothing to do with debug-info but more of a general fix when legalizing oprands?

Code after:

static SDValue LowerVectorArith(SDValue Op, SelectionDAG &DAG) {
  SDLoc DL(Op);
  if (Op.getValueType() != MVT::v2i16)
    return Op;
  EVT EltVT = Op.getValueType().getVectorElementType();
  SmallVector<SDValue> VecElements;
  for (int I = 0, E = Op.getValueType().getVectorNumElements(); I < E; I++) {
    SmallVector<SDValue> ScalarArgs;
    llvm::transform(Op->ops(), std::back_inserter(ScalarArgs),
                    [&](const SDUse &O) {
                      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT,
                                         O.get(), DAG.getIntPtrConstant(I, DL));
                    });
    VecElements.push_back(DAG.getNode(Op.getOpcode(), DL, EltVT, ScalarArgs));
  }
  SDValue V =
      DAG.getNode(ISD::BUILD_VECTOR, DL, Op.getValueType(), VecElements);
  return V;
}

static SDValue lowerTcgen05St(SDValue Op, SelectionDAG &DAG,
                              bool hasOffset = false) {
  // skip lowering if the vector operand is already legalized
  if (!Op->getOperand(hasOffset ? 4 : 3).getValueType().isVector())
    return Op;

  SDNode *N = Op.getNode();
  SDLoc DL(N);
  SmallVector<SDValue, 32> Ops;

  // split the vector argument
  for (size_t I = 0; I < N->getNumOperands(); I++) {
    SDValue Val = N->getOperand(I);
    EVT ValVT = Val.getValueType();
    if (ValVT.isVector()) {
      EVT EltVT = ValVT.getVectorElementType();
      for (unsigned J = 0, NElts = ValVT.getVectorNumElements(); J < NElts; J++)
        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Val,
                                  DAG.getIntPtrConstant(J, DL)));
    } else
      Ops.push_back(Val);
  }

  MemIntrinsicSDNode *MemSD = cast<MemIntrinsicSDNode>(N);
  SDValue Tcgen05StNode =
      DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, DL, N->getVTList(), Ops,
                              MemSD->getMemoryVT(), MemSD->getMemOperand());

  return Tcgen05StNode;
}