================
@@ -123,8 +125,676 @@ 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());
----------------
steffenlarsen wrote:

Ironically, you've found something that makes this work in CIR that doesn't 
work in OGCG. I've added a test case for it and will create a patch for fixing 
this for OGCG.

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