Skip to content

[CIR ] Add DLTI dialect support to module attributes #142241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,12 +37,20 @@ CIRGenerator::~CIRGenerator() {
assert(deferredInlineMemberFuncDefs.empty() || diags.hasErrorOccurred());
}

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>();

Expand All @@ -51,6 +61,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(); }
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ add_clang_library(clangCIR
CIROpenACCSupport
MLIRCIR
MLIRCIRInterfaces
MLIRTargetLLVMIRImport
)
22 changes: 22 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 1 addition & 0 deletions clang/lib/CIR/Dialect/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_clang_library(MLIRCIR
CIRDialect.cpp
CIRMemorySlot.cpp
CIRTypes.cpp
CIRDataLayout.cpp

DEPENDS
MLIRCIROpsIncGen
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CIR/CodeGen/dlti.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add another pair of RUN lines to test with a big-endian target?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I add a big-endian target triple, it might cause errors for others who haven't built LLVM with support for that architecture. Is there a way when the target isn't available?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I add a big-endian target triple, it might cause errors for others who haven't built LLVM with support for that architecture. Is there a way when the target isn't available?

You can add it in a separate test and use something like // REQUIRES: aarch64-registered-target (or whichever target you're testing).

// RUN: FileCheck --input-file=%t.cir %s --check-prefix=LITTLE

void foo() {}

// LITTLE-DAG: dlti.dl_spec =
// LITTLE-DAG: #dlti.dl_spec<
// LITTLE-DAG: i16 = dense<16> : vector<2xi64>,
// LITTLE-DAG: i32 = dense<32> : vector<2xi64>,
// LITTLE-DAG: i8 = dense<8> : vector<2xi64>,
// LITTLE-DAG: i1 = dense<8> : vector<2xi64>,
// LITTLE-DAG: !llvm.ptr = dense<64> : vector<4xi64>,
// LITTLE-DAG: f80 = dense<128> : vector<2xi64>,
// LITTLE-DAG: i128 = dense<128> : vector<2xi64>,
// LITTLE-DAG: !llvm.ptr<272> = dense<64> : vector<4xi64>,
// LITTLE-DAG: i64 = dense<64> : vector<2xi64>,
// LITTLE-DAG: !llvm.ptr<270> = dense<32> : vector<4xi64>,
// LITTLE-DAG: !llvm.ptr<271> = dense<32> : vector<4xi64>,
// LITTLE-DAG: f128 = dense<128> : vector<2xi64>,
// LITTLE-DAG: f16 = dense<16> : vector<2xi64>,
// LITTLE-DAG: f64 = dense<64> : vector<2xi64>,
// LITTLE-DAG: "dlti.stack_alignment" = 128 : i64
// LITTLE-DAG: "dlti.endianness" = "little"
23 changes: 23 additions & 0 deletions clang/test/CIR/CodeGen/dlti_be.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// REQUIRES: aarch64-registered-target
// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=BIG

void foo() {}

// BIG-DAG: dlti.dl_spec =
// BIG-DAG: #dlti.dl_spec<
// BIG-DAG: i16 = dense<[16, 32]> : vector<2xi64>,
// BIG-DAG: i32 = dense<32> : vector<2xi64>,
// BIG-DAG: i8 = dense<[8, 32]> : vector<2xi64>,
// BIG-DAG: i1 = dense<8> : vector<2xi64>,
// BIG-DAG: !llvm.ptr = dense<64> : vector<4xi64>,
// BIG-DAG: i128 = dense<128> : vector<2xi64>,
// BIG-DAG: !llvm.ptr<272> = dense<64> : vector<4xi64>,
// BIG-DAG: i64 = dense<64> : vector<2xi64>,
// BIG-DAG: !llvm.ptr<270> = dense<32> : vector<4xi64>,
// BIG-DAG: !llvm.ptr<271> = dense<32> : vector<4xi64>,
// BIG-DAG: f128 = dense<128> : vector<2xi64>,
// BIG-DAG: f16 = dense<16> : vector<2xi64>,
// BIG-DAG: f64 = dense<64> : vector<2xi64>,
// BIG-DAG: "dlti.stack_alignment" = 128 : i64
// BIG-DAG: "dlti.endianness" = "big"
8 changes: 4 additions & 4 deletions clang/test/CIR/Lowering/func-simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: }

Expand All @@ -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: }

Expand Down
4 changes: 3 additions & 1 deletion clang/tools/cir-opt/cir-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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();
Expand Down
Loading