================
@@ -123,8 +126,674 @@ lowerNVPTXPrintf(cir::OffloadPrintfOp op, mlir::Value 
format,
   return mlir::success();
 }
 
+std::optional<int64_t> getConstantInt(mlir::Value value) {
+  auto constOp = value.getDefiningOp<cir::ConstantOp>();
+  auto intAttr =
+      constOp ? mlir::dyn_cast<cir::IntAttr>(constOp.getValue()) : nullptr;
+  if (!intAttr)
+    return std::nullopt;
+  const llvm::APInt &v = intAttr.getValue();
+  if (mlir::cast<cir::IntType>(intAttr.getType()).isSigned()
+          ? v.getSignificantBits() > 64
+          : v.getActiveBits() > 63)
+    return std::nullopt;
+  return v.getSExtValue();
+}
+
+bool isByteType(mlir::Type ty) {
+  auto intTy = mlir::dyn_cast<cir::IntType>(ty);
+  return intTy && intTy.getWidth() == 8;
+}
+
+bool getConstantStringInfo(mlir::Value ptr, mlir::ModuleOp mod,
+                           mlir::SymbolTableCollection &symbolTables,
+                           std::string &str) {
+  int64_t offset = 0;
+  while (mlir::Operation *def = ptr.getDefiningOp()) {
+    if (auto cast = mlir::dyn_cast<cir::CastOp>(def)) {
+      if (cast.getKind() != cir::CastKind::array_to_ptrdecay &&
+          cast.getKind() != cir::CastKind::bitcast &&
+          cast.getKind() != cir::CastKind::address_space)
+        break;
+      ptr = cast.getSrc();
+    } else if (auto elt = mlir::dyn_cast<cir::GetElementOp>(def)) {
+      std::optional<int64_t> index = getConstantInt(elt.getIndex());
+      if (!index || !isByteType(elt.getElementType()) ||
+          llvm::AddOverflow(offset, *index, offset))
+        return false;
+      ptr = elt.getBase();
+    } else if (auto stride = mlir::dyn_cast<cir::PtrStrideOp>(def)) {
+      std::optional<int64_t> index = getConstantInt(stride.getStride());
+      if (!index || !isByteType(stride.getElementType()) ||
+          llvm::AddOverflow(offset, *index, offset))
+        return false;
+      ptr = stride.getBase();
+    } else {
+      break;
+    }
+  }
+
+  auto getGlobal = ptr.getDefiningOp<cir::GetGlobalOp>();
+  if (!getGlobal)
+    return false;
+
+  // The global may or may not have been converted already.
+  std::string data;
+  mlir::Operation *symbol =
+      symbolTables.lookupSymbolIn(mod, getGlobal.getNameAttr());
+  if (auto global = mlir::dyn_cast_if_present<cir::GlobalOp>(symbol)) {
+    std::optional<mlir::Attribute> init = global.getInitialValue();
+    auto arrayTy = mlir::dyn_cast<cir::ArrayType>(global.getSymType());
+    if (!global.getConstant() || !init || !arrayTy ||
+        !isByteType(arrayTy.getElementType()))
+      return false;
+    if (auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(*init)) {
+      auto strAttr = mlir::dyn_cast<mlir::StringAttr>(constArr.getElts());
+      if (!strAttr)
+        return false;
+      data = strAttr.getValue().str();
+    } else if (!mlir::isa<cir::ZeroAttr>(*init)) {
+      return false;
+    }
+    // Add back the trailing NULs the string attribute leaves out.
+    data.resize(arrayTy.getSize(), '\0');
+  } else if (auto global =
+                 mlir::dyn_cast_if_present<mlir::LLVM::GlobalOp>(symbol)) {
+    if (!global.getConstant())
+      return false;
+    mlir::Attribute value = global.getValueOrNull();
+    if (auto strAttr = mlir::dyn_cast_if_present<mlir::StringAttr>(value)) {
+      data = strAttr.getValue().str();
+    } else if (auto dense =
+                   
mlir::dyn_cast_if_present<mlir::DenseIntElementsAttr>(value);
+               dense && dense.getElementType().isInteger(8)) {
+      for (const llvm::APInt &c : dense.getValues<llvm::APInt>())
+        data.push_back(static_cast<char>(c.getZExtValue()));
+    } else {
+      return false;
+    }
+  } else {
+    return false;
+  }
+
+  if (offset < 0 || static_cast<uint64_t>(offset) > data.size())
+    return false;
+  llvm::StringRef rest = llvm::StringRef(data).drop_front(offset);
+  str = rest.substr(0, rest.find('\0')).str();
+  return true;
+}
+
+// helper struct to package the string related data
+struct StringData {
+  std::string str;
+  mlir::Value realSize;
+  mlir::Value alignedSize;
+  bool isConst = true;
+};
+
+class AMDGPUPrintfLowering {
+public:
+  AMDGPUPrintfLowering(cir::OffloadPrintfOp op,
+                       mlir::ConversionPatternRewriter &rewriter,
+                       const mlir::DataLayout &dataLayout,
+                       mlir::SymbolTableCollection &symbolTables,
+                       unsigned genericAddrSpace)
+      : op(op), rewriter(rewriter), dataLayout(dataLayout),
+        symbolTables(symbolTables), mod(op->getParentOfType<mlir::ModuleOp>()),
+        genericAddrSpace(genericAddrSpace) {}
+
+  mlir::LogicalResult lower(mlir::ValueRange args, bool isBuffered);
+
+private:
+  mlir::Value getI32(uint32_t value) {
+    return mlir::LLVM::ConstantOp::create(
+        rewriter, op.getLoc(), rewriter.getI32Type(), llvm::APInt(32, value));
+  }
+  mlir::Value getI64(uint64_t value) {
+    return mlir::LLVM::ConstantOp::create(
+        rewriter, op.getLoc(), rewriter.getI64Type(), llvm::APInt(64, value));
+  }
+  mlir::Value createCall(llvm::StringRef name, mlir::Type resTy,
+                         mlir::ValueRange args);
+  mlir::Value gepInBounds(mlir::Value ptr, mlir::LLVM::GEPArg offset);
+  void addPrintfFormatMetadata(llvm::StringRef entry, bool onlyIfEmpty);
+
+  mlir::Value fitArgInto64Bits(mlir::Value arg);
+  mlir::Value callPrintfBegin(mlir::Value version);
+  mlir::Value callAppendArgs(mlir::Value desc, int numArgs, mlir::Value arg0,
+                             mlir::Value arg1, mlir::Value arg2,
+                             mlir::Value arg3, mlir::Value arg4,
+                             mlir::Value arg5, mlir::Value arg6, bool isLast);
+  mlir::Value appendArg(mlir::Value desc, mlir::Value arg, bool isLast);
+  mlir::Value getStrlenWithNull(mlir::Value str);
+  mlir::Value callAppendStringN(mlir::Value desc, mlir::Value str,
+                                mlir::Value length, bool isLast);
+  mlir::Value appendString(mlir::Value desc, mlir::Value arg, bool isLast);
+  mlir::Value processArg(mlir::Value desc, mlir::Value arg, bool specIsCString,
+                         bool isLast);
+  bool isCStringArg(mlir::ValueRange args, size_t i) const;
+  mlir::Value callBufferedPrintfStart(
+      mlir::ValueRange args, mlir::Value fmt, bool isConstFmtStr,
+      llvm::SmallVectorImpl<StringData> &stringContents, mlir::Value &argSize);
+  void
+  processConstantStringArg(const StringData &sd,
+                           llvm::SmallVectorImpl<mlir::Value> &whatToStore);
+  mlir::Value processNonStringArg(mlir::Value arg);
+  void callBufferedPrintfArgPush(mlir::ValueRange args, mlir::Value ptrToStore,
+                                 llvm::ArrayRef<StringData> stringContents,
+                                 bool isConstFmtStr);
+  mlir::Value emitAMDGPUPrintfCall(mlir::ValueRange args, bool isBuffered);
+
+  cir::OffloadPrintfOp op;
+  mlir::ConversionPatternRewriter &rewriter;
+  const mlir::DataLayout &dataLayout;
+  mlir::SymbolTableCollection &symbolTables;
+  mlir::ModuleOp mod;
+  unsigned genericAddrSpace;
+
+  /// The rest of the op's block, which the expansion branches to.
+  mlir::Block *cont = nullptr;
+  std::string fmtStr;
+  llvm::SparseBitVector<8> specIsCString;
+};
+
 } // namespace
 
+mlir::Value AMDGPUPrintfLowering::createCall(llvm::StringRef name,
+                                             mlir::Type resTy,
+                                             mlir::ValueRange args) {
+  auto fnTy = mlir::LLVM::LLVMFunctionType::get(
+      resTy, llvm::to_vector(args.getTypes()), /*isVarArg=*/false);
+  createLLVMFuncOpIfNotExist(rewriter, symbolTables, op, name, fnTy);
+  return mlir::LLVM::CallOp::create(
+             rewriter, op.getLoc(), fnTy,
+             mlir::FlatSymbolRefAttr::get(rewriter.getContext(), name), args)
+      .getResult();
+}
+
+mlir::Value AMDGPUPrintfLowering::gepInBounds(mlir::Value ptr,
+                                              mlir::LLVM::GEPArg offset) {
+  return mlir::LLVM::GEPOp::create(rewriter, op.getLoc(), ptr.getType(),
+                                   rewriter.getI8Type(), ptr,
+                                   llvm::ArrayRef<mlir::LLVM::GEPArg>{offset},
+                                   mlir::LLVM::GEPNoWrapFlags::inbounds);
+}
+
+void AMDGPUPrintfLowering::addPrintfFormatMetadata(llvm::StringRef entry,
+                                                   bool onlyIfEmpty) {
+  constexpr llvm::StringLiteral name = "llvm.printf.fmts";
+  mlir::Attribute node = mlir::LLVM::MDNodeAttr::get(
+      rewriter.getContext(),
+      {mlir::LLVM::MDStringAttr::get(
+          rewriter.getContext(),
+          mlir::StringAttr::get(rewriter.getContext(), entry))});
+
+  mlir::LLVM::NamedMetadataOp metaD;
+  for (auto md : mod.getOps<mlir::LLVM::NamedMetadataOp>()) {
+    if (md.getMetadataName() == name) {
+      metaD = md;
+      break;
+    }
+  }
+
+  if (!metaD) {
+    mlir::OpBuilder::InsertionGuard guard(rewriter);
+    rewriter.setInsertionPointToEnd(mod.getBody());
+    mlir::LLVM::NamedMetadataOp::create(rewriter, mod.getLoc(), name,
+                                        rewriter.getArrayAttr(node));
+    return;
+  }
+
+  if (onlyIfEmpty && !metaD.getNodes().empty())
+    return;
+  llvm::SmallVector<mlir::Attribute> nodes(metaD.getNodes().getValue());
+  nodes.push_back(node);
+  rewriter.modifyOpInPlace(
+      metaD, [&] { metaD.setNodesAttr(rewriter.getArrayAttr(nodes)); });
+}
+
+mlir::Value AMDGPUPrintfLowering::fitArgInto64Bits(mlir::Value arg) {
+  mlir::Type int64Ty = rewriter.getI64Type();
+  mlir::Type ty = arg.getType();
+
+  if (auto intTy = mlir::dyn_cast<mlir::IntegerType>(ty)) {
+    switch (intTy.getWidth()) {
+    case 32:
+      return mlir::LLVM::ZExtOp::create(rewriter, op.getLoc(), int64Ty, arg);
+    case 64:
+      return arg;
+    }
+  }
+
+  if (ty.isF64()) {
+    return mlir::LLVM::BitcastOp::create(rewriter, op.getLoc(), int64Ty, arg);
+  }
+
+  if (mlir::isa<mlir::LLVM::LLVMPointerType>(ty)) {
+    return mlir::LLVM::PtrToIntOp::create(rewriter, op.getLoc(), int64Ty, arg);
+  }
+
+  llvm_unreachable("unexpected type");
+}
+
+mlir::Value AMDGPUPrintfLowering::callPrintfBegin(mlir::Value version) {
+  return createCall("__ockl_printf_begin", rewriter.getI64Type(), version);
+}
+
+mlir::Value AMDGPUPrintfLowering::callAppendArgs(
+    mlir::Value desc, int numArgs, mlir::Value arg0, mlir::Value arg1,
+    mlir::Value arg2, mlir::Value arg3, mlir::Value arg4, mlir::Value arg5,
+    mlir::Value arg6, bool isLast) {
+  mlir::Value isLastValue = getI32(isLast);
+  mlir::Value numArgsValue = getI32(numArgs);
+  return createCall("__ockl_printf_append_args", rewriter.getI64Type(),
+                    {desc, numArgsValue, arg0, arg1, arg2, arg3, arg4, arg5,
+                     arg6, isLastValue});
+}
+
+mlir::Value AMDGPUPrintfLowering::appendArg(mlir::Value desc, mlir::Value arg,
+                                            bool isLast) {
+  mlir::Value arg0 = fitArgInto64Bits(arg);
+  mlir::Value zero = getI64(0);
+  return callAppendArgs(desc, 1, arg0, zero, zero, zero, zero, zero, zero,
+                        isLast);
+}
+
+// The device library does not provide strlen, so we build our own loop
+// here. While we are at it, we also include the terminating null in the 
length.
+mlir::Value AMDGPUPrintfLowering::getStrlenWithNull(mlir::Value str) {
+  mlir::Block *prev = rewriter.getInsertionBlock();
+  mlir::Region *region = cont->getParent();
+
+  mlir::Value charZero = mlir::LLVM::ConstantOp::create(
+      rewriter, op.getLoc(), rewriter.getI8Type(), llvm::APInt(8, 0));
+  mlir::Value one = getI64(1);
+  mlir::Value zero = getI64(0);
+  mlir::Type int64Ty = rewriter.getI64Type();
+
+  // The length is either zero for a null pointer, or the computed value for an
+  // actual string. We need a join block for a phi that represents the final
+  // value.
+  //
+  //  Strictly speaking, the zero does not matter since
+  // __ockl_printf_append_string_n ignores the length if the pointer is null.
+  mlir::Block *join = rewriter.createBlock(region, cont->getIterator(),
+                                           {int64Ty}, {op.getLoc()});
+  mlir::Block *whileBlock = rewriter.createBlock(
+      region, join->getIterator(), {str.getType()}, {op.getLoc()});
+  mlir::Block *whileDone = rewriter.createBlock(region, join->getIterator());
+
+  // Emit an early return for when the pointer is null.
+  rewriter.setInsertionPointToEnd(prev);
+  mlir::Value cmpNull = mlir::LLVM::ICmpOp::create(
+      rewriter, op.getLoc(), mlir::LLVM::ICmpPredicate::eq, str,
+      mlir::LLVM::ZeroOp::create(rewriter, op.getLoc(), str.getType()));
+  mlir::LLVM::CondBrOp::create(rewriter, op.getLoc(), cmpNull, join, zero,
+                               whileBlock, str);
+
+  // Entry to the while loop.
+  rewriter.setInsertionPointToEnd(whileBlock);
+
+  mlir::Value ptrPhi = whileBlock->getArgument(0);
+  mlir::Value ptrNext = mlir::LLVM::GEPOp::create(
+      rewriter, op.getLoc(), str.getType(), rewriter.getI8Type(), ptrPhi,
+      llvm::ArrayRef<mlir::LLVM::GEPArg>{one});
+
+  // Condition for the while loop.
+  mlir::Value data = mlir::LLVM::LoadOp::create(rewriter, op.getLoc(),
+                                                rewriter.getI8Type(), ptrPhi);
+  mlir::Value cmp = mlir::LLVM::ICmpOp::create(
+      rewriter, op.getLoc(), mlir::LLVM::ICmpPredicate::eq, data, charZero);
+  mlir::LLVM::CondBrOp::create(rewriter, op.getLoc(), cmp, whileDone,
+                               mlir::ValueRange(), whileBlock, ptrNext);
+
+  // Add one to the computed length.
+  rewriter.setInsertionPointToEnd(whileDone);
+  auto addrTy = mlir::IntegerType::get(
+      rewriter.getContext(), *dataLayout.getTypeIndexBitwidth(str.getType()));
+  mlir::Value endAddr =
+      mlir::LLVM::PtrToAddrOp::create(rewriter, op.getLoc(), addrTy, ptrPhi);
+  mlir::Value beginAddr =
+      mlir::LLVM::PtrToAddrOp::create(rewriter, op.getLoc(), addrTy, str);
+  mlir::Value len =
+      mlir::LLVM::SubOp::create(rewriter, op.getLoc(), endAddr, beginAddr);
+  if (addrTy != int64Ty)
+    len = mlir::LLVM::ZExtOp::create(rewriter, op.getLoc(), int64Ty, len);
+  len = mlir::LLVM::AddOp::create(rewriter, op.getLoc(), len, one);
+
+  // Final join.
+  mlir::LLVM::BrOp::create(rewriter, op.getLoc(), len, join);
+  rewriter.setInsertionPointToEnd(join);
+  return join->getArgument(0);
+}
+
+mlir::Value AMDGPUPrintfLowering::callAppendStringN(mlir::Value desc,
+                                                    mlir::Value str,
+                                                    mlir::Value length,
+                                                    bool isLast) {
+  mlir::Value isLastInt32 = getI32(isLast);
+  // __ockl_printf_append_string_n takes a generic pointer, which can address a
+  // string in any address space.
+  auto ptrTy =
+      mlir::LLVM::LLVMPointerType::get(rewriter.getContext(), 
genericAddrSpace);
+  if (str.getType() != ptrTy)
+    str =
+        mlir::LLVM::AddrSpaceCastOp::create(rewriter, op.getLoc(), ptrTy, str);
+  return createCall("__ockl_printf_append_string_n", rewriter.getI64Type(),
+                    {desc, str, length, isLastInt32});
+}
+
+mlir::Value AMDGPUPrintfLowering::appendString(mlir::Value desc,
+                                               mlir::Value arg, bool isLast) {
+  mlir::Value length = getStrlenWithNull(arg);
+  return callAppendStringN(desc, arg, length, isLast);
+}
+
+mlir::Value AMDGPUPrintfLowering::processArg(mlir::Value desc, mlir::Value arg,
+                                             bool specIsCString, bool isLast) {
+  if (specIsCString && mlir::isa<mlir::LLVM::LLVMPointerType>(arg.getType())) {
+    return appendString(desc, arg, isLast);
+  }
+  // If the format specifies a string but the argument is not, the frontend 
will
+  // have printed a warning. We just rely on undefined behaviour and send the
+  // argument anyway.
+  return appendArg(desc, arg, isLast);
+}
+
+// As in processArg, a non-pointer argument for a string is sent as a scalar.
+bool AMDGPUPrintfLowering::isCStringArg(mlir::ValueRange args, size_t i) const 
{
+  return specIsCString.test(i) &&
+         mlir::isa<mlir::LLVM::LLVMPointerType>(args[i].getType());
+}
+
+// Calculates frame size required for current printf expansion and allocates
+// space on printf buffer. Printf frame includes following contents
+// [ ControlDWord , format string/Hash , Arguments (each aligned to 8 byte) ]
+mlir::Value AMDGPUPrintfLowering::callBufferedPrintfStart(
+    mlir::ValueRange args, mlir::Value fmt, bool isConstFmtStr,
+    llvm::SmallVectorImpl<StringData> &stringContents, mlir::Value &argSize) {
+  mlir::Value nonConstStrLen;
+  mlir::Value lenWithNull;
+  mlir::Value lenWithNullAligned;
+  mlir::Value tempAdd;
+
+  // First 4 bytes to be reserved for control dword
+  size_t bufSize = 4;
+  if (isConstFmtStr)
+    // First 8 bytes of MD5 hash
+    bufSize += 8;
+  else {
+    lenWithNull = getStrlenWithNull(fmt);
+
+    // Align the computed length to next 8 byte boundary
+    tempAdd = mlir::LLVM::AddOp::create(rewriter, op.getLoc(), lenWithNull,
+                                        getI64(7U));
+    nonConstStrLen =
+        mlir::LLVM::AndOp::create(rewriter, op.getLoc(), tempAdd, getI64(~7U));
+
+    stringContents.push_back({"", lenWithNull, nonConstStrLen, false});
+  }
+
+  mlir::OperandRange cirArgs = op->getOperands();
+  for (size_t i = 1; i < args.size(); i++) {
+    if (isCStringArg(args, i)) {
+      std::string argStr;
+      if (getConstantStringInfo(cirArgs[i], mod, symbolTables, argStr)) {
+        auto alignedLen = llvm::alignTo(argStr.size() + 1, 8);
+        stringContents.push_back({argStr, /*realSize=*/{}, /*alignedSize=*/{},
+                                  /*isConst=*/true});
+        bufSize += alignedLen;
+      } else {
+        lenWithNull = getStrlenWithNull(args[i]);
+
+        // Align the computed length to next 8 byte boundary
+        tempAdd = mlir::LLVM::AddOp::create(rewriter, op.getLoc(), lenWithNull,
+                                            getI64(7U));
+        lenWithNullAligned = mlir::LLVM::AndOp::create(rewriter, op.getLoc(),
+                                                       tempAdd, getI64(~7U));
+
+        if (nonConstStrLen) {
+          mlir::Value val = mlir::LLVM::AddOp::create(
+              rewriter, op.getLoc(), lenWithNullAligned, nonConstStrLen);
+          nonConstStrLen = val;
+        } else
+          nonConstStrLen = lenWithNullAligned;
+
+        stringContents.push_back({"", lenWithNull, lenWithNullAligned, false});
+      }
+    } else {
+      uint64_t allocSize =
+          dataLayout.getTypeSize(args[i].getType()).getFixedValue();
+      // We end up expanding non string arguments to 8 bytes
+      // (args smaller than 8 bytes)
+      bufSize += std::max<uint64_t>(allocSize, 8);
+    }
+  }
+
+  // calculate final size value to be passed to printf_alloc
+  mlir::Value sizeToReserve = getI64(bufSize);
+  if (nonConstStrLen)
+    sizeToReserve = mlir::LLVM::AddOp::create(rewriter, op.getLoc(),
+                                              nonConstStrLen, sizeToReserve);
+
+  argSize = mlir::LLVM::TruncOp::create(rewriter, op.getLoc(),
+                                        rewriter.getI32Type(), sizeToReserve);
+
+  // call the printf_alloc function
+  unsigned globalAS = 0;
+  if (auto as = mlir::dyn_cast_if_present<mlir::IntegerAttr>(
+          dataLayout.getGlobalMemorySpace()))
+    globalAS = as.getValue().getZExtValue();
+  auto ptrTy =
+      mlir::LLVM::LLVMPointerType::get(rewriter.getContext(), globalAS);
+  auto allocName =
+      mlir::StringAttr::get(rewriter.getContext(), "__printf_alloc");
+  bool declared = symbolTables.lookupSymbolIn(mod, allocName);
+  mlir::Value ptr = createCall(allocName, ptrTy, argSize);
+  if (!declared)
+    mlir::cast<mlir::LLVM::LLVMFuncOp>(
+        symbolTables.lookupSymbolIn(mod, allocName))
+        .setNoUnwind(true);
+  return ptr;
+}
+
+// Prepare constant string argument to push onto the buffer
+void AMDGPUPrintfLowering::processConstantStringArg(
+    const StringData &sd, llvm::SmallVectorImpl<mlir::Value> &whatToStore) {
+  llvm::SmallVector<uint32_t, 16> words;
+  llvm::packAMDGPUPrintfConstantString(sd.str, words);
+  for (uint32_t word : words)
+    whatToStore.push_back(getI32(word));
+}
+
+mlir::Value AMDGPUPrintfLowering::processNonStringArg(mlir::Value arg) {
+  mlir::Type ty = arg.getType();
+
+  if (auto intTy = mlir::dyn_cast<mlir::IntegerType>(ty)) {
+    if (intTy.getWidth() < 64) {
+      return mlir::LLVM::ZExtOp::create(rewriter, op.getLoc(),
+                                        rewriter.getI64Type(), arg);
+    }
+  }
+
+  if (mlir::isa<mlir::FloatType>(ty)) {
+    if (dataLayout.getTypeSize(ty).getFixedValue() < 8) {
+      return mlir::LLVM::FPExtOp::create(rewriter, op.getLoc(),
+                                         rewriter.getF64Type(), arg);
+    }
+  }
+
+  return arg;
+}
+
+void AMDGPUPrintfLowering::callBufferedPrintfArgPush(
+    mlir::ValueRange args, mlir::Value ptrToStore,
+    llvm::ArrayRef<StringData> stringContents, bool isConstFmtStr) {
+  const StringData *strIt = stringContents.begin();
+  size_t i = isConstFmtStr ? 1 : 0;
+  for (; i < args.size(); i++) {
+    llvm::SmallVector<mlir::Value, 32> whatToStore;
+    if ((i == 0) || isCStringArg(args, i)) {
+      if (strIt->isConst) {
+        processConstantStringArg(*strIt, whatToStore);
+        strIt++;
+      } else {
+        // This copies the contents of the string, however the next offset
+        // is at aligned length, the extra space that might be created due
+        // to alignment padding is not populated with any specific value
+        // here. This would be safe as long as runtime is sync with
+        // the offsets.
+        auto memcpy = mlir::LLVM::MemcpyOp::create(
+            rewriter, op.getLoc(), ptrToStore, args[i], strIt->realSize,
+            /*isVolatile=*/false);
+        mlir::NamedAttribute 
align1(mlir::LLVM::LLVMDialect::getAlignAttrName(),
+                                    rewriter.getI64IntegerAttr(1));
+        memcpy.setArgAttrsAttr(
+            rewriter.getArrayAttr({rewriter.getDictionaryAttr(align1),
+                                   rewriter.getDictionaryAttr(align1),
+                                   rewriter.getDictionaryAttr({})}));
+
+        ptrToStore = gepInBounds(ptrToStore, strIt->alignedSize);
+
+        // done with current argument, move to next
+        strIt++;
+        continue;
+      }
+    } else {
+      whatToStore.push_back(processNonStringArg(args[i]));
+    }
+
+    for (mlir::Value toStore : whatToStore) {
+      mlir::LLVM::StoreOp::create(rewriter, op.getLoc(), toStore, ptrToStore);
+      ptrToStore = gepInBounds(
+          ptrToStore,
+          dataLayout.getTypeSize(toStore.getType()).getFixedValue());
----------------
aobolensk wrote:

```suggestion
          llvm::alignTo(
              dataLayout.getTypeSize(toStore.getType()).getFixedValue(), 8));
```

https://github.com/llvm/llvm-project/pull/231563
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to