[llvm] Nvptx port LowerBITCAST to SelectionDAG (PR #120903)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 21 23:06:54 PST 2025


================
@@ -910,6 +910,77 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op,
   return DAG.getLoad(DestVT, dl, Store, StackPtr, MachinePointerInfo(), Align);
 }
 
+SDValue DAGTypeLegalizer::LowerBitcastInRegister(SDNode *N) const {
+  // Lower a bitcast into in-register shift operations
+  assert(N->getOpcode() == ISD::BITCAST && "Unexpected opcode!");
+
+  EVT FromVT = N->getOperand(0)->getValueType(0);
+  EVT ToVT = N->getValueType(0);
+
+  SDLoc DL(N);
+
+  bool IsBigEndian = DAG.getDataLayout().isBigEndian();
+
+  if (FromVT.isVector() && ToVT.isScalarInteger()) {
+
+    EVT ElemVT = FromVT.getVectorElementType();
+    unsigned NumElems = FromVT.getVectorNumElements();
+    unsigned ElemBits = ElemVT.getSizeInBits();
+
+    unsigned PackedBits = ToVT.getSizeInBits();
+    assert(PackedBits >= ElemBits * NumElems &&
+           "Scalar type does not have enough bits to pack vector values.");
+
+    EVT PackVT = EVT::getIntegerVT(*DAG.getContext(), ElemBits * NumElems);
+    SDValue Packed = DAG.getConstant(0, DL, PackVT);
+
+    for (unsigned I = 0; I < NumElems; ++I) {
+      unsigned ElementIndex = IsBigEndian ? (NumElems - 1 - I) : I;
+      SDValue Elem =
+          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT, N->getOperand(0),
+                      DAG.getIntPtrConstant(ElementIndex, DL));
+      SDValue ExtElem = DAG.getNode(ISD::ZERO_EXTEND, DL, PackVT, Elem);
+      SDValue ShiftAmount =
+          DAG.getShiftAmountConstant(ElemBits * I, PackVT, DL);
+      SDValue ShiftedElem =
+          DAG.getNode(ISD::SHL, DL, PackVT, ExtElem, ShiftAmount);
+
+      Packed = DAG.getNode(ISD::OR, DL, PackVT, Packed, ShiftedElem);
+    }
+
+    return DAG.getBitcast(ToVT, Packed);
+
+  } else if (FromVT.isScalarInteger() && ToVT.isVector()) {
+
+    EVT ElemVT = ToVT.getVectorElementType();
+    unsigned NumElems = ToVT.getVectorNumElements();
+    unsigned ElemBits = ElemVT.getSizeInBits();
+
+    unsigned PackedBits = FromVT.getSizeInBits();
+    assert(PackedBits >= ElemBits * NumElems &&
+           "Vector does not have enough bits to unpack scalar type.");
+
+    SmallVector<SDValue, 8> Elements;
+    Elements.reserve(NumElems);
+
+    for (unsigned I = 0; I < NumElems; ++I) {
+      unsigned ElementIndex = IsBigEndian ? (NumElems - 1 - I) : I;
+      unsigned ShiftAmountVal = ElemBits * ElementIndex;
+
+      SDValue ShiftAmount =
+          DAG.getShiftAmountConstant(ShiftAmountVal, FromVT, DL);
----------------
arsenm wrote:

Pull the getShiftAmountTy out of the loop? Can then use a shorter getConstant inside 

https://github.com/llvm/llvm-project/pull/120903


More information about the llvm-commits mailing list