diff --git a/toolchain/check/cpp/export.cpp b/toolchain/check/cpp/export.cpp index 08052418e67b..7a2204a72d7f 100644 --- a/toolchain/check/cpp/export.cpp +++ b/toolchain/check/cpp/export.cpp @@ -1607,8 +1607,10 @@ static auto BuildCarbonToCarbonThunk(Context& context, SemIR::LocId loc_id, // If this thunk will be exposed as a C++ constructor, we put the output // parameter first to match the Itanium constructor ABI. // - // TODO: use `clang::CodeGen::CGCXXABI::HasThisReturn` to determine if the - // constructor's `this` should be a return value instead of an output param. + // Some C++ ABIs also return `this` from constructors. We don't model that + // here; instead, lowering defines the thunk in the LLVM function Clang + // creates for its C++ declaration, and returns `this` if Clang's signature + // does. See `FileContext::GetCppThunkLLVMFunction`. if (target.export_as_constructor) { CARBON_CHECK(target.return_type_id != SemIR::TypeId::None); std::rotate(thunk_param_type_ids.begin(), thunk_param_type_ids.end() - 1, @@ -1626,6 +1628,9 @@ static auto BuildCarbonToCarbonThunk(Context& context, SemIR::LocId loc_id, .param_type_ids = thunk_param_type_ids, .param_kinds = thunk_param_kinds}) .second; + context.functions() + .Get(carbon_thunk_function_id) + .SetCppThunk(target.function.first_decl_id()); BuildThunkDefinitionForExport( context, carbon_thunk_function_id, target.function_id, @@ -1673,6 +1678,20 @@ static auto BuildCppToCarbonThunk(Context& context, SemIR::LocId loc_id, return; } + // Map the Carbon thunk to its C++ declaration, so that lowering can define + // the thunk in the same LLVM function that Clang uses to call it. + SemIR::ClangDeclSignature carbon_function_signature{ + .kind = SemIR::ClangDeclSignature::Normal, + .num_params = static_cast(carbon_function_decl->getNumParams())}; + carbon_function_signature.passing_modes.assign( + carbon_function_signature.num_params, + SemIR::ClangDeclSignature::PassingMode::ByValue); + context.clang_decls().Add( + {.key = SemIR::ClangDeclKey::ForFunctionDecl( + carbon_function_decl, context.clang_decl_signatures().Add( + std::move(carbon_function_signature))), + .inst_id = carbon_thunk_target.function.first_decl_id()}); + // Build the thunk function body. clang::Sema& sema = context.clang_sema(); clang::Sema::ContextRAII context_raii(sema, thunk_function_decl); diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index d4714ea0940e..d0b1063c64c8 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -16,6 +16,7 @@ #include "common/vlog.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" +#include "llvm/IR/Instructions.h" #include "llvm/Linker/Linker.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -335,6 +336,45 @@ auto FileContext::HandleReferencedCppFunction(clang::FunctionDecl* cpp_decl) return function_address; } +auto FileContext::GetCppThunkLLVMFunction( + const FunctionTypeInfo& function_type_info, clang::FunctionDecl* cpp_decl) + -> llvm::Function* { + // Ask Clang for its function for the thunk, creating its declaration if it + // doesn't exist yet. Clang names it based on the thunk's asm label, which + // may differ from Carbon's name for it in the IR (for example, `\01`-prefixed + // on targets with a global symbol prefix). Using Clang's function means that + // C++ calls to the thunk refer to its definition in the IR. + // TODO: This code generator can be for the wrong AST if we're not using + // --share-cpp-ast. + auto* llvm_function = + dyn_cast(context().cpp_code_generator()->GetAddrOfGlobal( + CreateGlobalDecl(cpp_decl), /*isForDefinition=*/false)); + CARBON_CHECK(llvm_function); + + // The thunk takes all of its parameters by reference, so Clang should lower + // them the same way we do. However, some C++ ABIs return `this` from + // constructors; `BuildFunctionBody` handles that. + auto* cpp_type = llvm_function->getFunctionType(); + auto* carbon_type = function_type_info.type; + CARBON_CHECK(llvm::equal(cpp_type->params(), carbon_type->params()), + "C++ thunk parameter types don't match: {0} vs {1}", *cpp_type, + *carbon_type); + CARBON_CHECK( + cpp_type->getReturnType() == carbon_type->getReturnType() || + (carbon_type->getReturnType()->isVoidTy() && + llvm_function->hasParamAttribute(0, llvm::Attribute::Returned)), + "C++ thunk return types don't match: {0} vs {1}", *cpp_type, + *carbon_type); + CARBON_CHECK(function_type_info.sret_type == nullptr, + "C++ thunks return through an explicit output parameter"); + + for (auto [name_id, arg] : llvm::zip_equal(function_type_info.param_name_ids, + llvm_function->args())) { + arg.setName(sem_ir().names().GetIRBaseName(name_id)); + } + return llvm_function; +} + auto FileContext::HandleReferencedSpecificFunction( SemIR::FunctionId function_id, SemIR::SpecificId specific_id, llvm::Type* llvm_type) -> void { @@ -371,6 +411,13 @@ auto FileContext::GetOrCreateLLVMFunction( "Specific functions cannot have C++ definitions"); return HandleReferencedCppFunction(clang_decl->decl()->getAsFunction()); } + if (function.special_function_kind == + SemIR::Function::SpecialFunctionKind::CppThunk) { + CARBON_CHECK(!specific_id.has_value(), + "Specific functions cannot be C++ thunks"); + return GetCppThunkLLVMFunction(function_type_info, + clang_decl->decl()->getAsFunction()); + } } } @@ -686,6 +733,23 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id, lower_block(block_id); } + // Some C++ ABIs return `this` from constructors. If Clang's declaration of a + // C++ thunk does that, return the parameter it marks as `returned` instead + // of returning nothing. + if (declaration_function.special_function_kind == + SemIR::Function::SpecialFunctionKind::CppThunk && + !function_info->llvm_function->getReturnType()->isVoidTy() && + function_info->type->getReturnType()->isVoidTy()) { + auto* this_arg = function_info->llvm_function->getArg(0); + for (auto& llvm_block : *function_info->llvm_function) { + auto* ret = dyn_cast(llvm_block.getTerminator()); + if (ret && !ret->getReturnValue()) { + llvm::ReturnInst::Create(llvm_context(), this_arg, ret->getIterator()); + ret->eraseFromParent(); + } + } + } + // LLVM requires that the entry block has no predecessors. auto* entry_block = &function_info->llvm_function->getEntryBlock(); if (entry_block->hasNPredecessorsOrMore(1)) { @@ -715,8 +779,17 @@ auto FileContext::BuildDISubprogram(const SemIR::Function& function, } auto loc = GetLocForDI(function.definition_id); llvm::DISubroutineType* subroutine_type = function_info.di_type; + // A function named by Clang from an asm label has a `\01` marker followed + // by the target's global prefix, if any. Use the unprefixed name, matching + // other functions. + llvm::StringRef linkage_name = function_info.llvm_function->getName(); + if (linkage_name.consume_front("\1")) { + if (char global_prefix = llvm_module().getDataLayout().getGlobalPrefix()) { + linkage_name.consume_front(llvm::StringRef(&global_prefix, 1)); + } + } auto* subprogram = context().di_builder().createFunction( - context().di_compile_unit(), name, function_info.llvm_function->getName(), + context().di_compile_unit(), name, linkage_name, /*File=*/context().di_builder().createFile(loc.filename, ""), /*LineNo=*/loc.line_number, subroutine_type, /*ScopeLine=*/0, llvm::DINode::FlagZero, diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 035baa7eaf90..de885ee1e149 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -211,6 +211,13 @@ class FileContext { auto HandleReferencedCppFunction(clang::FunctionDecl* cpp_decl) -> llvm::Function*; + // Gets the LLVM function that Clang uses for a Carbon thunk exported to C++, + // given the thunk's C++ declaration. The thunk's definition is lowered into + // this function. + auto GetCppThunkLLVMFunction(const FunctionTypeInfo& function_type_info, + clang::FunctionDecl* cpp_decl) + -> llvm::Function*; + // Notes that a specific function has been referenced for the first time. // Updates the fingerprint to include the function's type, and adds the // function to the list of specific functions whose definitions should be diff --git a/toolchain/lower/testdata/interop/cpp/array.carbon b/toolchain/lower/testdata/interop/cpp/array.carbon index 7c170ca40e6b..0dbfc4b1ce96 100644 --- a/toolchain/lower/testdata/interop/cpp/array.carbon +++ b/toolchain/lower/testdata/interop/cpp/array.carbon @@ -87,7 +87,7 @@ int H() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.Main(ptr %_, ptr %_1) #3 !dbg !40 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.Main(ptr noundef nonnull align 4 dereferenceable(20) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #4 !dbg !40 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %F.call = call i32 @_CF.Main(ptr %_), !dbg !43 // CHECK:STDOUT: store i32 %F.call, ptr %_1, align 4, !dbg !43 @@ -98,6 +98,7 @@ int H() { // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #3 = { nounwind } +// CHECK:STDOUT: attributes #4 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!25} // CHECK:STDOUT: !llvm.module.flags = !{!51, !52, !53, !6, !7} diff --git a/toolchain/lower/testdata/interop/cpp/class/export/class.carbon b/toolchain/lower/testdata/interop/cpp/class/export/class.carbon index d79e02e5cf21..95a40e859ee1 100644 --- a/toolchain/lower/testdata/interop/cpp/class/export/class.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/export/class.carbon @@ -301,7 +301,7 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CCallLayoutA__carbon_thunk.Main(ptr %_) #5 !dbg !67 { +// CHECK:STDOUT: define void @_CCallLayoutA__carbon_thunk.Main(ptr noundef nonnull align 8 dereferenceable(8) %_) #6 !dbg !67 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc21 = load ptr, ptr %_, align 8, !dbg !69 // CHECK:STDOUT: call void @_CCallLayoutA.Main(ptr %.loc21), !dbg !69 @@ -336,7 +336,7 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CCallLayoutB__carbon_thunk.Main(ptr %_) #5 !dbg !83 { +// CHECK:STDOUT: define void @_CCallLayoutB__carbon_thunk.Main(ptr noundef nonnull align 8 dereferenceable(8) %_) #6 !dbg !83 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc22 = load ptr, ptr %_, align 8, !dbg !85 // CHECK:STDOUT: call void @_CCallLayoutB.Main(ptr %.loc22), !dbg !85 @@ -371,7 +371,7 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CCallLayoutC__carbon_thunk.Main(ptr %_) #5 !dbg !99 { +// CHECK:STDOUT: define void @_CCallLayoutC__carbon_thunk.Main(ptr noundef nonnull align 8 dereferenceable(8) %_) #6 !dbg !99 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc23 = load ptr, ptr %_, align 8, !dbg !101 // CHECK:STDOUT: call void @_CCallLayoutC.Main(ptr %.loc23), !dbg !101 @@ -418,6 +418,7 @@ fn G() { // CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #4 = { alwaysinline nounwind } // CHECK:STDOUT: attributes #5 = { nounwind } +// CHECK:STDOUT: attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!49} // CHECK:STDOUT: !llvm.module.flags = !{!43, !44, !45, !19, !20} diff --git a/toolchain/lower/testdata/interop/cpp/class/export/method.carbon b/toolchain/lower/testdata/interop/cpp/class/export/method.carbon index 85313134e569..5337db5feb08 100644 --- a/toolchain/lower/testdata/interop/cpp/class/export/method.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/export/method.carbon @@ -124,7 +124,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.A.Main(ptr %self) #4 !dbg !35 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.A.Main(ptr noundef nonnull align 1 %self) #6 !dbg !35 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.A.Main(ptr %self), !dbg !37 // CHECK:STDOUT: ret void, !dbg !37 @@ -141,6 +141,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #4 = { nounwind } // CHECK:STDOUT: attributes #5 = { alwaysinline nounwind } +// CHECK:STDOUT: attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!21} // CHECK:STDOUT: !llvm.module.flags = !{!51, !52, !53, !4, !5} @@ -247,7 +248,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.ArgsA.Main(ptr %self, ptr %_, ptr %_1) #4 !dbg !81 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.ArgsA.Main(ptr noundef nonnull align 1 %self, ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #6 !dbg !81 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc6_29.2 = load i32, ptr %_, align 4, !dbg !85 // CHECK:STDOUT: %ArgsA.F.call = call i32 @_CF.ArgsA.Main(ptr %self, i32 %.loc6_29.2), !dbg !85 @@ -273,6 +274,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #4 = { nounwind } // CHECK:STDOUT: attributes #5 = { alwaysinline nounwind } +// CHECK:STDOUT: attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!58} // CHECK:STDOUT: !llvm.module.flags = !{!51, !52, !53, !4, !5} @@ -362,7 +364,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.StaticA.Main() #2 !dbg !112 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.StaticA.Main() #4 !dbg !112 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.StaticA.Main(), !dbg !113 // CHECK:STDOUT: ret void, !dbg !113 @@ -384,6 +386,7 @@ fn CallCallF() { Cpp.CallStaticF(); } // CHECK:STDOUT: attributes #1 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #2 = { nounwind } // CHECK:STDOUT: attributes #3 = { alwaysinline nounwind } +// CHECK:STDOUT: attributes #4 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!103} // CHECK:STDOUT: !llvm.module.flags = !{!51, !52, !53, !4, !5} diff --git a/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon b/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon index 9c769ae0d976..cde108a4d60c 100644 --- a/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon @@ -125,14 +125,14 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_Cfunc__carbon_thunk.Derived.Main(ptr %self) #2 !dbg !74 { +// CHECK:STDOUT: define void @_Cfunc__carbon_thunk.Derived.Main(ptr noundef nonnull align 8 dereferenceable(12) %self) #4 !dbg !74 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_Cfunc.Derived.Main(ptr %self), !dbg !76 // CHECK:STDOUT: ret void, !dbg !76 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_Cother_func__carbon_thunk.Derived.Main(ptr %self) #2 !dbg !78 { +// CHECK:STDOUT: define void @_Cother_func__carbon_thunk.Derived.Main(ptr noundef nonnull align 8 dereferenceable(12) %self) #4 !dbg !78 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %Derived.other_func.call.vtable = load ptr, ptr %self, align 8, !dbg !80 // CHECK:STDOUT: %Derived.other_func.call = call ptr @llvm.load.relative.i32(ptr %Derived.other_func.call.vtable, i32 8), !dbg !80 @@ -158,7 +158,7 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZN4BaseC1Ev.carbon_thunk.(ptr noundef %return) #4 { +// CHECK:STDOUT: define internal void @_ZN4BaseC1Ev.carbon_thunk.(ptr noundef %return) #5 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %return.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !4 @@ -179,13 +179,13 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: read) -// CHECK:STDOUT: declare ptr @llvm.load.relative.i32(ptr, i32) #5 +// CHECK:STDOUT: declare ptr @llvm.load.relative.i32(ptr, i32) #6 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #6 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #7 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZNR6Carbon4Main7Derived4funcEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #4 align 2 { +// CHECK:STDOUT: define internal void @_ZNR6Carbon4Main7Derived4funcEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #5 align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !110 @@ -195,7 +195,7 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZNK6Carbon4Main7Derived10other_funcEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #4 align 2 { +// CHECK:STDOUT: define internal void @_ZNK6Carbon4Main7Derived10other_funcEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #5 align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !110 @@ -205,7 +205,7 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN4BaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #7 comdat align 2 { +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN4BaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr #8 comdat align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !4 @@ -216,7 +216,7 @@ fn DoThing() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN11FurtherBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #7 comdat align 2 { +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN11FurtherBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #8 comdat align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !108 @@ -234,10 +234,11 @@ fn DoThing() { // CHECK:STDOUT: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #2 = { nounwind } // CHECK:STDOUT: attributes #3 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #4 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #5 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } -// CHECK:STDOUT: attributes #6 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } -// CHECK:STDOUT: attributes #7 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #4 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #5 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #6 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } +// CHECK:STDOUT: attributes #7 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #8 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!40} // CHECK:STDOUT: !llvm.module.flags = !{!115, !116, !117, !7, !8} diff --git a/toolchain/lower/testdata/interop/cpp/class/virtual_fn.carbon b/toolchain/lower/testdata/interop/cpp/class/virtual_fn.carbon index b340b53ede3b..4a8a617e7079 100644 --- a/toolchain/lower/testdata/interop/cpp/class/virtual_fn.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/virtual_fn.carbon @@ -231,7 +231,7 @@ void delete_new_Base() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.Final.Main(ptr %self) #8 !dbg !49 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.Final.Main(ptr noundef nonnull align 8 dereferenceable(8) %self) #7 !dbg !49 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.Final.Main(ptr %self), !dbg !51 // CHECK:STDOUT: ret void, !dbg !51 @@ -262,7 +262,7 @@ void delete_new_Base() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.Base.Main(ptr %self) #8 !dbg !66 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.Base.Main(ptr noundef nonnull align 8 dereferenceable(8) %self) #7 !dbg !66 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.Base.Main(ptr %self), !dbg !68 // CHECK:STDOUT: ret void, !dbg !68 diff --git a/toolchain/lower/testdata/interop/cpp/class/virtual_fn_carbon_only.carbon b/toolchain/lower/testdata/interop/cpp/class/virtual_fn_carbon_only.carbon index c30acc92d969..4e6eed9ed660 100644 --- a/toolchain/lower/testdata/interop/cpp/class/virtual_fn_carbon_only.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/virtual_fn_carbon_only.carbon @@ -101,7 +101,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_Cf__carbon_thunk.Z.Main(ptr %self) #1 !dbg !41 { +// CHECK:STDOUT: define void @_Cf__carbon_thunk.Z.Main(ptr noundef nonnull align 8 dereferenceable(8) %self) #3 !dbg !41 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_Cf.Z.Main(ptr %self), !dbg !43 // CHECK:STDOUT: ret void, !dbg !43 @@ -122,7 +122,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZN1XC1Ev.carbon_thunk.(ptr noundef %return) #3 { +// CHECK:STDOUT: define internal void @_ZN1XC1Ev.carbon_thunk.(ptr noundef %return) #4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %return.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !69 @@ -143,10 +143,10 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #4 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #5 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZN6Carbon4Main1Z1fEv(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #3 align 2 { +// CHECK:STDOUT: define internal void @_ZN6Carbon4Main1Z1fEv(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #4 align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !73 @@ -156,7 +156,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1XC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #5 comdat align 2 { +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1XC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #6 comdat align 2 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %this.addr = alloca ptr, align 8 // CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !69 @@ -172,9 +172,10 @@ fn F() { // CHECK:STDOUT: attributes #0 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #1 = { nounwind } // CHECK:STDOUT: attributes #2 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #3 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } -// CHECK:STDOUT: attributes #5 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #4 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #5 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #6 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!13} // CHECK:STDOUT: !llvm.module.flags = !{!76, !77, !78, !2, !3} diff --git a/toolchain/lower/testdata/interop/cpp/function/export/constructor.carbon b/toolchain/lower/testdata/interop/cpp/function/export/constructor.carbon index 663101edd84c..5c4252f12cf6 100644 --- a/toolchain/lower/testdata/interop/cpp/function/export/constructor.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/export/constructor.carbon @@ -39,10 +39,10 @@ void f() { // CHECK:STDOUT: define dso_local void @_Z1fv() #0 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a = alloca %"class.Carbon::Main::OneArg", align 1 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %a) #5 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %a) #6 // CHECK:STDOUT: call void @_ZN6Carbon4Main6OneArgC2Ei(ptr noundef nonnull align 1 %a, i32 noundef 42) -// CHECK:STDOUT: call void @_ZN6Carbon4Main6OneArgD2Ev(ptr noundef nonnull align 1 %a) #5 -// CHECK:STDOUT: call void @llvm.lifetime.end.p0(ptr %a) #5 +// CHECK:STDOUT: call void @_ZN6Carbon4Main6OneArgD2Ev(ptr noundef nonnull align 1 %a) #6 +// CHECK:STDOUT: call void @llvm.lifetime.end.p0(ptr %a) #6 // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: @@ -84,7 +84,7 @@ void f() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_COneArg__carbon_thunk.OneArg.Main(ptr %_, ptr %_1) #5 !dbg !19 { +// CHECK:STDOUT: define void @_COneArg__carbon_thunk.OneArg.Main(ptr noundef nonnull align 1 %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) unnamed_addr #5 !dbg !19 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc6_28.2 = load i32, ptr %_1, align 4, !dbg !22 // CHECK:STDOUT: call void @_COneArg.OneArg.Main(ptr %_, i32 %.loc6_28.2), !dbg !22 @@ -92,7 +92,7 @@ void f() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f5db22251d2a7ef4(ptr %t) #5 !dbg !25 { +// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f5db22251d2a7ef4(ptr %t) #6 !dbg !25 { // CHECK:STDOUT: ret void, !dbg !30 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -101,7 +101,8 @@ void f() { // CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #4 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #5 = { nounwind } +// CHECK:STDOUT: attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #6 = { nounwind } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!6} // CHECK:STDOUT: !llvm.module.flags = !{!39, !40, !41, !3, !4} diff --git a/toolchain/lower/testdata/interop/cpp/function/export/default_values.carbon b/toolchain/lower/testdata/interop/cpp/function/export/default_values.carbon index 81f16fc36496..3d6ca07762d6 100644 --- a/toolchain/lower/testdata/interop/cpp/function/export/default_values.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/export/default_values.carbon @@ -125,7 +125,7 @@ void CallF() { // CHECK:STDOUT: declare void @_CF.OtherFunction(i32) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.OtherFunction(ptr %_) #2 !dbg !41 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.OtherFunction(ptr noundef nonnull align 4 dereferenceable(4) %_) #2 !dbg !41 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.1 = load i32, ptr %_, align 4, !dbg !43 // CHECK:STDOUT: call void @_CF.OtherFunction(i32 %.1), !dbg !43 @@ -135,7 +135,7 @@ void CallF() { // CHECK:STDOUT: declare void @_CF.FirstFunction(i32) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.FirstFunction(ptr %_) #2 !dbg !45 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.FirstFunction(ptr noundef nonnull align 4 dereferenceable(4) %_) #2 !dbg !45 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.1 = load i32, ptr %_, align 4, !dbg !47 // CHECK:STDOUT: call void @_CF.FirstFunction(i32 %.1), !dbg !47 @@ -143,7 +143,7 @@ void CallF() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define internal void @_C__global_init.Main() #2 !dbg !51 { +// CHECK:STDOUT: define internal void @_C__global_init.Main() #3 !dbg !51 { // CHECK:STDOUT: entry: // CHECK:STDOUT: store i32 23, ptr @_C__carbon_default_value__CF.OtherFunction_0.Main, align 4 // CHECK:STDOUT: store i32 0, ptr @_C__carbon_default_value__CF.FirstFunction_0.Main, align 4 @@ -152,7 +152,8 @@ void CallF() { // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #1 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #2 = { nounwind } +// CHECK:STDOUT: attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { nounwind } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!40} // CHECK:STDOUT: !llvm.module.flags = !{!53, !54, !55, !6, !7} diff --git a/toolchain/lower/testdata/interop/cpp/function/export/function.carbon b/toolchain/lower/testdata/interop/cpp/function/export/function.carbon index 009bb60ae6cb..c3fcc682403e 100644 --- a/toolchain/lower/testdata/interop/cpp/function/export/function.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/export/function.carbon @@ -221,7 +221,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: declare void @_CBoolArg.Other(i1) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CBoolArg__carbon_thunk.Other(ptr %_) #2 !dbg !44 { +// CHECK:STDOUT: define void @_CBoolArg__carbon_thunk.Other(ptr noundef nonnull align 1 dereferenceable(1) %_) #2 !dbg !44 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.1 = load i8, ptr %_, align 1, !dbg !46 // CHECK:STDOUT: %.11 = trunc i8 %.1 to i1, !dbg !46 @@ -232,7 +232,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: declare void @_CIntArg.Other(i32) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CIntArg__carbon_thunk.Other(ptr %_) #2 !dbg !48 { +// CHECK:STDOUT: define void @_CIntArg__carbon_thunk.Other(ptr noundef nonnull align 4 dereferenceable(4) %_) #2 !dbg !48 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.1 = load i32, ptr %_, align 4, !dbg !50 // CHECK:STDOUT: call void @_CIntArg.Other(i32 %.1), !dbg !50 @@ -242,7 +242,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: declare void @_CFloatArg.Other(float) // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CFloatArg__carbon_thunk.Other(ptr %_) #2 !dbg !52 { +// CHECK:STDOUT: define void @_CFloatArg__carbon_thunk.Other(ptr noundef nonnull align 4 dereferenceable(4) %_) #2 !dbg !52 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.1 = load float, ptr %_, align 4, !dbg !54 // CHECK:STDOUT: call void @_CFloatArg.Other(float %.1), !dbg !54 @@ -252,7 +252,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: declare i32 @_CIntReturn.Other() // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CIntReturn__carbon_thunk.Other(ptr %_) #2 !dbg !56 { +// CHECK:STDOUT: define void @_CIntReturn__carbon_thunk.Other(ptr noundef nonnull align 4 dereferenceable(4) %_) #2 !dbg !56 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %IntReturn.call = call i32 @_CIntReturn.Other(), !dbg !58 // CHECK:STDOUT: store i32 %IntReturn.call, ptr %_, align 4, !dbg !58 @@ -261,7 +261,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #1 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #2 = { nounwind } +// CHECK:STDOUT: attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!41} // CHECK:STDOUT: !llvm.module.flags = !{!68, !69, !70, !2, !3} @@ -329,7 +329,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.Main() #0 !dbg !77 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.Main() #1 !dbg !77 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.Main(), !dbg !78 // CHECK:STDOUT: ret void, !dbg !78 @@ -343,29 +343,30 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_Z2G2v() #1 comdat { +// CHECK:STDOUT: define linkonce_odr dso_local void @_Z2G2v() #2 comdat { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_Z2G1v() // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_Z2G1v() #1 comdat { +// CHECK:STDOUT: define linkonce_odr dso_local void @_Z2G1v() #2 comdat { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_ZN6Carbon4MainL1FEv() // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZN6Carbon4MainL1FEv() #2 { +// CHECK:STDOUT: define internal void @_ZN6Carbon4MainL1FEv() #3 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF__carbon_thunk.Main() // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { inlinehint mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { inlinehint mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!74} // CHECK:STDOUT: !llvm.module.flags = !{!68, !69, !70, !2, !3} @@ -408,7 +409,7 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_Cbase__carbon_thunk.Main() #0 !dbg !86 { +// CHECK:STDOUT: define void @_Cbase__carbon_thunk.Main() #1 !dbg !86 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_Cbase.Main(), !dbg !87 // CHECK:STDOUT: ret void, !dbg !87 @@ -422,22 +423,23 @@ fn CallCallBase() { Cpp.CallBase(); } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress uwtable -// CHECK:STDOUT: define linkonce_odr dso_local void @_Z8CallBasev() #1 comdat { +// CHECK:STDOUT: define linkonce_odr dso_local void @_Z8CallBasev() #2 comdat { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_ZN6Carbon4MainL4baseEv() // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal void @_ZN6Carbon4MainL4baseEv() #2 { +// CHECK:STDOUT: define internal void @_ZN6Carbon4MainL4baseEv() #3 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_Cbase__carbon_thunk.Main() // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { inlinehint mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { inlinehint mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!83} // CHECK:STDOUT: !llvm.module.flags = !{!68, !69, !70, !2, !3} diff --git a/toolchain/lower/testdata/interop/cpp/function/export/generic.carbon b/toolchain/lower/testdata/interop/cpp/function/export/generic.carbon index 7c0ae588321c..9da8ac8d2297 100644 --- a/toolchain/lower/testdata/interop/cpp/function/export/generic.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/export/generic.carbon @@ -196,14 +196,14 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.26f2099a79512a5d.Main(ptr %_) #4 !dbg !42 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.26f2099a79512a5d.Main(ptr noundef nonnull align 1 %_) #6 !dbg !42 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.Main.6662a1ffb773360a(ptr %_), !dbg !44 // CHECK:STDOUT: ret void, !dbg !44 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CF__carbon_thunk.7a3b9f04ddf4269e.Main(ptr %_) #4 !dbg !46 { +// CHECK:STDOUT: define void @_CF__carbon_thunk.7a3b9f04ddf4269e.Main(ptr noundef nonnull align 1 %_) #6 !dbg !46 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CF.Main.d53b17eed3ce903c(ptr %_), !dbg !48 // CHECK:STDOUT: ret void, !dbg !48 @@ -252,6 +252,7 @@ fn Run() { // CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #4 = { nounwind } // CHECK:STDOUT: attributes #5 = { alwaysinline nounwind } +// CHECK:STDOUT: attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!15} // CHECK:STDOUT: !llvm.module.flags = !{!86, !87, !88, !4, !5} diff --git a/toolchain/lower/testdata/interop/cpp/function/export/macho_asm_label.carbon b/toolchain/lower/testdata/interop/cpp/function/export/macho_asm_label.carbon new file mode 100644 index 000000000000..55167d4b4bd6 --- /dev/null +++ b/toolchain/lower/testdata/interop/cpp/function/export/macho_asm_label.carbon @@ -0,0 +1,368 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/full.carbon +// Mach-O has a global symbol prefix (`_`), so Clang refers to Carbon functions +// exported to C++ using an `\01`-prefixed asm label name. Check that those +// references resolve to the Carbon definitions in the IR. +// EXTRA-ARGS: --target=arm64-apple-macosx14.0 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interop/cpp/function/export/macho_asm_label.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interop/cpp/function/export/macho_asm_label.carbon + +// --- function.carbon + +library "[[@TEST_NAME]]"; + +import Cpp; + +fn F(i: i32) -> i32 { return i; } + +inline Cpp ''' +int G() { + return Carbon::F(1); +} +'''; + +fn H() -> i32 { return Cpp.G(); } + +// --- constructor.carbon + +library "[[@TEST_NAME]]"; + +import Cpp; + +class C { + fn C(i: i32) -> Self { + return {.i = i}; + } + + var i: i32; +} + +inline Cpp ''' +int G() { + Carbon::C c(42); + return c.i; +} +'''; + +fn H() -> i32 { return Cpp.G(); } + +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'function.carbon' +// CHECK:STDOUT: source_filename = "function.carbon" +// CHECK:STDOUT: target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" +// CHECK:STDOUT: target triple = "arm64-apple-macosx14.0.0" +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress ssp uwtable(sync) +// CHECK:STDOUT: define noundef i32 @_Z1Gv() #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %call = call noundef i32 @_ZN6Carbon4MainL1FEi(i32 noundef 1) +// CHECK:STDOUT: ret i32 %call +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind ssp uwtable(sync) +// CHECK:STDOUT: define internal noundef i32 @_ZN6Carbon4MainL1FEi(i32 noundef %0) #1 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %retval = alloca i32, align 4 +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !36 +// CHECK:STDOUT: call void @"\01__CF__carbon_thunk.Main"(ptr noundef nonnull align 4 dereferenceable(4) %.addr, ptr noundef nonnull align 4 dereferenceable(4) %retval) +// CHECK:STDOUT: %1 = load i32, ptr %retval, align 4 +// CHECK:STDOUT: ret i32 %1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define i32 @_CF.Main(i32 %i) #2 !dbg !18 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret i32 %i, !dbg !24 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @"\01__CF__carbon_thunk.Main"(ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #3 !dbg !26 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc6 = load i32, ptr %_, align 4, !dbg !29 +// CHECK:STDOUT: %F.call = call i32 @_CF.Main(i32 %.loc6), !dbg !29 +// CHECK:STDOUT: store i32 %F.call, ptr %_1, align 4, !dbg !29 +// CHECK:STDOUT: ret void, !dbg !29 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define i32 @_CH.Main() #2 !dbg !31 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %G.call = call i32 @_Z1Gv(), !dbg !34 +// CHECK:STDOUT: ret i32 %G.call, !dbg !35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { mustprogress ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #1 = { alwaysinline mustprogress nounwind ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #2 = { nounwind } +// CHECK:STDOUT: attributes #3 = { nounwind "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!10} +// CHECK:STDOUT: !llvm.module.flags = !{!37, !38, !39, !7, !8} +// CHECK:STDOUT: !llvm.errno.tbaa = !{!41} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{!"Simple C++ TBAA"} +// CHECK:STDOUT: !1 = !{!"omnipotent char", !0, i64 0} +// CHECK:STDOUT: !2 = !{!"int", !1, i64 0} +// CHECK:STDOUT: !7 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !8 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !9 = !DIFile(filename: "function.carbon", directory: "") +// CHECK:STDOUT: !10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !9, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK:STDOUT: !12 = !{!11, !11} +// CHECK:STDOUT: !13 = !DISubroutineType(types: !12) +// CHECK:STDOUT: !14 = !{null, !11, !11} +// CHECK:STDOUT: !15 = !DISubroutineType(types: !14) +// CHECK:STDOUT: !16 = !{!11} +// CHECK:STDOUT: !17 = !DISubroutineType(types: !16) +// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !9, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !10, retainedNodes: !25) +// CHECK:STDOUT: !19 = !DILocalVariable(arg: 1, scope: !18, type: !11) +// CHECK:STDOUT: !24 = !DILocation(line: 6, column: 23, scope: !18) +// CHECK:STDOUT: !25 = !{!19} +// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "F__carbon_thunk", linkageName: "_CF__carbon_thunk.Main", scope: null, file: !9, line: 6, type: !15, spFlags: DISPFlagDefinition, unit: !10, retainedNodes: !30) +// CHECK:STDOUT: !27 = !DILocalVariable(arg: 1, scope: !26, type: !11) +// CHECK:STDOUT: !28 = !DILocalVariable(arg: 2, scope: !26, type: !11) +// CHECK:STDOUT: !29 = !DILocation(line: 6, column: 1, scope: !26) +// CHECK:STDOUT: !30 = !{!27, !28} +// CHECK:STDOUT: !31 = distinct !DISubprogram(name: "H", linkageName: "_CH.Main", scope: null, file: !9, line: 14, type: !17, spFlags: DISPFlagDefinition, unit: !10) +// CHECK:STDOUT: !34 = !DILocation(line: 14, column: 24, scope: !31) +// CHECK:STDOUT: !35 = !DILocation(line: 14, column: 17, scope: !31) +// CHECK:STDOUT: !36 = !{!2, !2, i64 0} +// CHECK:STDOUT: !37 = !{i32 8, !"PIC Level", i32 2} +// CHECK:STDOUT: !38 = !{i32 7, !"uwtable", i32 1} +// CHECK:STDOUT: !39 = !{i32 7, !"frame-pointer", i32 4} +// CHECK:STDOUT: !40 = !{!"__libc_errno", !2, i64 0} +// CHECK:STDOUT: !41 = !{!40, !2, i64 0} +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'constructor.carbon' +// CHECK:STDOUT: source_filename = "constructor.carbon" +// CHECK:STDOUT: target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" +// CHECK:STDOUT: target triple = "arm64-apple-macosx14.0.0" +// CHECK:STDOUT: +// CHECK:STDOUT: %"class.Carbon::Main::C" = type { i32 } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress ssp uwtable(sync) +// CHECK:STDOUT: define noundef i32 @_Z1Gv() #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %c = alloca %"class.Carbon::Main::C", align 4 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %c) #4 +// CHECK:STDOUT: %call = call noundef ptr @_ZN6Carbon4Main1CC1Ei(ptr noundef nonnull align 4 dereferenceable(4) %c, i32 noundef 42) +// CHECK:STDOUT: %i = getelementptr inbounds nuw %"class.Carbon::Main::C", ptr %c, i32 0, i32 0 +// CHECK:STDOUT: %0 = load i32, ptr %i, align 4, !tbaa !4 +// CHECK:STDOUT: %call1 = call noundef ptr @_ZN6Carbon4Main1CD1Ev(ptr noundef nonnull align 4 dead_on_return(4) dereferenceable(4) %c) #4 +// CHECK:STDOUT: call void @llvm.lifetime.end.p0(ptr %c) #4 +// CHECK:STDOUT: ret i32 %0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind ssp uwtable(sync) +// CHECK:STDOUT: define internal noundef ptr @_ZN6Carbon4Main1CC1Ei(ptr noundef nonnull returned align 4 dereferenceable(4) %this, i32 noundef %0) unnamed_addr #2 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !101 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !36 +// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: %call = call noundef ptr @"\01__CC__carbon_thunk.C.Main"(ptr noundef nonnull align 4 dereferenceable(4) %this1, ptr noundef nonnull align 4 dereferenceable(4) %.addr) +// CHECK:STDOUT: ret ptr %this1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind ssp uwtable(sync) +// CHECK:STDOUT: define linkonce_odr noundef ptr @_ZN6Carbon4Main1CD1Ev(ptr noundef nonnull returned align 4 dead_on_return(4) dereferenceable(4) %this) unnamed_addr #3 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !101 +// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: %call = call noundef ptr @_ZN6Carbon4Main1CD2Ev(ptr noundef nonnull align 4 dead_on_return(4) dereferenceable(4) %this1) #4 +// CHECK:STDOUT: ret ptr %this1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.end.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CC.C.Main(ptr sret({ i32 }) %return, i32 %i) #4 !dbg !51 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc8_19.2.i = getelementptr inbounds nuw { i32 }, ptr %return, i32 0, i32 0, !dbg !57 +// CHECK:STDOUT: store i32 %i, ptr %.loc8_19.2.i, align 4, !dbg !57 +// CHECK:STDOUT: ret void, !dbg !58 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind +// CHECK:STDOUT: define weak_odr void @"_C__destroy_thunk:thunk.C.Main"(ptr %self) #5 !dbg !60 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: call void @_CSelfDestruct.Core.356af3b6aef18564(ptr %self), !dbg !62 +// CHECK:STDOUT: ret void, !dbg !62 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.d424893893628d5b:core.SubobjectDestroy.Core"(ptr %self) #4 !dbg !64 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc6_9.1.i = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !66 +// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc6_9.1.i), !dbg !66 +// CHECK:STDOUT: ret void, !dbg !66 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.08d9e38b928ba575:core.SubobjectDestroy.Core"(ptr %self) #4 !dbg !70 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc6_9.1.i = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !72 +// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc6_9.1.i), !dbg !72 +// CHECK:STDOUT: ret void, !dbg !72 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define noundef ptr @"\01__CC__carbon_thunk.C.Main"(ptr noundef nonnull returned align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) unnamed_addr #6 !dbg !74 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc7_24.2 = load i32, ptr %_1, align 4, !dbg !77 +// CHECK:STDOUT: call void @_CC.C.Main(ptr %_, i32 %.loc7_24.2), !dbg !77 +// CHECK:STDOUT: ret ptr %_ +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define i32 @_CH.Main() #4 !dbg !79 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %G.call = call i32 @_Z1Gv(), !dbg !82 +// CHECK:STDOUT: ret i32 %G.call, !dbg !83 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.356af3b6aef18564(ptr %t) #4 !dbg !85 { +// CHECK:STDOUT: call void @"_COp.08d9e38b928ba575:core.SubobjectDestroy.Core"(ptr %t), !dbg !89 +// CHECK:STDOUT: ret void, !dbg !90 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f127f30143696d51(ptr %t) #4 !dbg !92 { +// CHECK:STDOUT: ret void, !dbg !97 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind ssp uwtable(sync) +// CHECK:STDOUT: define linkonce_odr noundef ptr @_ZN6Carbon4Main1CD2Ev(ptr noundef nonnull returned align 4 dead_on_return(4) dereferenceable(4) %this) unnamed_addr #3 personality ptr @__gxx_personality_v0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !101 +// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: invoke void @"\01__C__destroy_thunk:thunk.C.Main"(ptr noundef nonnull align 4 dereferenceable(4) %this1) +// CHECK:STDOUT: to label %invoke.cont unwind label %terminate.lpad +// CHECK:STDOUT: +// CHECK:STDOUT: invoke.cont: ; preds = %entry +// CHECK:STDOUT: ret ptr %this1 +// CHECK:STDOUT: +// CHECK:STDOUT: terminate.lpad: ; preds = %entry +// CHECK:STDOUT: %0 = landingpad { ptr, i32 } +// CHECK:STDOUT: catch ptr null +// CHECK:STDOUT: %1 = extractvalue { ptr, i32 } %0, 0 +// CHECK:STDOUT: call void @__clang_call_terminate(ptr %1) #9 +// CHECK:STDOUT: unreachable +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @"\01__C__destroy_thunk:thunk.C.Main"(ptr noundef nonnull align 4 dereferenceable(4)) #7 +// CHECK:STDOUT: +// CHECK:STDOUT: declare i32 @__gxx_personality_v0(...) +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: noinline noreturn nounwind ssp uwtable(sync) +// CHECK:STDOUT: define linkonce_odr hidden void @__clang_call_terminate(ptr noundef %0) #8 { +// CHECK:STDOUT: %2 = call ptr @__cxa_begin_catch(ptr %0) #4 +// CHECK:STDOUT: call void @_ZSt9terminatev() #9 +// CHECK:STDOUT: unreachable +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare ptr @__cxa_begin_catch(ptr) +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_ZSt9terminatev() +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @_CSelfDestruct.Core.f127f30143696d51, { 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { mustprogress ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress nounwind ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #3 = { inlinehint mustprogress nounwind ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #4 = { nounwind } +// CHECK:STDOUT: attributes #5 = { alwaysinline nounwind } +// CHECK:STDOUT: attributes #6 = { nounwind "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #7 = { "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #8 = { noinline noreturn nounwind ssp uwtable(sync) "frame-pointer"="non-leaf-no-reserve" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" "tune-cpu"="apple-m5" } +// CHECK:STDOUT: attributes #9 = { noreturn nounwind } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!43} +// CHECK:STDOUT: !llvm.module.flags = !{!37, !38, !39, !7, !8} +// CHECK:STDOUT: !llvm.errno.tbaa = !{!41} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{!"Simple C++ TBAA"} +// CHECK:STDOUT: !1 = !{!"omnipotent char", !0, i64 0} +// CHECK:STDOUT: !2 = !{!"int", !1, i64 0} +// CHECK:STDOUT: !3 = !{!"_ZTSN6Carbon4Main1CE", !2, i64 0} +// CHECK:STDOUT: !4 = !{!3, !2, i64 0} +// CHECK:STDOUT: !7 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !8 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK:STDOUT: !16 = !{!11} +// CHECK:STDOUT: !17 = !DISubroutineType(types: !16) +// CHECK:STDOUT: !36 = !{!2, !2, i64 0} +// CHECK:STDOUT: !37 = !{i32 8, !"PIC Level", i32 2} +// CHECK:STDOUT: !38 = !{i32 7, !"uwtable", i32 1} +// CHECK:STDOUT: !39 = !{i32 7, !"frame-pointer", i32 4} +// CHECK:STDOUT: !40 = !{!"__libc_errno", !2, i64 0} +// CHECK:STDOUT: !41 = !{!40, !2, i64 0} +// CHECK:STDOUT: !42 = !DIFile(filename: "constructor.carbon", directory: "") +// CHECK:STDOUT: !43 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !42, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !44 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !45 = !{!44, !11} +// CHECK:STDOUT: !46 = !DISubroutineType(types: !45) +// CHECK:STDOUT: !47 = !{null, !44} +// CHECK:STDOUT: !48 = !DISubroutineType(types: !47) +// CHECK:STDOUT: !49 = !{null, !44, !11} +// CHECK:STDOUT: !50 = !DISubroutineType(types: !49) +// CHECK:STDOUT: !51 = distinct !DISubprogram(name: "C", linkageName: "_CC.C.Main", scope: null, file: !42, line: 7, type: !46, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !59) +// CHECK:STDOUT: !52 = !DILocalVariable(arg: 1, scope: !51, type: !11) +// CHECK:STDOUT: !57 = !DILocation(line: 8, column: 12, scope: !51) +// CHECK:STDOUT: !58 = !DILocation(line: 8, column: 5, scope: !51) +// CHECK:STDOUT: !59 = !{!52} +// CHECK:STDOUT: !60 = distinct !DISubprogram(name: "__destroy_thunk", linkageName: "_C__destroy_thunk:thunk.C.Main", scope: null, file: !42, line: 6, type: !48, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !63) +// CHECK:STDOUT: !61 = !DILocalVariable(arg: 1, scope: !60, type: !44) +// CHECK:STDOUT: !62 = !DILocation(line: 6, column: 1, scope: !60) +// CHECK:STDOUT: !63 = !{!61} +// CHECK:STDOUT: !64 = distinct !DISubprogram(name: "Op", linkageName: "_COp.d424893893628d5b:core.SubobjectDestroy.Core", scope: null, file: !42, line: 6, type: !48, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !69) +// CHECK:STDOUT: !65 = !DILocalVariable(arg: 1, scope: !64, type: !44) +// CHECK:STDOUT: !66 = !DILocation(line: 6, column: 1, scope: !64) +// CHECK:STDOUT: !67 = !{null, !11} +// CHECK:STDOUT: !68 = !DISubroutineType(types: !67) +// CHECK:STDOUT: !69 = !{!65} +// CHECK:STDOUT: !70 = distinct !DISubprogram(name: "Op", linkageName: "_COp.08d9e38b928ba575:core.SubobjectDestroy.Core", scope: null, file: !42, line: 6, type: !48, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !73) +// CHECK:STDOUT: !71 = !DILocalVariable(arg: 1, scope: !70, type: !44) +// CHECK:STDOUT: !72 = !DILocation(line: 6, column: 1, scope: !70) +// CHECK:STDOUT: !73 = !{!71} +// CHECK:STDOUT: !74 = distinct !DISubprogram(name: "C__carbon_thunk", linkageName: "_CC__carbon_thunk.C.Main", scope: null, file: !42, line: 7, type: !50, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !78) +// CHECK:STDOUT: !75 = !DILocalVariable(arg: 1, scope: !74, type: !44) +// CHECK:STDOUT: !76 = !DILocalVariable(arg: 2, scope: !74, type: !11) +// CHECK:STDOUT: !77 = !DILocation(line: 7, column: 3, scope: !74) +// CHECK:STDOUT: !78 = !{!75, !76} +// CHECK:STDOUT: !79 = distinct !DISubprogram(name: "H", linkageName: "_CH.Main", scope: null, file: !42, line: 21, type: !17, spFlags: DISPFlagDefinition, unit: !43) +// CHECK:STDOUT: !82 = !DILocation(line: 21, column: 24, scope: !79) +// CHECK:STDOUT: !83 = !DILocation(line: 21, column: 17, scope: !79) +// CHECK:STDOUT: !84 = !DIFile(filename: "{{.*}}/prelude/destroy.carbon", directory: "") +// CHECK:STDOUT: !85 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.356af3b6aef18564", scope: null, file: !84, line: 36, type: !48, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !91) +// CHECK:STDOUT: !86 = !DILocalVariable(arg: 1, scope: !85, type: !44) +// CHECK:STDOUT: !89 = !DILocation(line: 38, column: 5, scope: !85) +// CHECK:STDOUT: !90 = !DILocation(line: 36, column: 1, scope: !85) +// CHECK:STDOUT: !91 = !{!86} +// CHECK:STDOUT: !92 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.f127f30143696d51", scope: null, file: !84, line: 36, type: !68, spFlags: DISPFlagDefinition, unit: !43, retainedNodes: !98) +// CHECK:STDOUT: !93 = !DILocalVariable(arg: 1, scope: !92, type: !11) +// CHECK:STDOUT: !97 = !DILocation(line: 36, column: 1, scope: !92) +// CHECK:STDOUT: !98 = !{!93} +// CHECK:STDOUT: !99 = !{!"any pointer", !1, i64 0} +// CHECK:STDOUT: !100 = !{!"p1 _ZTSN6Carbon4Main1CE", !99, i64 0} +// CHECK:STDOUT: !101 = !{!100, !100, i64 0} +// CHECK:STDOUT: diff --git a/toolchain/lower/testdata/interop/cpp/function/import/function_ptr.carbon b/toolchain/lower/testdata/interop/cpp/function/import/function_ptr.carbon index a7eb6844ccd6..938dfa2154b8 100644 --- a/toolchain/lower/testdata/interop/cpp/function/import/function_ptr.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/import/function_ptr.carbon @@ -196,7 +196,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr %_, ptr %_1) #0 !dbg !36 { +// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #1 !dbg !36 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc8 = load float, ptr %_, align 4, !dbg !39 // CHECK:STDOUT: %MyCallback.call = call i32 @_CMyCallback.Main(float %.loc8), !dbg !40 @@ -205,7 +205,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.9d0db8a57c58fabc(ptr %t) #0 !dbg !43 { @@ -213,7 +213,8 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!26} // CHECK:STDOUT: !llvm.module.flags = !{!17, !18, !19, !2, !3} @@ -270,7 +271,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr %_, ptr %_1) #0 !dbg !55 { +// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #1 !dbg !55 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc5 = load float, ptr %_, align 4, !dbg !58 // CHECK:STDOUT: %MyCallback.call = call i32 @_CMyCallback.Main(float %.loc5), !dbg !58 @@ -278,10 +279,11 @@ fn F() { // CHECK:STDOUT: ret void, !dbg !58 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_Z12TakeCallbackPFifE(ptr noundef) #1 +// CHECK:STDOUT: declare void @_Z12TakeCallbackPFifE(ptr noundef) #2 // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!51} // CHECK:STDOUT: !llvm.module.flags = !{!17, !18, !19, !2, !3} @@ -482,14 +484,14 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr %_, ptr %_1) #0 !dbg !108 { +// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #1 !dbg !108 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CMyCallback.Main(ptr %_1, ptr %_), !dbg !112 // CHECK:STDOUT: ret void, !dbg !112 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.9d0db8a57c58fabc(ptr %t) #0 !dbg !114 { @@ -497,7 +499,8 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!99} // CHECK:STDOUT: !llvm.module.flags = !{!17, !18, !19, !2, !3} @@ -552,16 +555,17 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr %_, ptr %_1) #0 !dbg !126 { +// CHECK:STDOUT: define void @_CMyCallback__carbon_thunk.Main(ptr noundef nonnull align 4 dereferenceable(4) %_, ptr noundef nonnull align 4 dereferenceable(4) %_1) #1 !dbg !126 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CMyCallback.Main(ptr %_1, ptr %_), !dbg !129 // CHECK:STDOUT: ret void, !dbg !129 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_Z19TakeComplexCallbackPF1CS_E(ptr noundef) #1 +// CHECK:STDOUT: declare void @_Z19TakeComplexCallbackPF1CS_E(ptr noundef) #2 // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } -// CHECK:STDOUT: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!122} // CHECK:STDOUT: !llvm.module.flags = !{!17, !18, !19, !2, !3} diff --git a/toolchain/lower/testdata/interop/cpp/function/import/method_ptr.carbon b/toolchain/lower/testdata/interop/cpp/function/import/method_ptr.carbon index 230c527509ae..5c00c840457f 100644 --- a/toolchain/lower/testdata/interop/cpp/function/import/method_ptr.carbon +++ b/toolchain/lower/testdata/interop/cpp/function/import/method_ptr.carbon @@ -194,14 +194,14 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMethod__carbon_thunk.C.Main(ptr %self) #0 !dbg !44 { +// CHECK:STDOUT: define void @_CMethod__carbon_thunk.C.Main(ptr noundef nonnull align 1 %self) #2 !dbg !44 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CMethod.C.Main(ptr %self), !dbg !47 // CHECK:STDOUT: ret void, !dbg !47 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.9d0db8a57c58fabc(ptr %t) #0 !dbg !49 { @@ -215,7 +215,8 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!35} // CHECK:STDOUT: !llvm.module.flags = !{!28, !29, !30, !2, !3} @@ -287,14 +288,14 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CMethod__carbon_thunk.C.Main(ptr %self) #0 !dbg !73 { +// CHECK:STDOUT: define void @_CMethod__carbon_thunk.C.Main(ptr noundef nonnull align 1 %self) #2 !dbg !73 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @_CMethod.C.Main(ptr %self), !dbg !75 // CHECK:STDOUT: ret void, !dbg !75 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable -// CHECK:STDOUT: define internal void @_Z20TakeGenericMethodPtrIN6Carbon4Main1CEEvMT_KFvvE.carbon_thunk._(ptr noundef %ptr) #2 { +// CHECK:STDOUT: define internal void @_Z20TakeGenericMethodPtrIN6Carbon4Main1CEEvMT_KFvvE.carbon_thunk._(ptr noundef %ptr) #3 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %ptr.addr = alloca ptr, align 8 // CHECK:STDOUT: %coerce = alloca { i64, i64 }, align 8 @@ -311,7 +312,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3 +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #4 // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.9d0db8a57c58fabc(ptr %t) #0 !dbg !77 { @@ -323,13 +324,14 @@ fn F() { // CHECK:STDOUT: ret void, !dbg !89 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: declare void @_Z20TakeGenericMethodPtrIN6Carbon4Main1CEEvMT_KFvvE(i64, i64) #4 +// CHECK:STDOUT: declare void @_Z20TakeGenericMethodPtrIN6Carbon4Main1CEEvMT_KFvvE(i64, i64) #5 // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } -// CHECK:STDOUT: attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #5 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!64} // CHECK:STDOUT: !llvm.module.flags = !{!28, !29, !30, !2, !3} diff --git a/toolchain/lower/testdata/interop/cpp/issue7142.carbon b/toolchain/lower/testdata/interop/cpp/issue7142.carbon index f429bf1fb3ba..45ef9a3adc7a 100644 --- a/toolchain/lower/testdata/interop/cpp/issue7142.carbon +++ b/toolchain/lower/testdata/interop/cpp/issue7142.carbon @@ -56,7 +56,7 @@ void f() { // CHECK:STDOUT: declare ptr @_CGet.Main() // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define void @_CGet__carbon_thunk.Main(ptr %_) #1 !dbg !12 { +// CHECK:STDOUT: define void @_CGet__carbon_thunk.Main(ptr noundef nonnull align 8 dereferenceable(8) %_) #1 !dbg !12 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %Get.call = call ptr @_CGet.Main(), !dbg !14 // CHECK:STDOUT: store ptr %Get.call, ptr %_, align 8, !dbg !14 @@ -71,7 +71,7 @@ void f() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define weak_odr void @"_COp.daf9f875be2f7080:core.SubobjectDestroy.Core"(ptr %self) #1 !dbg !20 { +// CHECK:STDOUT: define weak_odr void @"_COp.daf9f875be2f7080:core.SubobjectDestroy.Core"(ptr %self) #3 !dbg !20 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc15_9.1.price = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !22 // CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc15_9.1.price), !dbg !22 @@ -79,7 +79,7 @@ void f() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define weak_odr void @"_COp.5a23cc09585c55d2:core.SubobjectDestroy.Core"(ptr %self) #1 !dbg !26 { +// CHECK:STDOUT: define weak_odr void @"_COp.5a23cc09585c55d2:core.SubobjectDestroy.Core"(ptr %self) #3 !dbg !26 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc15_9.1.price = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !28 // CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc15_9.1.price), !dbg !28 @@ -87,18 +87,18 @@ void f() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.6b8b385dcf82cc70(ptr %t) #1 !dbg !31 { +// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.6b8b385dcf82cc70(ptr %t) #3 !dbg !31 { // CHECK:STDOUT: call void @"_COp.5a23cc09585c55d2:core.SubobjectDestroy.Core"(ptr %t), !dbg !35 // CHECK:STDOUT: ret void, !dbg !36 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f127f30143696d51(ptr %t) #1 !dbg !38 { +// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f127f30143696d51(ptr %t) #3 !dbg !38 { // CHECK:STDOUT: ret void, !dbg !43 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress nounwind uwtable -// CHECK:STDOUT: define internal noundef ptr @_ZN6Carbon4MainL3GetEv() #3 { +// CHECK:STDOUT: define internal noundef ptr @_ZN6Carbon4MainL3GetEv() #4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %retval = alloca ptr, align 8 // CHECK:STDOUT: call void @_CGet__carbon_thunk.Main(ptr noundef nonnull align 8 dereferenceable(8) %retval) @@ -110,9 +110,10 @@ void f() { // CHECK:STDOUT: uselistorder ptr @_CSelfDestruct.Core.f127f30143696d51, { 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -// CHECK:STDOUT: attributes #1 = { nounwind } +// CHECK:STDOUT: attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #2 = { alwaysinline nounwind } -// CHECK:STDOUT: attributes #3 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #3 = { nounwind } +// CHECK:STDOUT: attributes #4 = { alwaysinline mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.dbg.cu = !{!5} // CHECK:STDOUT: !llvm.module.flags = !{!52, !53, !54, !2, !3}