[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