[MLIR][LLVM] Preserve default function attributes on invokes (#212263)
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.
This commit is contained in:
parent
022bf7ba97
commit
9ccf2a81a1
5 changed files with 56 additions and 4 deletions
26
clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp
Normal file
26
clang/test/CIR/CodeGen/default-func-attrs-invoke.cpp
Normal file
|
|
@ -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"
|
||||||
|
|
@ -743,6 +743,7 @@ def LLVM_InvokeOp
|
||||||
Variadic<LLVM_Type>:$unwindDestOperands,
|
Variadic<LLVM_Type>:$unwindDestOperands,
|
||||||
OptionalAttr<DenseI32ArrayAttr>:$branch_weights,
|
OptionalAttr<DenseI32ArrayAttr>:$branch_weights,
|
||||||
DefaultValuedAttr<CConv, "CConv::C">:$CConv,
|
DefaultValuedAttr<CConv, "CConv::C">:$CConv,
|
||||||
|
OptionalAttr<DictionaryAttr>:$default_func_attrs,
|
||||||
VariadicOfVariadic<LLVM_Type,
|
VariadicOfVariadic<LLVM_Type,
|
||||||
"op_bundle_sizes">:$op_bundle_operands,
|
"op_bundle_sizes">:$op_bundle_operands,
|
||||||
DenseI32ArrayAttr:$op_bundle_sizes,
|
DenseI32ArrayAttr:$op_bundle_sizes,
|
||||||
|
|
|
||||||
|
|
@ -1569,7 +1569,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
|
||||||
build(builder, state, getCallOpResultTypes(calleeType),
|
build(builder, state, getCallOpResultTypes(calleeType),
|
||||||
getCallOpVarCalleeType(calleeType), SymbolRefAttr::get(func), ops,
|
getCallOpVarCalleeType(calleeType), SymbolRefAttr::get(func), ops,
|
||||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, normalOps, unwindOps,
|
/*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,
|
void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
|
||||||
|
|
@ -1578,8 +1579,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
|
||||||
ValueRange unwindOps) {
|
ValueRange unwindOps) {
|
||||||
build(builder, state, tys,
|
build(builder, state, tys,
|
||||||
/*var_callee_type=*/nullptr, callee, ops, /*arg_attrs=*/nullptr,
|
/*var_callee_type=*/nullptr, callee, ops, /*arg_attrs=*/nullptr,
|
||||||
/*res_attrs=*/nullptr, normalOps, unwindOps, nullptr, nullptr, {}, {},
|
/*res_attrs=*/nullptr, normalOps, unwindOps, nullptr, nullptr,
|
||||||
normal, unwind);
|
/*default_func_attrs=*/nullptr, {}, {}, normal, unwind);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvokeOp::build(OpBuilder &builder, OperationState &state,
|
void InvokeOp::build(OpBuilder &builder, OperationState &state,
|
||||||
|
|
@ -1589,7 +1590,8 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
|
||||||
build(builder, state, getCallOpResultTypes(calleeType),
|
build(builder, state, getCallOpResultTypes(calleeType),
|
||||||
getCallOpVarCalleeType(calleeType), callee, ops,
|
getCallOpVarCalleeType(calleeType), callee, ops,
|
||||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, normalOps, unwindOps,
|
/*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) {
|
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
|
||||||
|
|
|
||||||
|
|
@ -689,6 +689,9 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
|
||||||
operandsRef.drop_front(), opBundles);
|
operandsRef.drop_front(), opBundles);
|
||||||
}
|
}
|
||||||
result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
|
result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
|
||||||
|
moduleTranslation.convertFunctionAttrCollection(
|
||||||
|
invOp.getDefaultFuncAttrsAttr(), result,
|
||||||
|
ModuleTranslation::convertDefaultFuncAttr);
|
||||||
if (failed(moduleTranslation.convertArgAndResultAttrs(invOp, result)))
|
if (failed(moduleTranslation.convertArgAndResultAttrs(invOp, result)))
|
||||||
return failure();
|
return failure();
|
||||||
moduleTranslation.mapBranch(invOp, result);
|
moduleTranslation.mapBranch(invOp, result);
|
||||||
|
|
|
||||||
|
|
@ -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()
|
llvm.func @f()
|
||||||
|
|
||||||
// CHECK-LABEL: @builtin_call
|
// CHECK-LABEL: @builtin_call
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue