[clang] [CIR ] Add DLTI dialect support to module attributes (PR #142241)

via cfe-commits cfe-commits at lists.llvm.org
Fri May 30 16:49:00 PDT 2025


https://github.com/Andres-Salamanca created https://github.com/llvm/llvm-project/pull/142241

This PR adds support for the DLTI dialect by attaching it to the module attributes and introduces a utility function to determine if the target is big-endian, which is required for https://github.com/llvm/llvm-project/pull/142041. Some tests were updated because we now use `mlir::translateDataLayout`, which "updates" the `DataLayout` where the alignment for `long` is 8 instead of the previously 4. This updated is consistent with Incubator.

>From c60cbfd510f28161c592dfdef6d3d8e10f0ce59a Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Fri, 30 May 2025 18:13:31 -0500
Subject: [PATCH] Add DLTI dialect support to module attributes and function to
 check for big endian

---
 .../clang/CIR/Dialect/IR/CIRDataLayout.h      | 10 +++++++-
 clang/lib/CIR/CodeGen/CIRGenerator.cpp        | 14 +++++++++++
 clang/lib/CIR/CodeGen/CMakeLists.txt          |  1 +
 clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp    | 22 ++++++++++++++++++
 clang/lib/CIR/Dialect/IR/CMakeLists.txt       |  1 +
 clang/test/CIR/CodeGen/dlti.c                 | 23 +++++++++++++++++++
 clang/test/CIR/Lowering/func-simple.cpp       |  8 +++----
 clang/tools/cir-opt/cir-opt.cpp               |  4 +++-
 8 files changed, 77 insertions(+), 6 deletions(-)
 create mode 100644 clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
 create mode 100644 clang/test/CIR/CodeGen/dlti.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
index 62fc53f2362fb..8ef565d6afd34 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
@@ -12,6 +12,7 @@
 #ifndef CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
 #define CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
 
+#include "mlir/Dialect/DLTI/DLTI.h"
 #include "mlir/IR/BuiltinOps.h"
 
 namespace cir {
@@ -21,11 +22,18 @@ namespace cir {
 class CIRDataLayout {
   // This is starting with the minimum functionality needed for code that is
   // being upstreamed. Additional methods and members will be added as needed.
+  bool bigEndian = false;
+
 public:
   mlir::DataLayout layout;
 
   /// Constructs a DataLayout the module's data layout attribute.
-  CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} {}
+  CIRDataLayout(mlir::ModuleOp modOp);
+
+  /// Parse a data layout string (with fallback to default values).
+  void reset(mlir::DataLayoutSpecInterface spec);
+
+  bool isBigEndian() const { return bigEndian; }
 };
 
 } // namespace cir
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 40252ffecfba1..3f1a8f2a924e2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -14,11 +14,13 @@
 
 #include "mlir/Dialect/OpenACC/OpenACC.h"
 #include "mlir/IR/MLIRContext.h"
+#include "mlir/Target/LLVMIR/Import.h"
 
 #include "clang/AST/DeclGroup.h"
 #include "clang/CIR/CIRGenerator.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"
+#include "llvm/IR/DataLayout.h"
 
 using namespace cir;
 using namespace clang;
@@ -31,12 +33,20 @@ CIRGenerator::CIRGenerator(clang::DiagnosticsEngine &diags,
     : diags(diags), fs(std::move(vfs)), codeGenOpts{cgo} {}
 CIRGenerator::~CIRGenerator() = default;
 
+static void setMLIRDataLayout(mlir::ModuleOp &mod, const llvm::DataLayout &dl) {
+  mlir::MLIRContext *mlirContext = mod.getContext();
+  mlir::DataLayoutSpecInterface dlSpec =
+      mlir::translateDataLayout(dl, mlirContext);
+  mod->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);
+}
+
 void CIRGenerator::Initialize(ASTContext &astContext) {
   using namespace llvm;
 
   this->astContext = &astContext;
 
   mlirContext = std::make_unique<mlir::MLIRContext>();
+  mlirContext->loadDialect<mlir::DLTIDialect>();
   mlirContext->loadDialect<cir::CIRDialect>();
   mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();
 
@@ -47,6 +57,10 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
 
   cgm = std::make_unique<clang::CIRGen::CIRGenModule>(
       *mlirContext.get(), astContext, codeGenOpts, diags);
+  mlir::ModuleOp mod = cgm->getModule();
+  llvm::DataLayout layout =
+      llvm::DataLayout(astContext.getTargetInfo().getDataLayoutString());
+  setMLIRDataLayout(mod, layout);
 }
 
 bool CIRGenerator::verifyModule() const { return cgm->verifyModule(); }
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 4c0aa9a3d0a64..3ecb0e9f60a49 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -41,4 +41,5 @@ add_clang_library(clangCIR
   CIROpenACCSupport
   MLIRCIR
   MLIRCIRInterfaces
+  MLIRTargetLLVMIRImport
 )
diff --git a/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
new file mode 100644
index 0000000000000..d835c4076224a
--- /dev/null
+++ b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
@@ -0,0 +1,22 @@
+#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
+
+using namespace cir;
+
+//===----------------------------------------------------------------------===//
+//                       DataLayout Class Implementation
+//===----------------------------------------------------------------------===//
+
+CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout(modOp) {
+  reset(modOp.getDataLayoutSpec());
+}
+
+void CIRDataLayout::reset(mlir::DataLayoutSpecInterface spec) {
+  bigEndian = false;
+  if (spec) {
+    mlir::StringAttr key = mlir::StringAttr::get(
+        spec.getContext(), mlir::DLTIDialect::kDataLayoutEndiannessKey);
+    if (mlir::DataLayoutEntryInterface entry = spec.getSpecForIdentifier(key))
+      if (auto str = llvm::dyn_cast<mlir::StringAttr>(entry.getValue()))
+        bigEndian = str == mlir::DLTIDialect::kDataLayoutEndiannessBig;
+  }
+}
diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
index e5256bf961f46..98575941035f2 100644
--- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
@@ -3,6 +3,7 @@ add_clang_library(MLIRCIR
   CIRDialect.cpp
   CIRMemorySlot.cpp
   CIRTypes.cpp
+  CIRDataLayout.cpp
 
   DEPENDS
   MLIRCIROpsIncGen
diff --git a/clang/test/CIR/CodeGen/dlti.c b/clang/test/CIR/CodeGen/dlti.c
new file mode 100644
index 0000000000000..3340e6eab5b75
--- /dev/null
+++ b/clang/test/CIR/CodeGen/dlti.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+void foo() {}
+
+//  CHECK-DAG: dlti.dl_spec =
+//  CHECK-DAG:   #dlti.dl_spec<
+//  CHECK-DAG:     i16 = dense<16> : vector<2xi64>,
+//  CHECK-DAG:     i32 = dense<32> : vector<2xi64>,
+//  CHECK-DAG:     i8 = dense<8> : vector<2xi64>,
+//  CHECK-DAG:     i1 = dense<8> : vector<2xi64>,
+//  CHECK-DAG:     !llvm.ptr = dense<64> : vector<4xi64>,
+//  CHECK-DAG:     f80 = dense<128> : vector<2xi64>,
+//  CHECK-DAG:     i128 = dense<128> : vector<2xi64>,
+//  CHECK-DAG:     !llvm.ptr<272> = dense<64> : vector<4xi64>,
+//  CHECK-DAG:     i64 = dense<64> : vector<2xi64>,
+//  CHECK-DAG:     !llvm.ptr<270> = dense<32> : vector<4xi64>,
+//  CHECK-DAG:     !llvm.ptr<271> = dense<32> : vector<4xi64>,
+//  CHECK-DAG:     f128 = dense<128> : vector<2xi64>,
+//  CHECK-DAG:     f16 = dense<16> : vector<2xi64>,
+//  CHECK-DAG:     f64 = dense<64> : vector<2xi64>,
+//  CHECK-DAG:     "dlti.stack_alignment" = 128 : i64
+//  CHECK-DAG:     "dlti.endianness" = "little"
diff --git a/clang/test/CIR/Lowering/func-simple.cpp b/clang/test/CIR/Lowering/func-simple.cpp
index 3d6a837daf6e5..0a8da8983b8e5 100644
--- a/clang/test/CIR/Lowering/func-simple.cpp
+++ b/clang/test/CIR/Lowering/func-simple.cpp
@@ -42,8 +42,8 @@ int scopes() {
 long longfunc() { return 42l; }
 // CHECK: define{{.*}} i64 @_Z8longfuncv() {
 // CHECK:   %[[RV]] = alloca i64, i64 1, align 8
-// CHECK:   store i64 42, ptr %[[RV]], align 4
-// CHECK:   %[[R:.*]] = load i64, ptr %[[RV]], align 4
+// CHECK:   store i64 42, ptr %[[RV]], align 8
+// CHECK:   %[[R:.*]] = load i64, ptr %[[RV]], align 8
 // CHECK:   ret i64 %[[R]]
 // CHECK: }
 
@@ -58,8 +58,8 @@ unsigned unsignedfunc() { return 42u; }
 unsigned long long ullfunc() { return 42ull; }
 // CHECK: define{{.*}} i64 @_Z7ullfuncv() {
 // CHECK:   %[[RV:.*]] = alloca i64, i64 1, align 8
-// CHECK:   store i64 42, ptr %[[RV]], align 4
-// CHECK:   %[[R:.*]] = load i64, ptr %[[RV]], align 4
+// CHECK:   store i64 42, ptr %[[RV]], align 8
+// CHECK:   %[[R:.*]] = load i64, ptr %[[RV]], align 8
 // CHECK:   ret i64 %[[R]]
 // CHECK: }
 
diff --git a/clang/tools/cir-opt/cir-opt.cpp b/clang/tools/cir-opt/cir-opt.cpp
index 0e20b97feced8..3dad3b18f7082 100644
--- a/clang/tools/cir-opt/cir-opt.cpp
+++ b/clang/tools/cir-opt/cir-opt.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
@@ -32,7 +33,8 @@ int main(int argc, char **argv) {
   // TODO: register needed MLIR passes for CIR?
   mlir::DialectRegistry registry;
   registry.insert<mlir::BuiltinDialect, cir::CIRDialect,
-                  mlir::memref::MemRefDialect, mlir::LLVM::LLVMDialect>();
+                  mlir::memref::MemRefDialect, mlir::LLVM::LLVMDialect,
+                  mlir::DLTIDialect>();
 
   ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
     return mlir::createCIRCanonicalizePass();



More information about the cfe-commits mailing list