Skip to content

Conversation

@timnoack
Copy link
Contributor

Enables locations to be used as operation attributes.

In contrast to the implicit source location every operation carries (Operation::getLoc())—which may be fused or modified during transformations—a LocationAttr used as an operation attribute has explicit semantics defined by the operation itself.

For example, in our Zig-like language frontend (where types are first-class values), we use a location attribute on struct type operations to store the declaration location, which is part of the type's semantic identity. Using an explicit attribute instead of Operation::getLoc() ensures this semantic information is preserved during transformations.

@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir mlir:ods labels Nov 12, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 12, 2025

@llvm/pr-subscribers-mlir-core

@llvm/pr-subscribers-mlir-ods

Author: Tim Noack (timnoack)

Changes

Enables locations to be used as operation attributes.

In contrast to the implicit source location every operation carries (Operation::getLoc())—which may be fused or modified during transformations—a LocationAttr used as an operation attribute has explicit semantics defined by the operation itself.

For example, in our Zig-like language frontend (where types are first-class values), we use a location attribute on struct type operations to store the declaration location, which is part of the type's semantic identity. Using an explicit attribute instead of Operation::getLoc() ensures this semantic information is preserved during transformations.


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

3 Files Affected:

  • (modified) mlir/include/mlir/IR/CommonAttrConstraints.td (+6-1)
  • (modified) mlir/test/IR/locations.mlir (+7)
  • (modified) mlir/test/lib/Dialect/Test/TestOps.td (+6)
diff --git a/mlir/include/mlir/IR/CommonAttrConstraints.td b/mlir/include/mlir/IR/CommonAttrConstraints.td
index b7e168a3e6f86..8ac1a2ea21422 100644
--- a/mlir/include/mlir/IR/CommonAttrConstraints.td
+++ b/mlir/include/mlir/IR/CommonAttrConstraints.td
@@ -188,7 +188,12 @@ class AnyAttrOf<list<Attr> allowedAttrs, string summary = "",
 }
 
 def LocationAttr : Attr<CPred<"::llvm::isa<::mlir::LocationAttr>($_self)">,
-                        "location attribute">;
+                        "location attribute"> {
+  let storageType = [{ ::mlir::LocationAttr }];
+  let returnType = [{ ::mlir::Location }];
+  let convertFromStorage = "::mlir::Location($_self)";
+  let constBuilderCall = "(::mlir::LocationAttr)$0";
+}
 
 def BoolAttr : Attr<CPred<"::llvm::isa<::mlir::BoolAttr>($_self)">, "bool attribute"> {
   let storageType = [{ ::mlir::BoolAttr }];
diff --git a/mlir/test/IR/locations.mlir b/mlir/test/IR/locations.mlir
index b725307b420b7..20d9889308302 100644
--- a/mlir/test/IR/locations.mlir
+++ b/mlir/test/IR/locations.mlir
@@ -105,3 +105,10 @@ func.func @dialect_location() {
   test.attr_with_loc("dialectLoc" loc(#test.custom_location<"foo.mlir"*32>))
   return
 }
+
+// CHECK-LABEL: @location_attr
+// CHECK: test.op_with_loc_attr loc("cheetos":10:20)
+func.func @location_attr() {
+  test.op_with_loc_attr loc("cheetos":10:20)
+  return
+}
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index cae0083f728e0..275025978a784 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -1192,6 +1192,12 @@ def TestLocationDstNoResOp : TEST_Op<"loc_dst_no_res"> {
   let results = (outs);
 }
 
+def TestLocationAttrOp : TEST_Op<"op_with_loc_attr"> {
+  let arguments = (ins LocationAttr:$loc_attr);
+  let results = (outs );
+  let assemblyFormat = "$loc_attr attr-dict";
+}
+
 //===----------------------------------------------------------------------===//
 // Test Patterns
 //===----------------------------------------------------------------------===//

@llvmbot
Copy link
Member

llvmbot commented Nov 12, 2025

@llvm/pr-subscribers-mlir

Author: Tim Noack (timnoack)

Changes

Enables locations to be used as operation attributes.

In contrast to the implicit source location every operation carries (Operation::getLoc())—which may be fused or modified during transformations—a LocationAttr used as an operation attribute has explicit semantics defined by the operation itself.

For example, in our Zig-like language frontend (where types are first-class values), we use a location attribute on struct type operations to store the declaration location, which is part of the type's semantic identity. Using an explicit attribute instead of Operation::getLoc() ensures this semantic information is preserved during transformations.


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

3 Files Affected:

  • (modified) mlir/include/mlir/IR/CommonAttrConstraints.td (+6-1)
  • (modified) mlir/test/IR/locations.mlir (+7)
  • (modified) mlir/test/lib/Dialect/Test/TestOps.td (+6)
diff --git a/mlir/include/mlir/IR/CommonAttrConstraints.td b/mlir/include/mlir/IR/CommonAttrConstraints.td
index b7e168a3e6f86..8ac1a2ea21422 100644
--- a/mlir/include/mlir/IR/CommonAttrConstraints.td
+++ b/mlir/include/mlir/IR/CommonAttrConstraints.td
@@ -188,7 +188,12 @@ class AnyAttrOf<list<Attr> allowedAttrs, string summary = "",
 }
 
 def LocationAttr : Attr<CPred<"::llvm::isa<::mlir::LocationAttr>($_self)">,
-                        "location attribute">;
+                        "location attribute"> {
+  let storageType = [{ ::mlir::LocationAttr }];
+  let returnType = [{ ::mlir::Location }];
+  let convertFromStorage = "::mlir::Location($_self)";
+  let constBuilderCall = "(::mlir::LocationAttr)$0";
+}
 
 def BoolAttr : Attr<CPred<"::llvm::isa<::mlir::BoolAttr>($_self)">, "bool attribute"> {
   let storageType = [{ ::mlir::BoolAttr }];
diff --git a/mlir/test/IR/locations.mlir b/mlir/test/IR/locations.mlir
index b725307b420b7..20d9889308302 100644
--- a/mlir/test/IR/locations.mlir
+++ b/mlir/test/IR/locations.mlir
@@ -105,3 +105,10 @@ func.func @dialect_location() {
   test.attr_with_loc("dialectLoc" loc(#test.custom_location<"foo.mlir"*32>))
   return
 }
+
+// CHECK-LABEL: @location_attr
+// CHECK: test.op_with_loc_attr loc("cheetos":10:20)
+func.func @location_attr() {
+  test.op_with_loc_attr loc("cheetos":10:20)
+  return
+}
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index cae0083f728e0..275025978a784 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -1192,6 +1192,12 @@ def TestLocationDstNoResOp : TEST_Op<"loc_dst_no_res"> {
   let results = (outs);
 }
 
+def TestLocationAttrOp : TEST_Op<"op_with_loc_attr"> {
+  let arguments = (ins LocationAttr:$loc_attr);
+  let results = (outs );
+  let assemblyFormat = "$loc_attr attr-dict";
+}
+
 //===----------------------------------------------------------------------===//
 // Test Patterns
 //===----------------------------------------------------------------------===//

@joker-eph joker-eph merged commit be2f875 into llvm:main Nov 13, 2025
10 checks passed
@timnoack timnoack deleted the locationattr-operand branch November 13, 2025 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mlir:core MLIR Core Infrastructure mlir:ods mlir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants