Author: Erich Keane Date: 2026-01-28T06:06:56-08:00 New Revision: 6682681fd2d79a2b1fc76a07605e580e0146daba
URL: https://github.com/llvm/llvm-project/commit/6682681fd2d79a2b1fc76a07605e580e0146daba DIFF: https://github.com/llvm/llvm-project/commit/6682681fd2d79a2b1fc76a07605e580e0146daba.diff LOG: [CIR] Implement returns_twice, cold, hot, noduplicate, convergent func attrs (#178289) Continuing my quest to get most of the attributes completed, this patch implements 5 attributes for CIR/Clang CIR codegen. 4 of the 5 are also implemented in LLVM-MLIR, since 'convergent' was already there. As a part of this, we also had to make sure that attributes were handled properly for Call operation lowering, like we do for function attributes. Added: clang/test/CIR/CodeGen/misc-attrs.cpp Modified: clang/include/clang/CIR/Dialect/IR/CIRDialect.td clang/lib/CIR/CodeGen/CIRGenCall.cpp clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp mlir/lib/Target/LLVMIR/ModuleImport.cpp mlir/lib/Target/LLVMIR/ModuleTranslation.cpp mlir/test/Dialect/LLVMIR/func.mlir mlir/test/Dialect/LLVMIR/roundtrip.mlir mlir/test/Target/LLVMIR/Import/function-attributes.ll mlir/test/Target/LLVMIR/Import/instructions.ll mlir/test/Target/LLVMIR/llvmir.mlir Removed: ################################################################################ diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td index 47ca625c34816..31cebdde1aa64 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td @@ -41,6 +41,12 @@ def CIR_Dialect : Dialect { static llvm::StringRef getNoThrowAttrName() { return "nothrow"; } static llvm::StringRef getNoReturnAttrName() { return "noreturn"; } static llvm::StringRef getSideEffectAttrName() { return "side_effect"; } + static llvm::StringRef getReturnsTwiceAttrName() { return "returns_twice"; } + static llvm::StringRef getColdAttrName() { return "cold"; } + static llvm::StringRef getHotAttrName() { return "hot"; } + static llvm::StringRef getNoDuplicatesAttrName() { return "noduplicate"; } + static llvm::StringRef getConvergentAttrName() { return "convergent"; } + static llvm::StringRef getNoUnwindAttrName() { return "nounwind"; } static llvm::StringRef getModuleLevelAsmAttrName() { return "cir.module_asm"; } static llvm::StringRef getGlobalCtorsAttrName() { return "cir.global_ctors"; } static llvm::StringRef getGlobalDtorsAttrName() { return "cir.global_dtors"; } diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index a7680d3b9e823..83b1c4e78c4d6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -122,9 +122,13 @@ void CIRGenModule::constructAttributeList(llvm::StringRef name, assert(!cir::MissingFeatures::opCallCallConv()); sideEffect = cir::SideEffect::All; + auto addUnitAttr = [&](llvm::StringRef name) { + attrs.set(name, mlir::UnitAttr::get(&getMLIRContext())); + }; + if (info.isNoReturn()) - attrs.set(cir::CIRDialect::getNoReturnAttrName(), - mlir::UnitAttr::get(&getMLIRContext())); + addUnitAttr(cir::CIRDialect::getNoReturnAttrName()); + // TODO(cir): Check/add cmse_nonsecure_call attribute here. addAttributesFromFunctionProtoType(getBuilder(), attrs, @@ -134,15 +138,23 @@ void CIRGenModule::constructAttributeList(llvm::StringRef name, if (targetDecl) { if (targetDecl->hasAttr<NoThrowAttr>()) - attrs.set(cir::CIRDialect::getNoThrowAttrName(), - mlir::UnitAttr::get(&getMLIRContext())); + addUnitAttr(cir::CIRDialect::getNoThrowAttrName()); // TODO(cir): This is actually only possible if targetDecl isn't a // declarator, which ObjCMethodDecl seems to be the only way to get this to // happen. We're including it here for completeness, but we should add a // test for this when we start generating ObjectiveC. if (targetDecl->hasAttr<NoReturnAttr>()) - attrs.set(cir::CIRDialect::getNoReturnAttrName(), - mlir::UnitAttr::get(&getMLIRContext())); + addUnitAttr(cir::CIRDialect::getNoReturnAttrName()); + if (targetDecl->hasAttr<ReturnsTwiceAttr>()) + addUnitAttr(cir::CIRDialect::getReturnsTwiceAttrName()); + if (targetDecl->hasAttr<ColdAttr>()) + addUnitAttr(cir::CIRDialect::getColdAttrName()); + if (targetDecl->hasAttr<HotAttr>()) + addUnitAttr(cir::CIRDialect::getHotAttrName()); + if (targetDecl->hasAttr<NoDuplicateAttr>()) + addUnitAttr(cir::CIRDialect::getNoDuplicatesAttrName()); + if (targetDecl->hasAttr<ConvergentAttr>()) + addUnitAttr(cir::CIRDialect::getConvergentAttrName()); if (const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) { addAttributesFromFunctionProtoType( diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 1894e92a485cd..091489c404642 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1606,6 +1606,22 @@ mlir::LogicalResult CIRToLLVMRotateOpLowering::matchAndRewrite( return mlir::LogicalResult::success(); } +static void lowerCallAttributes(cir::CIRCallOpInterface op, + SmallVectorImpl<mlir::NamedAttribute> &result) { + for (mlir::NamedAttribute attr : op->getAttrs()) { + assert(!cir::MissingFeatures::opFuncCallingConv()); + if (attr.getName() == CIRDialect::getCalleeAttrName() || + attr.getName() == CIRDialect::getSideEffectAttrName() || + attr.getName() == CIRDialect::getNoThrowAttrName() || + attr.getName() == CIRDialect::getNoUnwindAttrName() || + attr.getName() == CIRDialect::getNoReturnAttrName()) + continue; + + assert(!cir::MissingFeatures::opFuncExtraAttrs()); + result.push_back(attr); + } +} + static mlir::LogicalResult rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, mlir::ConversionPatternRewriter &rewriter, @@ -1627,6 +1643,9 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, convertSideEffectForCall(op, call.getNothrow(), call.getSideEffect(), memoryEffects, noUnwind, willReturn, noReturn); + SmallVector<mlir::NamedAttribute, 4> attributes; + lowerCallAttributes(call, attributes); + mlir::LLVM::LLVMFunctionType llvmFnTy; // Temporary to handle the case where we need to prepend an operand if the @@ -1684,6 +1703,7 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( op, llvmFnTy, calleeAttr, callOperands); + newOp->setAttrs(attributes); if (memoryEffects) newOp.setMemoryEffectsAttr(memoryEffects); newOp.setNoUnwind(noUnwind); diff --git a/clang/test/CIR/CodeGen/misc-attrs.cpp b/clang/test/CIR/CodeGen/misc-attrs.cpp new file mode 100644 index 0000000000000..837f99275c70d --- /dev/null +++ b/clang/test/CIR/CodeGen/misc-attrs.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -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 -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 -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM + +extern "C" { + // CIR: cir.func{{.*}}@returns_twice() attributes {returns_twice} { + // LLVM: Function Attrs:{{.*}}returns_twice + // LLVM-NEXT: define{{.*}}@returns_twice() #[[RT_ATTR:.*]] { + __attribute__((returns_twice)) + void returns_twice() {} + // CIR: cir.func{{.*}}@cold() attributes {cold} { + // LLVM: Function Attrs:{{.*}}cold + // LLVM-NEXT: define{{.*}}@cold() #[[COLD_ATTR:.*]] { + __attribute__((cold)) + void cold() {} + // CIR: cir.func{{.*}}@hot() attributes {hot} { + // LLVM: Function Attrs:{{.*}}hot + // LLVM-NEXT: define{{.*}}@hot() #[[HOT_ATTR:.*]] { + __attribute__((hot)) + void hot() {} + // CIR: cir.func{{.*}}@nodupes() attributes {noduplicate} { + // LLVM: Function Attrs:{{.*}}noduplicate + // LLVM-NEXT: define{{.*}}@nodupes() #[[ND_ATTR:.*]] { + __attribute__((noduplicate)) + void nodupes() {} + // CIR: cir.func{{.*}}@convergent() attributes {convergent} { + // LLVM: Function Attrs:{{.*}}convergent + // LLVM-NEXT: define{{.*}}@convergent() #[[CONV_ATTR:.*]] { + __attribute__((convergent)) + void convergent() {} + + void caller() { + // CIR: cir.call @returns_twice() {returns_twice} : () -> () + // LLVM: call void @returns_twice() #[[RT_CALL_ATTR:.*]] + returns_twice(); + // CIR: cir.call @cold() {cold} : () -> () + // LLVM: call void @cold() #[[COLD_CALL_ATTR:.*]] + cold(); + // CIR: cir.call @hot() {hot} : () -> () + // LLVM: call void @hot() #[[HOT_CALL_ATTR:.*]] + hot(); + // CIR: cir.call @nodupes() {noduplicate} : () -> () + // LLVM: call void @nodupes() #[[ND_CALL_ATTR:.*]] + nodupes(); + // CIR: cir.call @convergent() {convergent} : () -> () + // LLVM: call void @convergent() #[[CONV_CALL_ATTR:.*]] + convergent(); + } +} + +// LLVM: attributes #[[RT_ATTR]] = {{.*}}returns_twice +// LLVM: attributes #[[COLD_ATTR]] = {{.*}}cold +// LLVM: attributes #[[HOT_ATTR]] = {{.*}}hot +// LLVM: attributes #[[ND_ATTR]] = {{.*}}noduplicate +// LLVM: attributes #[[CONV_ATTR]] = {{.*}}convergent +// LLVM: attributes #[[RT_CALL_ATTR]] = {{.*}}returns_twice +// LLVM: attributes #[[COLD_CALL_ATTR]] = {{.*}}cold +// LLVM: attributes #[[HOT_CALL_ATTR]] = {{.*}}hot +// LLVM: attributes #[[ND_CALL_ATTR]] = {{.*}}noduplicate +// LLVM: attributes #[[CONV_CALL_ATTR]] = {{.*}}convergent diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 390d5a1ea7dfe..f6f1c90b481c5 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -795,7 +795,8 @@ def LLVM_CallOp DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$TailCallKind, OptionalAttr<LLVM_MemoryEffectsAttr>:$memory_effects, UnitAttr:$convergent, UnitAttr:$no_unwind, UnitAttr:$will_return, - UnitAttr:$noreturn, + UnitAttr:$noreturn, UnitAttr:$returns_twice, UnitAttr:$hot, + UnitAttr:$cold, UnitAttr:$noduplicate, VariadicOfVariadic<LLVM_Type, "op_bundle_sizes">:$op_bundle_operands, DenseI32ArrayAttr:$op_bundle_sizes, OptionalAttr<ArrayAttr>:$op_bundle_tags, @@ -1995,6 +1996,10 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [ OptionalAttr<UnitAttr>:$will_return, OptionalAttr<UnitAttr>:$noreturn, OptionalAttr<UnitAttr>:$optimize_none, + OptionalAttr<UnitAttr>:$returns_twice, + OptionalAttr<UnitAttr>:$hot, + OptionalAttr<UnitAttr>:$cold, + OptionalAttr<UnitAttr>:$noduplicate, OptionalAttr<LLVM_VecTypeHintAttr>:$vec_type_hint, OptionalAttr<DenseI32ArrayAttr>:$work_group_size_hint, OptionalAttr<DenseI32ArrayAttr>:$reqd_work_group_size, diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index d1c45bcb1656b..27d6355c9e221 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -995,7 +995,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results, /*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr, /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr, - /*noreturn=*/nullptr, + /*noreturn=*/nullptr, /*returns_twice=*/nullptr, /*hot=*/nullptr, + /*cold=*/nullptr, /*noduplicate=*/nullptr, /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, @@ -1027,6 +1028,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr, /*noreturn=*/nullptr, + /*returns_twice=*/nullptr, /*hot=*/nullptr, + /*cold=*/nullptr, /*noduplicate=*/nullptr, /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, /*access_groups=*/nullptr, @@ -1044,6 +1047,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, /*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr, /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr, /*noreturn=*/nullptr, + /*returns_twice=*/nullptr, /*hot=*/nullptr, + /*cold=*/nullptr, /*noduplicate=*/nullptr, /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, @@ -1061,6 +1066,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func, /*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr, /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr, /*noreturn=*/nullptr, + /*returns_twice=*/nullptr, /*hot=*/nullptr, + /*cold=*/nullptr, /*noduplicate=*/nullptr, /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp index b1d7f3ab7b777..31636abfff27f 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -423,6 +423,14 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, call->addFnAttr(llvm::Attribute::WillReturn); if (callOp.getNoreturnAttr()) call->addFnAttr(llvm::Attribute::NoReturn); + if (callOp.getReturnsTwiceAttr()) + call->addFnAttr(llvm::Attribute::ReturnsTwice); + if (callOp.getColdAttr()) + call->addFnAttr(llvm::Attribute::Cold); + if (callOp.getHotAttr()) + call->addFnAttr(llvm::Attribute::Hot); + if (callOp.getNoduplicateAttr()) + call->addFnAttr(llvm::Attribute::NoDuplicate); if (callOp.getNoInlineAttr()) call->addFnAttr(llvm::Attribute::NoInline); if (callOp.getAlwaysInlineAttr()) diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 555e72bd77358..928e7a57ae24f 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2653,11 +2653,13 @@ static constexpr std::array kExplicitLLVMFuncOpAttributes{ StringLiteral("aarch64_pstate_sm_compatible"), StringLiteral("aarch64_pstate_sm_enabled"), StringLiteral("alwaysinline"), + StringLiteral("cold"), StringLiteral("convergent"), StringLiteral("denormal-fp-math"), StringLiteral("denormal-fp-math-f32"), StringLiteral("fp-contract"), StringLiteral("frame-pointer"), + StringLiteral("hot"), StringLiteral("inlinehint"), StringLiteral("instrument-function-entry"), StringLiteral("instrument-function-exit"), @@ -2665,10 +2667,12 @@ static constexpr std::array kExplicitLLVMFuncOpAttributes{ StringLiteral("no-infs-fp-math"), StringLiteral("no-nans-fp-math"), StringLiteral("no-signed-zeros-fp-math"), + StringLiteral("noduplicate"), StringLiteral("noinline"), StringLiteral("noreturn"), StringLiteral("nounwind"), StringLiteral("optnone"), + StringLiteral("returns_twice"), StringLiteral("target-features"), StringLiteral("tune-cpu"), StringLiteral("uwtable"), @@ -2710,6 +2714,14 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, funcOp.setWillReturn(true); if (func->hasFnAttribute(llvm::Attribute::NoReturn)) funcOp.setNoreturn(true); + if (func->hasFnAttribute(llvm::Attribute::ReturnsTwice)) + funcOp.setReturnsTwice(true); + if (func->hasFnAttribute(llvm::Attribute::Cold)) + funcOp.setCold(true); + if (func->hasFnAttribute(llvm::Attribute::Hot)) + funcOp.setHot(true); + if (func->hasFnAttribute(llvm::Attribute::NoDuplicate)) + funcOp.setNoduplicate(true); if (func->hasFnAttribute("aarch64_pstate_sm_enabled")) funcOp.setArmStreaming(true); @@ -2931,6 +2943,12 @@ LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst, op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid()); op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid()); op.setNoreturn(callAttrs.getFnAttr(llvm::Attribute::NoReturn).isValid()); + op.setReturnsTwice( + callAttrs.getFnAttr(llvm::Attribute::ReturnsTwice).isValid()); + op.setHot(callAttrs.getFnAttr(llvm::Attribute::Hot).isValid()); + op.setCold(callAttrs.getFnAttr(llvm::Attribute::Cold).isValid()); + op.setNoduplicate( + callAttrs.getFnAttr(llvm::Attribute::NoDuplicate).isValid()); op.setNoInline(callAttrs.getFnAttr(llvm::Attribute::NoInline).isValid()); op.setAlwaysInline( callAttrs.getFnAttr(llvm::Attribute::AlwaysInline).isValid()); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 46a0b97f1edbd..79d65ffe4e551 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1670,6 +1670,14 @@ static void convertFunctionAttributes(LLVMFuncOp func, llvmFunc->addFnAttr(llvm::Attribute::InlineHint); if (func.getOptimizeNoneAttr()) llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone); + if (func.getReturnsTwiceAttr()) + llvmFunc->addFnAttr(llvm::Attribute::ReturnsTwice); + if (func.getColdAttr()) + llvmFunc->addFnAttr(llvm::Attribute::Cold); + if (func.getHotAttr()) + llvmFunc->addFnAttr(llvm::Attribute::Hot); + if (func.getNoduplicateAttr()) + llvmFunc->addFnAttr(llvm::Attribute::NoDuplicate); if (func.getConvergentAttr()) llvmFunc->addFnAttr(llvm::Attribute::Convergent); if (func.getNoUnwindAttr()) diff --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir index 936260f862a98..a66087e431eee 100644 --- a/mlir/test/Dialect/LLVMIR/func.mlir +++ b/mlir/test/Dialect/LLVMIR/func.mlir @@ -330,6 +330,30 @@ module { llvm.return } + llvm.func @returnstwice_function() attributes {returnstwice} { + // CHECK: @returnstwice_function + // CHECK-SAME: attributes {returnstwice} + llvm.return + } + + llvm.func @hot_function() attributes {hot} { + // CHECK: @hot_function + // CHECK-SAME: attributes {hot} + llvm.return + } + + llvm.func @cold_function() attributes {cold} { + // CHECK: @cold_function + // CHECK-SAME: attributes {cold} + llvm.return + } + + llvm.func @noduplicate_function() attributes {noduplicate} { + // CHECK: @noduplicate_function + // CHECK-SAME: attributes {noduplicate} + llvm.return + } + } // ----- diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir index fc2456b350a56..9ce45afd96c25 100644 --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -125,6 +125,18 @@ func.func @ops(%arg0: i32, %arg1: f32, // CHECK: llvm.call @baz() {noreturn} : () -> () llvm.call @baz() {noreturn} : () -> () +// CHECK: llvm.call @baz() {returns_twice} : () -> () + llvm.call @baz() {returns_twice} : () -> () + +// CHECK: llvm.call @baz() {hot} : () -> () + llvm.call @baz() {hot} : () -> () + +// CHECK: llvm.call @baz() {cold} : () -> () + llvm.call @baz() {cold} : () -> () + +// CHECK: llvm.call @baz() {noduplicate} : () -> () + llvm.call @baz() {noduplicate} : () -> () + // CHECK: llvm.call @baz() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write, errnoMem = none, targetMem0 = none, targetMem1 = none>} : () -> () llvm.call @baz() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write, errnoMem = none, targetMem0 = none, targetMem1 = none>} : () -> () diff --git a/mlir/test/Target/LLVMIR/Import/function-attributes.ll b/mlir/test/Target/LLVMIR/Import/function-attributes.ll index 69e18e1c5bbff..1002ad03c227c 100644 --- a/mlir/test/Target/LLVMIR/Import/function-attributes.ll +++ b/mlir/test/Target/LLVMIR/Import/function-attributes.ll @@ -417,5 +417,29 @@ declare void @noreturn_attribute() noreturn // ----- +; CHECK-LABEL: @returnstwice_attribute +; CHECK-SAME: attributes {returns_twice} +declare void @returnstwice_attribute() returns_twice + +// ----- + +; CHECK-LABEL: @hot_attribute +; CHECK-SAME: attributes {hot} +declare void @hot_attribute() hot + +// ----- + +; CHECK-LABEL: @cold_attribute +; CHECK-SAME: attributes {cold} +declare void @cold_attribute() cold + +// ----- + +; CHECK-LABEL: @noduplicate_attribute +; CHECK-SAME: attributes {noduplicate} +declare void @noduplicate_attribute() noduplicate + +// ----- + ; expected-warning @unknown {{'preallocated' attribute is invalid on current operation, skipping it}} declare void @test() preallocated(i32) diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll index 766f19ce386f8..11ebd70def8ce 100644 --- a/mlir/test/Target/LLVMIR/Import/instructions.ll +++ b/mlir/test/Target/LLVMIR/Import/instructions.ll @@ -713,6 +713,54 @@ define void @call_noreturn() { ; CHECK: llvm.func @f() declare void @f() +; CHECK-LABEL: @call_returnstwice +define void @call_returnstwice() { +; CHECK: llvm.call @f() {returns_twice} + call void @f() returns_twice + ret void +} + +; // ----- + +; CHECK: llvm.func @f() +declare void @f() + +; CHECK-LABEL: @call_hot +define void @call_hot() { +; CHECK: llvm.call @f() {hot} + call void @f() hot + ret void +} + +; // ----- + +; CHECK: llvm.func @f() +declare void @f() + +; CHECK-LABEL: @call_cold +define void @call_cold() { +; CHECK: llvm.call @f() {cold} + call void @f() cold + ret void +} + +; // ----- + +; CHECK: llvm.func @f() +declare void @f() + +; CHECK-LABEL: @call_noduplicate +define void @call_noduplicate() { +; CHECK: llvm.call @f() {noduplicate} + call void @f() noduplicate + ret void +} + +; // ----- + +; CHECK: llvm.func @f() +declare void @f() + ; CHECK-LABEL: @call_memory_effects define void @call_memory_effects() { ; CHECK: llvm.call @f() {memory_effects = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none, errnoMem = none, targetMem0 = none, targetMem1 = none>} diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 12d73b429b3ce..8adf305805b0e 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -2642,6 +2642,50 @@ llvm.func @noreturn() attributes { noreturn } { // ----- +// CHECK-LABEL: @returnstwice +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @returnstwice() attributes { returns_twice } { + llvm.return +} + +// CHECK: #[[ATTRS]] +// CHECK-SAME: returns_twice + +// ----- + +// CHECK-LABEL: @hot +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @hot() attributes { hot } { + llvm.return +} + +// CHECK: #[[ATTRS]] +// CHECK-SAME: hot + +// ----- + +// CHECK-LABEL: @cold +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @cold() attributes { cold } { + llvm.return +} + +// CHECK: #[[ATTRS]] +// CHECK-SAME:cold + +// ----- + +// CHECK-LABEL: @noduplicate +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @noduplicate() attributes { noduplicate } { + llvm.return +} + +// CHECK: #[[ATTRS]] +// CHECK-SAME: noduplicate + +// ----- + llvm.func @f() // CHECK-LABEL: @convergent_call _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
