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

Conversation

Andres-Salamanca
Copy link
Contributor

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 #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.

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels May 30, 2025
@llvmbot
Copy link
Member

llvmbot commented May 30, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: None (Andres-Salamanca)

Changes

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 #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.


Full diff: https://github.com/llvm/llvm-project/pull/142241.diff

8 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h (+9-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenerator.cpp (+14)
  • (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1)
  • (added) clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp (+22)
  • (modified) clang/lib/CIR/Dialect/IR/CMakeLists.txt (+1)
  • (added) clang/test/CIR/CodeGen/dlti.c (+23)
  • (modified) clang/test/CIR/Lowering/func-simple.cpp (+4-4)
  • (modified) clang/tools/cir-opt/cir-opt.cpp (+3-1)
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();

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

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

This seems right, but please make sure @andykaylor, @xlauko or @bcardosolopes approves before merging.

Copy link
Contributor

@xlauko xlauko left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

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

This looks good, pending an update to the test.

@@ -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).

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

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

LGTM pending RUN line suggestion by Andy

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

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

lgtm

@Andres-Salamanca Andres-Salamanca merged commit dc9b8fe into llvm:main Jun 5, 2025
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 5, 2025

LLVM Buildbot has detected a new failure on builder clang-ppc64-aix running on aix-ppc64 while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/64/builds/4061

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang-Unit :: ./AllClangUnitTests/18/192' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/build/tools/clang/unittests/./AllClangUnitTests-Clang-Unit-22544718-18-192.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=192 GTEST_SHARD_INDEX=18 /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/build/tools/clang/unittests/./AllClangUnitTests
--

Note: This is test shard 19 of 192.
[==========] Running 128 tests from 36 test suites.
[----------] Global test environment set-up.
[----------] 1 test from RecursiveASTVisitor
[ RUN      ] RecursiveASTVisitor.NoCrash
input.cc:3:20: error: a type specifier is required for all declarations
    3 |      class a(b(a::*)) class
      |                    ^
input.cc:3:22: error: expected ';' after top level declarator
    3 |      class a(b(a::*)) class
      |                      ^
      |                      ;
input.cc:3:23: error: declaration of anonymous class must be a definition
    3 |      class a(b(a::*)) class
      |                       ^
input.cc:4:3: error: expected unqualified-id
    4 |   
      |   ^
4 errors generated.
[       OK ] RecursiveASTVisitor.NoCrash (41 ms)
[----------] 1 test from RecursiveASTVisitor (41 ms total)

[----------] 1 test from TemplateName
[ RUN      ] TemplateName.PrintUsingTemplate
[       OK ] TemplateName.PrintUsingTemplate (49 ms)
[----------] 1 test from TemplateName (49 ms total)

[----------] 1 test from addTargetAndModeForProgramName
[ RUN      ] addTargetAndModeForProgramName.IgnoresExistingMode
[       OK ] addTargetAndModeForProgramName.IgnoresExistingMode (2 ms)
[----------] 1 test from addTargetAndModeForProgramName (2 ms total)

[----------] 1 test from HeaderMapTest
[ RUN      ] HeaderMapTest.lookupFilenameTruncatedPrefix
[       OK ] HeaderMapTest.lookupFilenameTruncatedPrefix (0 ms)
[----------] 1 test from HeaderMapTest (0 ms total)

[----------] 1 test from TransferTest
[ RUN      ] TransferTest.ResultObjectLocation
[       OK ] TransferTest.ResultObjectLocation (37 ms)
[----------] 1 test from TransferTest (37 ms total)

[----------] 1 test from GtestExpectTest
[ RUN      ] GtestExpectTest.NeShouldMatchExpectNe
...

@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 6, 2025

LLVM Buildbot has detected a new failure on builder flang-aarch64-latest-gcc running on linaro-flang-aarch64-latest-gcc while building clang at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/130/builds/13587

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
276.387 [1131/104/6221] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-nullify.cpp.o
276.800 [1131/103/6222] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/attr.cpp.o
278.635 [1131/102/6223] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-return.cpp.o
282.700 [1131/101/6224] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-allocate.cpp.o
284.892 [1131/100/6225] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/openacc-parsers.cpp.o
285.188 [1131/99/6226] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-modifiers.cpp.o
287.117 [1131/98/6227] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/Coarray.cpp.o
287.390 [1131/97/6228] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/program-tree.cpp.o
292.362 [1131/96/6229] Building CXX object tools/flang/lib/Frontend/CMakeFiles/flangFrontend.dir/CompilerInstance.cpp.o
294.986 [1131/95/6230] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-dsa.cpp.o
command timed out: 1200 seconds without output running [b'ninja'], attempting to kill
process killed by signal 9
program finished with exit code -1
elapsedTime=1495.157682

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants