[clang] [mlir] [MLIR][LLVM] Preserve default function attributes on invokes (PR #212263)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 27 07:45:44 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Akimasa Watanuki (Men-cotton)
<details>
<summary>Changes</summary>
Represent `default_func_attrs` on `LLVM::InvokeOp` and translate the collection onto the generated LLVM invoke instruction. Preserve default call-site attributes when throwing calls are lowered through the LLVM dialect, including CIR `try_call` operations.
---
Full diff: https://github.com/llvm/llvm-project/pull/212263.diff
5 Files Affected:
- (added) clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp (+26)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+1)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+6-4)
- (modified) mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp (+3)
- (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+20)
``````````diff
diff --git a/clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp b/clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp
new file mode 100644
index 0000000000000..0e7dcd9c49d18
--- /dev/null
+++ b/clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -default-function-attr "key=value" -default-function-attr "just_key" -fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -default-function-attr "key=value" -default-function-attr "just_key" -fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -default-function-attr "key=value" -default-function-attr "just_key" -fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+extern "C" void may_throw();
+
+// CIR-LABEL: cir.func {{.*}}@caller()
+// CIR: cir.call @may_throw()
+// LLVM-LABEL: define{{.*}}@caller()
+// LLVM: invoke void @may_throw() #[[ATTRS:[0-9]+]]
+extern "C" void caller() {
+ try {
+ may_throw();
+ } catch (...) {
+ }
+}
+
+// CIR-SAME: default_func_attrs
+// CIR-SAME: just_key
+// CIR-SAME: key = "value"
+// LLVM: attributes #[[ATTRS]]
+// LLVM-SAME: "just_key"
+// LLVM-SAME: "key"="value"
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 4bdcf5f6c1cc5..42279011e9536 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -743,6 +743,7 @@ def LLVM_InvokeOp
Variadic<LLVM_Type>:$unwindDestOperands,
OptionalAttr<DenseI32ArrayAttr>:$branch_weights,
DefaultValuedAttr<CConv, "CConv::C">:$CConv,
+ OptionalAttr<DictionaryAttr>:$default_func_attrs,
VariadicOfVariadic<LLVM_Type,
"op_bundle_sizes">:$op_bundle_operands,
DenseI32ArrayAttr:$op_bundle_sizes,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f3dc00e177b0f..efa67fa9f9af6 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1569,7 +1569,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
build(builder, state, getCallOpResultTypes(calleeType),
getCallOpVarCalleeType(calleeType), SymbolRefAttr::get(func), ops,
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, normalOps, unwindOps,
- nullptr, nullptr, {}, {}, normal, unwind);
+ nullptr, nullptr, /*default_func_attrs=*/nullptr, {}, {}, normal,
+ unwind);
}
void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
@@ -1578,8 +1579,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
ValueRange unwindOps) {
build(builder, state, tys,
/*var_callee_type=*/nullptr, callee, ops, /*arg_attrs=*/nullptr,
- /*res_attrs=*/nullptr, normalOps, unwindOps, nullptr, nullptr, {}, {},
- normal, unwind);
+ /*res_attrs=*/nullptr, normalOps, unwindOps, nullptr, nullptr,
+ /*default_func_attrs=*/nullptr, {}, {}, normal, unwind);
}
void InvokeOp::build(OpBuilder &builder, OperationState &state,
@@ -1589,7 +1590,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
build(builder, state, getCallOpResultTypes(calleeType),
getCallOpVarCalleeType(calleeType), callee, ops,
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, normalOps, unwindOps,
- nullptr, nullptr, {}, {}, normal, unwind);
+ nullptr, nullptr, /*default_func_attrs=*/nullptr, {}, {}, normal,
+ unwind);
}
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 7cd8c3c77c15f..489ba85410771 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -689,6 +689,9 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
operandsRef.drop_front(), opBundles);
}
result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
+ moduleTranslation.convertFunctionAttrCollection(
+ invOp.getDefaultFuncAttrsAttr(), result,
+ ModuleTranslation::convertDefaultFuncAttr);
if (failed(moduleTranslation.convertArgAndResultAttrs(invOp, result)))
return failure();
moduleTranslation.mapBranch(invOp, result);
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index a665c72f4f54c..b9db5aa3e3180 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -3131,6 +3131,26 @@ llvm.func @default_func_attrs_call() {
// -----
+llvm.func @f()
+llvm.func @__gxx_personality_v0(...) -> i32
+
+// CHECK-LABEL: @default_func_attrs_invoke
+// CHECK: invoke void @f() #[[ATTRS:[0-9]+]]
+llvm.func @default_func_attrs_invoke() attributes {personality = @__gxx_personality_v0} {
+ llvm.invoke @f() to ^bb2 unwind ^bb1 {default_func_attrs={key="value", justKey}} : () -> ()
+^bb1:
+ %0 = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)>
+ llvm.return
+^bb2:
+ llvm.return
+}
+
+// CHECK: #[[ATTRS]]
+// CHECK-SAME: "justKey"
+// CHECK-SAME: "key"="value"
+
+// -----
+
llvm.func @f()
// CHECK-LABEL: @builtin_call
``````````
</details>
https://github.com/llvm/llvm-project/pull/212263
More information about the cfe-commits
mailing list