[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits


@@ -115,6 +115,50 @@ def CIR_SourceLanguageAttr : 
CIR_EnumAttr {
   }];
 }
 
+//===--===//
+// OffloadKindAttr
+//===--===//
+
+def CIR_OffloadKind : CIR_I32Enum<"OffloadKind", "offload kind", [
+  I32EnumAttrCase<"Host", 0, "host">,
+  I32EnumAttrCase<"Device", 1, "device">

xlauko wrote:

```suggestion
  I32EnumCase<"Host", 0, "host">,
  I32EnumCase<"Device", 1, "device">
```

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits


@@ -110,6 +111,87 @@ Operation 
*cir::CIRDialect::materializeConstant(mlir::OpBuilder &builder,
  mlir::cast(value));
 }
 
+//===--===//
+// Dialect attribute verification
+//===--===//
+
+static LogicalResult verifyOffloadKind(mlir::ModuleOp module,
+   cir::OffloadKind expected) {
+  auto attr = module->getAttrOfType(
+  cir::CIRDialect::getOffloadKindAttrName());
+  if (!attr)
+return module.emitOpError()
+   << "expects '" << cir::CIRDialect::getOffloadKindAttrName()
+   << "' offload kind attribute";
+  if (attr.getValue() != expected)
+return module.emitOpError()
+   << "expects '" << cir::CIRDialect::getOffloadKindAttrName()
+   << "' value '" << cir::stringifyOffloadKind(expected) << "'";
+  return success();
+}
+
+// A module marked with `cir.offload.container` holds the host module followed
+// by one or more device modules, each tagged with `cir.offload.kind`. Keeping
+// the host module first gives later offload passes a simple convention for
+// finding the host side while iterating the remaining device modules.
+static LogicalResult verifyOffloadContainer(mlir::Operation *op) {
+  auto container = mlir::dyn_cast(op);
+  if (!container)
+return op->emitError() << "expects '"
+   << cir::CIRDialect::getOffloadContainerAttrName()
+   << "' attribute to be attached to '"
+   << mlir::ModuleOp::getOperationName() << "'";
+
+  mlir::Block &body = *container.getBody();
+  if (body.empty())
+return container.emitOpError()
+   << "expects host module as the first nested op";
+
+  auto host = mlir::dyn_cast(body.front());
+  if (!host)
+return container.emitOpError()
+   << "expects host module as the first nested op";
+  if (failed(verifyOffloadKind(host, cir::OffloadKind::Host)))
+return failure();
+
+  auto it = body.begin();
+  ++it;

xlauko wrote:

use `llvm::drop_begin(body)`

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits


@@ -115,6 +115,50 @@ def CIR_SourceLanguageAttr : 
CIR_EnumAttr {
   }];
 }
 
+//===--===//
+// OffloadKindAttr
+//===--===//
+
+def CIR_OffloadKind : CIR_I32Enum<"OffloadKind", "offload kind", [
+  I32EnumAttrCase<"Host", 0, "host">,
+  I32EnumAttrCase<"Device", 1, "device">
+]>;
+
+def CIR_OffloadKindAttr : CIR_EnumAttr {

xlauko wrote:

```suggestion
def CIR_OffloadKindAttr : CIR_EnumAttr {
```

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits




xlauko wrote:

Use CHECK-LABEL in between modules here

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits


@@ -110,6 +111,87 @@ Operation 
*cir::CIRDialect::materializeConstant(mlir::OpBuilder &builder,
  mlir::cast(value));
 }
 
+//===--===//
+// Dialect attribute verification
+//===--===//
+
+static LogicalResult verifyOffloadKind(mlir::ModuleOp module,
+   cir::OffloadKind expected) {
+  auto attr = module->getAttrOfType(
+  cir::CIRDialect::getOffloadKindAttrName());
+  if (!attr)
+return module.emitOpError()
+   << "expects '" << cir::CIRDialect::getOffloadKindAttrName()
+   << "' offload kind attribute";
+  if (attr.getValue() != expected)
+return module.emitOpError()
+   << "expects '" << cir::CIRDialect::getOffloadKindAttrName()
+   << "' value '" << cir::stringifyOffloadKind(expected) << "'";
+  return success();
+}
+
+// A module marked with `cir.offload.container` holds the host module followed
+// by one or more device modules, each tagged with `cir.offload.kind`. Keeping
+// the host module first gives later offload passes a simple convention for
+// finding the host side while iterating the remaining device modules.
+static LogicalResult verifyOffloadContainer(mlir::Operation *op) {
+  auto container = mlir::dyn_cast(op);
+  if (!container)
+return op->emitError() << "expects '"

xlauko wrote:

nit: emitOpError as everywhere else?

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-08 Thread Henrich Lauko via cfe-commits


@@ -115,6 +115,50 @@ def CIR_SourceLanguageAttr : 
CIR_EnumAttr {
   }];
 }
 
+//===--===//
+// OffloadKindAttr
+//===--===//
+
+def CIR_OffloadKind : CIR_I32Enum<"OffloadKind", "offload kind", [
+  I32EnumAttrCase<"Host", 0, "host">,
+  I32EnumAttrCase<"Device", 1, "device">
+]>;
+
+def CIR_OffloadKindAttr : CIR_EnumAttr {

xlauko wrote:

I recently moved all enum attributes to not spell `_kind`.
Can you fix this also in test expectaions.

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-07 Thread David Rivera via cfe-commits

https://github.com/RiverDave updated 
https://github.com/llvm/llvm-project/pull/206576

>From be1086b6453cc16402913c60f145a39abe7b3630 Mon Sep 17 00:00:00 2001
From: David Rivera 
Date: Mon, 29 Jun 2026 15:46:11 -0400
Subject: [PATCH 1/5] [CIR] Add offload container operation

Introduce cir.offload.container, a CIR dialect operation that groups one host 
CIR module with one or more device CIR modules in a single IR unit.

Nested modules are tagged with the new cir.offload.kind enum attribute using 
#cir.offload_kind and #cir.offload_kind. The verifier enforces 
the structural contract expected by follow-up offload merge/split pipeline 
patches: host module first, device modules after it, only nested builtin.module 
ops, and at least one device module.

This patch only adds the IR representation and verifier tests; the passes that 
create, consume, or split the container are left to later patches.
---
 .../clang/CIR/Dialect/IR/CIRDialect.td|  1 +
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 59 ++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp   | 61 +++
 .../test/CIR/IR/invalid-offload-container.cir | 54 
 clang/test/CIR/IR/offload-container.cir   | 32 ++
 5 files changed, 207 insertions(+)
 create mode 100644 clang/test/CIR/IR/invalid-offload-container.cir
 create mode 100644 clang/test/CIR/IR/offload-container.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 9ea186489ac65..00c8cfe008408 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -53,6 +53,7 @@ def CIR_Dialect : Dialect {
 static llvm::StringRef getModuleLevelAsmAttrName() { return 
"cir.module_asm"; }
 static llvm::StringRef getGlobalCtorsAttrName() { return 
"cir.global_ctors"; }
 static llvm::StringRef getGlobalDtorsAttrName() { return 
"cir.global_dtors"; }
+static llvm::StringRef getOffloadKindAttrName() { return 
"cir.offload.kind"; }
 static llvm::StringRef getOperandSegmentSizesAttrName() { return 
"operandSegmentSizes"; }
 static llvm::StringRef getNoCallerSavedRegsAttrName() { return 
"no_caller_saved_registers"; }
 static llvm::StringRef getNoCallbackAttrName() { return "nocallback"; }
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6d149e6b1ccaa..158b97adfbe4e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6141,6 +6141,65 @@ def CIR_VecSplatOp : CIR_Op<"vec.splat", [
   }];
 }
 
+//===--===//
+// OffloadKind
+//===--===//
+
+def CIR_OffloadKind : CIR_I32EnumAttr<"OffloadKind", "offload kind", [
+  I32EnumAttrCase<"Host", 0, "host">,
+  I32EnumAttrCase<"Device", 1, "device">
+]> {
+  let genSpecializedAttr = 0;
+}
+
+def CIR_OffloadKindAttr : CIR_EnumAttr {
+  let summary = "Offload kind (host or device)";
+}
+
+//===--===//
+// OffloadContainerOp
+//===--===//
+
+def CIR_OffloadContainerOp : CIR_Op<"offload.container", [
+NoRegionArguments, NoTerminator, SingleBlock, SymbolTable]> {
+  let summary = "Container for host and device CIR modules";
+  let description = [{
+`cir.offload.container` groups one host CIR module with one or more device
+CIR modules for offload-aware analysis and transformation.
+
+The body holds nested `builtin.module` operations. The first nested
+module is the host module and must carry
+`cir.offload.kind = #cir.offload_kind`. All remaining nested
+modules are device modules and must carry
+`cir.offload.kind = #cir.offload_kind`. There must be at least
+one device module.
+
+Example:
+
+```mlir
+cir.offload.container {
+  builtin.module @host attributes {cir.offload.kind = 
#cir.offload_kind} {
+  }
+  builtin.module @device_0 attributes {cir.offload.kind = 
#cir.offload_kind} {
+  }
+}
+```
+  }];
+
+  let regions = (region SizedRegion<1>:$body);
+
+  let assemblyFormat = "$body attr-dict";
+
+  let hasVerifier = 1;
+  let hasLLVMLowering = false;
+
+  let extraClassDeclaration = [{
+mlir::ModuleOp getHostModule();
+llvm::iterator_range>
+getDeviceModules();
+  }];
+}
+
 
//===--===//
 // BaseClassAddrOp
 
//===--===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 606b4fd9d3fa6..b36424aa31ded 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -18,6 +18,7 

[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-07 Thread via cfe-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

The build failed before running any tests. Click on a failure below to see the 
details.


tools/clang/include/clang/CIR/Dialect/IR/CIROps.cpp.inc 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.cpp.inc

```
FAILED: tools/clang/include/clang/CIR/Dialect/IR/CIROps.cpp.inc 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.cpp.inc
cd 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR
 && 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/mlir-tblgen 
-gen-op-defs 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/../mlir/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/mlir/include
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIROps.td
 --write-if-changed -o CIROps.cpp.inc -d CIROps.cpp.inc.d && /usr/bin/cmake -E 
cmake_transform_depfile Ninja gccdepfile 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR
 /home/gha/actions-runner/_work/llvm-project/llvm-project/build 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.cpp.inc.d
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/CMakeFiles/d/297aa97d4942a28141fed5d98d7a7b47ed99f97ad95009e6f242827f56aab6e8.d
Included from 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIROps.td:19:
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td:122:23:
 error: Couldn't find class 'CIR_I32EnumAttr'
def CIR_OffloadKind : CIR_I32EnumAttr<"OffloadKind", "offload kind", [
^
```


tools/clang/include/clang/CIR/Dialect/IR/CIROps.h.inc 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.h.inc

```
FAILED: tools/clang/include/clang/CIR/Dialect/IR/CIROps.h.inc 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.h.inc
cd 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR
 && 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/mlir-tblgen 
-gen-op-decls 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/../mlir/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/mlir/include
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIROps.td
 --write-if-changed -o CIROps.h.inc -d CIROps.h.inc.d && /usr/bin/cmake -E 
cmake_transform_depfile Ninja gccdepfile 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR
 /home/gha/actions-runner/_work/llvm-project/llvm-project/build 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROps.h.inc.d
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/CMakeFiles/d/d02f6e2d322101f4177025222c3d0ddebc6b552e28b76e179488dc79b0bd40d6.d
Included from 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIROps.td:19:
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td:122:23:
 error: Couldn't find class 'CIR_I32EnumAttr'
def CIR_OffloadKind : CIR_I32EnumAttr<"OffloadKind", "offload kind", [
^
```


tools/clang/include/clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc

```
FAILED: 

[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-02 Thread David Rivera via cfe-commits

https://github.com/RiverDave edited 
https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-02 Thread David Rivera via cfe-commits

RiverDave wrote:

gentle ping @andykaylor :)

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add offload container attribute (PR #206576)

2026-09-01 Thread David Rivera via cfe-commits

RiverDave wrote:

> Desing looks good. I can see you have some deviations from gpu dialect:
> 
> 1. GPU keeps `verifyOperationAttribute` trivial, just checks the `attr` sits 
> on ModuleOp, and defers structural checks to reference sites. This PR front 
> loads the verification. It is stricter and potentially more costly.
> 2. You introduce a strict ordering, host is first, gpu dialect does not 
> impose this. Our passes rely on `front() = host`. No strong feelings about 
> this, I would add a comment about it though to document the behavior.
> 3. gpu.dialect uses a dedicated `gpu.module`; In your PR code lives in nested 
> builtin.module. This is the design you propose. I am ok with this, but before 
> merging I would expect  to add a note confirming your design choice.
> 
> The PR title says "Op", now it is an attribute.
> 
> Some NITS:
> 
> The functions `isOffloadContainer` / `getOffloadHostModule` / 
> `getOffloadDeviceModules` have no coverage, and currently are not being 
> called. It is worthwhile to add some unit tests to lock their behavior, since 
> next optimizations will rely on these.

I've Dropped the three helpers from this patch instead of adding tests for them.

They have no callers yet, so a test could only re-assert what the verifier 
already guarantees (host module first, device modules after), which 
`offload-container.cir` and `invalid-offload-container.cir` cover. They'll come 
back with their first consumer in the merge/split pass work, where FileCheck 
over the pass exercises them directly -- think it'll make it easier to review 
for all of us.

https://github.com/llvm/llvm-project/pull/206576
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits