Browse Source

Use a single llvm::Module for C++ interop and Carbon IRGen (#6595)

Some module metadata changed - because rather than linking one module
with one module metadata value (eg: PIC Level 0, or unspecified) and one
module with a different one (PIC level 2, in clang) - we use Clang's
Module as-is, no merging required, so Clang's module metadata sticks
rather than being merged with default values from Carbon.

Also tweaked the name we use for Clang's module name so it matches the
carbon file name.

Otherwise the IR changes seem to be just reorderings - C++ interop goes
first, then Carbon, rather than the other way around.
David Blaikie 3 tháng trước cách đây
mục cha
commit
773b7136ef
26 tập tin đã thay đổi với 1904 bổ sung1874 xóa
  1. 2 2
      toolchain/check/cpp/generate_ast.cpp
  2. 13 13
      toolchain/driver/testdata/compile/optimize/clang_no_optimize_twice.carbon
  3. 17 8
      toolchain/lower/context.cpp
  4. 6 3
      toolchain/lower/context.h
  5. 31 40
      toolchain/lower/file_context.cpp
  6. 2 1
      toolchain/lower/file_context.h
  7. 6 3
      toolchain/lower/lower.cpp
  8. 3 3
      toolchain/lower/testdata/interop/cpp/base.carbon
  9. 14 14
      toolchain/lower/testdata/interop/cpp/clang_code_generator_callbacks.carbon
  10. 120 114
      toolchain/lower/testdata/interop/cpp/constructor.carbon
  11. 126 125
      toolchain/lower/testdata/interop/cpp/enum.carbon
  12. 42 39
      toolchain/lower/testdata/interop/cpp/extern_c.carbon
  13. 5 5
      toolchain/lower/testdata/interop/cpp/field.carbon
  14. 50 48
      toolchain/lower/testdata/interop/cpp/function_decl.carbon
  15. 1 1
      toolchain/lower/testdata/interop/cpp/function_in_template.carbon
  16. 68 63
      toolchain/lower/testdata/interop/cpp/globals.carbon
  17. 32 32
      toolchain/lower/testdata/interop/cpp/import_inline.carbon
  18. 93 92
      toolchain/lower/testdata/interop/cpp/method.carbon
  19. 127 127
      toolchain/lower/testdata/interop/cpp/nullptr.carbon
  20. 225 225
      toolchain/lower/testdata/interop/cpp/parameters.carbon
  21. 188 188
      toolchain/lower/testdata/interop/cpp/pointer.carbon
  22. 198 197
      toolchain/lower/testdata/interop/cpp/reference.carbon
  23. 350 347
      toolchain/lower/testdata/interop/cpp/return.carbon
  24. 120 119
      toolchain/lower/testdata/interop/cpp/template.carbon
  25. 54 56
      toolchain/lower/testdata/interop/cpp/virtual_base.carbon
  26. 11 9
      toolchain/lower/testdata/interop/cpp/void.carbon

+ 2 - 2
toolchain/check/cpp/generate_ast.cpp

@@ -339,7 +339,7 @@ class GenerateASTAction : public clang::ASTFrontendAction {
 
  protected:
   auto CreateASTConsumer(clang::CompilerInstance& clang_instance,
-                         llvm::StringRef file)
+                         llvm::StringRef /*file*/)
       -> std::unique_ptr<clang::ASTConsumer> override {
     auto& cpp_file = *context_->sem_ir().cpp_file();
     if (!cpp_file.llvm_context()) {
@@ -347,7 +347,7 @@ class GenerateASTAction : public clang::ASTFrontendAction {
     }
     auto code_generator =
         std::unique_ptr<clang::CodeGenerator>(clang::CreateLLVMCodeGen(
-            cpp_file.diagnostics(), file,
+            cpp_file.diagnostics(), context_->sem_ir().filename(),
             clang_instance.getVirtualFileSystemPtr(),
             clang_instance.getHeaderSearchOpts(),
             clang_instance.getPreprocessorOpts(),

+ 13 - 13
toolchain/driver/testdata/compile/optimize/clang_no_optimize_twice.carbon

@@ -33,29 +33,29 @@ fn Call() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_Z1fv = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
-// CHECK:STDOUT: define i32 @_CCall.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %g.call = call i32 @_Z1gv(), !dbg !16
-// CHECK:STDOUT:   ret i32 %g.call, !dbg !17
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef i32 @_Z1gv() #1 {
+// CHECK:STDOUT: define dso_local noundef i32 @_Z1gv() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %call = call noundef i32 @_Z1fv()
 // CHECK:STDOUT:   ret i32 %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_Z1fv() #2 comdat {
+// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_Z1fv() #1 comdat {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   ret i32 42
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { noinline nounwind optnone }
-// CHECK:STDOUT: attributes #1 = { 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 = { 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: ; Function Attrs: noinline nounwind optnone
+// CHECK:STDOUT: define i32 @_CCall.Main() #2 !dbg !12 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %g.call = call i32 @_Z1gv(), !dbg !16
+// CHECK:STDOUT:   ret i32 %g.call, !dbg !17
+// CHECK:STDOUT: }
+// 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 = { 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 #2 = { noinline nounwind optnone }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -64,7 +64,7 @@ fn Call() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 17 - 8
toolchain/lower/context.cpp

@@ -18,17 +18,24 @@ Context::Context(
     llvm::LLVMContext* llvm_context,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, bool want_debug_info,
     const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters,
-    llvm::StringRef module_name, int total_ir_count,
-    Lower::OptimizationLevel opt_level, llvm::raw_ostream* vlog_stream)
+    clang::CodeGenerator* clang_code_generator, llvm::StringRef module_name,
+    int total_ir_count, Lower::OptimizationLevel opt_level,
+    llvm::raw_ostream* vlog_stream)
     : llvm_context_(llvm_context),
-      llvm_module_(std::make_unique<llvm::Module>(module_name, *llvm_context)),
+      clang_code_generator_(clang_code_generator),
+      llvm_module_owner_(
+          clang_code_generator_
+              ? nullptr
+              : std::make_unique<llvm::Module>(module_name, *llvm_context)),
+      llvm_module_(llvm_module_owner_ ? llvm_module_owner_.get()
+                                      : clang_code_generator_->GetModule()),
       file_system_(std::move(fs)),
       opt_level_(opt_level),
       di_builder_(*llvm_module_),
-      di_compile_unit_(
-          want_debug_info
-              ? BuildDICompileUnit(module_name, *llvm_module_, di_builder_)
-              : nullptr),
+      di_compile_unit_(want_debug_info
+                           ? BuildDICompileUnit(llvm_module_->getName(),
+                                                *llvm_module_, di_builder_)
+                           : nullptr),
       tree_and_subtrees_getters_(tree_and_subtrees_getters),
       vlog_stream_(vlog_stream),
       total_ir_count_(total_ir_count),
@@ -65,7 +72,9 @@ auto Context::Finalize() && -> std::unique_ptr<llvm::Module> {
     }
   }
 
-  return std::move(llvm_module_);
+  return clang_code_generator_ ? std::unique_ptr<llvm::Module>(
+                                     clang_code_generator_->ReleaseModule())
+                               : std::move(llvm_module_owner_);
 }
 
 auto Context::BuildDICompileUnit(llvm::StringRef module_name,

+ 6 - 3
toolchain/lower/context.h

@@ -49,8 +49,9 @@ class Context {
       llvm::LLVMContext* llvm_context,
       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, bool want_debug_info,
       const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters,
-      llvm::StringRef module_name, int total_ir_count,
-      Lower::OptimizationLevel opt_level, llvm::raw_ostream* vlog_stream);
+      clang::CodeGenerator* code_generator, llvm::StringRef module_name,
+      int total_ir_count, Lower::OptimizationLevel opt_level,
+      llvm::raw_ostream* vlog_stream);
 
   // Gets or creates the `FileContext` for a given SemIR file. If an
   // `inst_namer` is specified the first time this is called for a file, it will
@@ -145,7 +146,9 @@ class Context {
 
   // State for building the LLVM IR.
   llvm::LLVMContext* llvm_context_;
-  std::unique_ptr<llvm::Module> llvm_module_;
+  clang::CodeGenerator* clang_code_generator_;
+  std::unique_ptr<llvm::Module> llvm_module_owner_;
+  llvm::Module* llvm_module_;
 
   // The filesystem for source code.
   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> file_system_;

+ 31 - 40
toolchain/lower/file_context.cpp

@@ -163,11 +163,6 @@ auto FileContext::Finalize() -> void {
     // const-correct.
     cpp_code_generator_->HandleTranslationUnit(
         const_cast<clang::ASTContext&>(cpp_file()->ast_context()));
-    bool link_error = llvm::Linker::linkModules(
-        /*Dest=*/llvm_module(),
-        /*Src=*/std::unique_ptr<llvm::Module>(
-            cpp_code_generator_->ReleaseModule()));
-    CARBON_CHECK(!link_error);
   }
 
   // Find equivalent specifics (from the same generic), replace all uses and
@@ -601,20 +596,17 @@ auto FileContext::FunctionTypeInfoBuilder::GetLoweredTypes(
 }
 
 auto FileContext::HandleReferencedCppFunction(clang::FunctionDecl* cpp_decl)
-    -> void {
-  clang::FunctionDecl* cpp_def = cpp_decl->getDefinition();
-  if (!cpp_def) {
-    return;
-  }
-
+    -> llvm::Function* {
   // Create the LLVM function (`CodeGenModule::GetOrCreateLLVMFunction()`)
   // so that code generation (`CodeGenModule::EmitGlobal()`) would see this
   // function name (`CodeGenModule::getMangledName()`), and will generate
   // its definition.
-  llvm::Constant* function_address =
-      cpp_code_generator_->GetAddrOfGlobal(CreateGlobalDecl(cpp_def),
-                                           /*isForDefinition=*/false);
+  auto* function_address = dyn_cast<llvm::Function>(
+      cpp_code_generator_->GetAddrOfGlobal(CreateGlobalDecl(cpp_decl),
+                                           /*isForDefinition=*/false));
   CARBON_CHECK(function_address);
+
+  return function_address;
 }
 
 auto FileContext::HandleReferencedSpecificFunction(
@@ -697,41 +689,40 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id,
              .llvm_function = existing}};
   }
 
+  llvm::Function* llvm_function;
   // If this is a C++ function, tell Clang that we referenced it.
   if (auto clang_decl_id = sem_ir().functions().Get(function_id).clang_decl_id;
       clang_decl_id.has_value()) {
     CARBON_CHECK(!specific_id.has_value(),
                  "Specific functions cannot have C++ definitions");
-    HandleReferencedCppFunction(
+    llvm_function = HandleReferencedCppFunction(
         sem_ir().clang_decls().Get(clang_decl_id).key.decl->getAsFunction());
-    // TODO: Check that the signature and mangling generated by Clang and the
-    // one we generated are the same.
-  }
-
-  // If this is a specific function, we may need to do additional work to emit
-  // its definition.
-  if (specific_id.has_value()) {
-    HandleReferencedSpecificFunction(function_id, specific_id,
-                                     function_type_info.type);
-  }
+  } else {
+    // If this is a specific function, we may need to do additional work to emit
+    // its definition.
+    if (specific_id.has_value()) {
+      HandleReferencedSpecificFunction(function_id, specific_id,
+                                       function_type_info.type);
+    }
 
-  auto* llvm_function = llvm::Function::Create(function_type_info.type, linkage,
-                                               mangled_name, llvm_module());
+    llvm_function = llvm::Function::Create(function_type_info.type, linkage,
+                                           mangled_name, llvm_module());
 
-  CARBON_CHECK(llvm_function->getName() == mangled_name,
-               "Mangled name collision: {0}", mangled_name);
+    CARBON_CHECK(llvm_function->getName() == mangled_name,
+                 "Mangled name collision: {0}", mangled_name);
 
-  // Set up parameters and the return slot.
-  for (auto [inst_id, arg] :
-       llvm::zip_equal(function_type_info.lowered_param_pattern_ids,
-                       llvm_function->args())) {
-    arg.setName(sem_ir().names().GetIRBaseName(
-        SemIR::GetPrettyNameFromPatternId(sem_ir(), inst_id)));
-  }
-  if (function_type_info.sret_type != nullptr) {
-    auto& return_arg = *llvm_function->args().begin();
-    return_arg.addAttr(llvm::Attribute::getWithStructRetType(
-        llvm_context(), function_type_info.sret_type));
+    // Set up parameters and the return slot.
+    for (auto [inst_id, arg] :
+         llvm::zip_equal(function_type_info.lowered_param_pattern_ids,
+                         llvm_function->args())) {
+      arg.setName(sem_ir().names().GetIRBaseName(
+          SemIR::GetPrettyNameFromPatternId(sem_ir(), inst_id)));
+    }
+    if (function_type_info.sret_type != nullptr) {
+      auto& return_arg = *llvm_function->args().begin();
+      return_arg.addAttr(llvm::Attribute::getWithStructRetType(
+          llvm_context(), function_type_info.sret_type));
+    }
   }
 
   return {{.type = function_type_info.type,

+ 2 - 1
toolchain/lower/file_context.h

@@ -180,7 +180,8 @@ class FileContext {
  private:
   // Notes that a C++ function has been referenced for the first time, so we
   // should ask Clang to generate a definition for it if possible.
-  auto HandleReferencedCppFunction(clang::FunctionDecl* cpp_decl) -> void;
+  auto HandleReferencedCppFunction(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

+ 6 - 3
toolchain/lower/lower.cpp

@@ -20,9 +20,12 @@ auto LowerToLLVM(
     const Parse::GetTreeAndSubtreesStore& tree_and_subtrees_getters,
     const SemIR::File& sem_ir, int total_ir_count,
     const LowerToLLVMOptions& options) -> std::unique_ptr<llvm::Module> {
-  Context context(&llvm_context, std::move(fs), options.want_debug_info,
-                  &tree_and_subtrees_getters, sem_ir.filename(), total_ir_count,
-                  options.opt_level, options.vlog_stream);
+  Context context(
+      &llvm_context, std::move(fs), options.want_debug_info,
+      &tree_and_subtrees_getters,
+      sem_ir.cpp_file() ? sem_ir.cpp_file()->GetCodeGenerator() : nullptr,
+      sem_ir.filename(), total_ir_count, options.opt_level,
+      options.vlog_stream);
 
   // TODO: Consider disabling instruction naming by default if we're not
   // producing textual LLVM IR.

+ 3 - 3
toolchain/lower/testdata/interop/cpp/base.carbon

@@ -89,7 +89,7 @@ fn Call(b: Cpp.B*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -136,7 +136,7 @@ fn Call(b: Cpp.B*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -188,7 +188,7 @@ fn Call(b: Cpp.B*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 14 - 14
toolchain/lower/testdata/interop/cpp/clang_code_generator_callbacks.carbon

@@ -81,7 +81,6 @@ void f2() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_ZN2t3IiE1iE = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: @llvm.compiler.used = appending global [1 x ptr] [ptr @_ZN2t24funcEv], section "llvm.metadata"
 // CHECK:STDOUT: @a = external global [10 x i8], align 1
 // CHECK:STDOUT: @b = dso_local global ptr @a, align 8
 // CHECK:STDOUT: @_ZN2t3IiE1iE = linkonce_odr dso_local global i32 0, comdat, align 4
@@ -89,6 +88,7 @@ void f2() {
 // CHECK:STDOUT: @_ZTI2t1 = dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS2t1 }, align 8
 // CHECK:STDOUT: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
 // CHECK:STDOUT: @_ZTS2t1 = dso_local constant [4 x i8] c"2t1\00", align 1
+// CHECK:STDOUT: @llvm.compiler.used = appending global [1 x ptr] [ptr @_ZN2t24funcEv], section "llvm.metadata"
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
 // CHECK:STDOUT: define dso_local void @_ZN2t12f1Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #0 align 2 {
@@ -100,19 +100,19 @@ void f2() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN2t24funcEv(ptr noundef nonnull align 1 dereferenceable(1) %this) #0 comdat align 2 {
+// CHECK:STDOUT: define dso_local noundef i32 @_Z1fv() #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %this.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !15
-// CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %0 = load i32, ptr getelementptr inbounds ([10 x %struct.S], ptr @a, i64 0, i64 3), align 4, !tbaa !15
+// CHECK:STDOUT:   ret i32 %0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define dso_local noundef i32 @_Z1fv() #0 {
+// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN2t24funcEv(ptr noundef nonnull align 1 dereferenceable(1) %this) #0 comdat align 2 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %0 = load i32, ptr getelementptr inbounds ([10 x %struct.S], ptr @a, i64 0, i64 3), align 4, !tbaa !17
-// CHECK:STDOUT:   ret i32 %0
+// CHECK:STDOUT:   %this.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !17
+// CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
@@ -131,7 +131,7 @@ void f2() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -143,7 +143,7 @@ void f2() {
 // CHECK:STDOUT: !12 = !{!13, !13, i64 0}
 // CHECK:STDOUT: !13 = !{!"p1 _ZTS2t1", !14, i64 0}
 // CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
-// CHECK:STDOUT: !16 = !{!"p1 _ZTS2t2", !14, i64 0}
-// CHECK:STDOUT: !17 = !{!18, !9, i64 0}
-// CHECK:STDOUT: !18 = !{!"_ZTS1S", !9, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !9, i64 0}
+// CHECK:STDOUT: !16 = !{!"_ZTS1S", !9, i64 0}
+// CHECK:STDOUT: !17 = !{!18, !18, i64 0}
+// CHECK:STDOUT: !18 = !{!"p1 _ZTS2t2", !14, i64 0}

+ 120 - 114
toolchain/lower/testdata/interop/cpp/constructor.carbon

@@ -89,45 +89,45 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_ZN1CC2Ev = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_26.1.temp = alloca [8 x i8], align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_26.1.temp), !dbg !15
-// CHECK:STDOUT:   call void @_ZN1CC1Ev.carbon_thunk(ptr %.loc7_26.1.temp), !dbg !15
-// CHECK:STDOUT:   ret void, !dbg !16
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_ZN1CC1Ev.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: define dso_local void @_ZN1CC1Ev.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !17
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !17
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_ZN1CC2Ev(ptr noundef nonnull align 4 dereferenceable(8) %0)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Ev(ptr noundef nonnull align 4 dereferenceable(8) %this) unnamed_addr #3 comdat align 2 {
+// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Ev(ptr noundef nonnull align 4 dereferenceable(8) %this) unnamed_addr #1 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 !17
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
 // CHECK:STDOUT:   %x_ = getelementptr inbounds nuw %class.C, ptr %this1, i32 0, i32 0
-// CHECK:STDOUT:   store i32 8, ptr %x_, align 4, !tbaa !20
+// CHECK:STDOUT:   store i32 8, ptr %x_, align 4, !tbaa !15
 // CHECK:STDOUT:   %y_ = getelementptr inbounds nuw %class.C, ptr %this1, i32 0, i32 1
-// CHECK:STDOUT:   store i32 9, ptr %y_, align 4, !tbaa !22
+// CHECK:STDOUT:   store i32 9, ptr %y_, align 4, !tbaa !17
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CF.Main() #2 !dbg !18 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc7_26.1.temp = alloca [8 x i8], align 1, !dbg !21
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_26.1.temp), !dbg !21
+// CHECK:STDOUT:   call void @_ZN1CC1Ev.carbon_thunk(ptr %.loc7_26.1.temp), !dbg !21
+// CHECK:STDOUT:   ret void, !dbg !22
+// 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:
+// CHECK:STDOUT: attributes #0 = { 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 #1 = { 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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -136,7 +136,7 @@ fn F() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -145,61 +145,61 @@ fn F() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 18, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !17 = !{!18, !18, i64 0}
-// CHECK:STDOUT: !18 = !{!"p1 _ZTS1C", !19, i64 0}
-// CHECK:STDOUT: !19 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !20 = !{!21, !9, i64 0}
-// CHECK:STDOUT: !21 = !{!"_ZTS1C", !9, i64 0, !9, i64 4}
-// CHECK:STDOUT: !22 = !{!21, !9, i64 4}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !9, i64 0}
+// CHECK:STDOUT: !16 = !{!"_ZTS1C", !9, i64 0, !9, i64 4}
+// CHECK:STDOUT: !17 = !{!16, !9, i64 4}
+// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !7, line: 6, type: !19, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !19 = !DISubroutineType(types: !20)
+// CHECK:STDOUT: !20 = !{null}
+// CHECK:STDOUT: !21 = !DILocation(line: 7, column: 18, scope: !18)
+// CHECK:STDOUT: !22 = !DILocation(line: 6, column: 1, scope: !18)
 // CHECK:STDOUT: ; ModuleID = 'call_copy.carbon'
 // CHECK:STDOUT: source_filename = "call_copy.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCopy.Main(ptr sret([4 x i8]) %return, ptr %c) #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_ZN4CopyC1ERKS_.carbon_thunk(ptr noundef %0, ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_10.1.temp = alloca [4 x i8], align 1, !dbg !18
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_10.1.temp), !dbg !18
-// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_.carbon_thunk(ptr %c, ptr %return), !dbg !18
-// CHECK:STDOUT:   ret void, !dbg !19
+// CHECK:STDOUT:   %.addr = alloca ptr, align 8
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4) %1, ptr noundef nonnull align 4 dereferenceable(4) %2)
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define void @"_COp:thunk.Copy.Cpp"(ptr sret([4 x i8]) %return, ptr %self) #1 !dbg !20 {
+// CHECK:STDOUT: declare void @_ZN4CopyC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4), ptr noundef nonnull align 4 dereferenceable(4)) unnamed_addr #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCopy.Main(ptr sret([4 x i8]) %return, ptr %c) #2 !dbg !15 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_.carbon_thunk(ptr %self, ptr %return), !dbg !23
-// CHECK:STDOUT:   ret void, !dbg !23
+// CHECK:STDOUT:   %.loc7_10.1.temp = alloca [4 x i8], align 1, !dbg !21
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_10.1.temp), !dbg !21
+// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_.carbon_thunk(ptr %c, ptr %return), !dbg !21
+// CHECK:STDOUT:   ret void, !dbg !22
 // 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:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_ZN4CopyC1ERKS_.carbon_thunk(ptr noundef %0, ptr noundef %return) #3 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
+// CHECK:STDOUT: define void @"_COp:thunk.Copy.Cpp"(ptr sret([4 x i8]) %return, ptr %self) #3 !dbg !23 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !24
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !24
-// CHECK:STDOUT:   %1 = load ptr, ptr %return.addr, align 8, !tbaa !24
-// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !24
-// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4) %1, ptr noundef nonnull align 4 dereferenceable(4) %2)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   call void @_ZN4CopyC1ERKS_.carbon_thunk(ptr %self, ptr %return), !dbg !26
+// CHECK:STDOUT:   ret void, !dbg !26
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN4CopyC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4), ptr noundef nonnull align 4 dereferenceable(4)) unnamed_addr #4
+// 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:
-// 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 #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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -208,7 +208,7 @@ fn F() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -217,21 +217,21 @@ fn F() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Copy", linkageName: "_CCopy.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 10, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Copy.Cpp", scope: null, file: !7, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21)
-// CHECK:STDOUT: !21 = !{!22}
-// CHECK:STDOUT: !22 = !DILocalVariable(arg: 1, scope: !20, type: !15)
-// CHECK:STDOUT: !23 = !DILocation(line: 0, scope: !20)
-// CHECK:STDOUT: !24 = !{!25, !25, i64 0}
-// CHECK:STDOUT: !25 = !{!"p1 _ZTS4Copy", !26, i64 0}
-// CHECK:STDOUT: !26 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS4Copy", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "Copy", linkageName: "_CCopy.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !19)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{!18, !18}
+// CHECK:STDOUT: !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !19 = !{!20}
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !15, type: !18)
+// CHECK:STDOUT: !21 = !DILocation(line: 7, column: 10, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 7, column: 3, scope: !15)
+// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Copy.Cpp", scope: null, file: !7, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !24)
+// CHECK:STDOUT: !24 = !{!25}
+// CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !23, type: !18)
+// CHECK:STDOUT: !26 = !DILocation(line: 0, scope: !23)
 // CHECK:STDOUT: ; ModuleID = 'call_c1_in_thunk.carbon'
 // CHECK:STDOUT: source_filename = "call_c1_in_thunk.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -241,6 +241,8 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_ZTV7Derived = comdat any
 // CHECK:STDOUT:
+// CHECK:STDOUT: $_ZTT7Derived = comdat any
+// CHECK:STDOUT:
 // CHECK:STDOUT: $_ZTI7Derived = comdat any
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_ZTS7Derived = comdat any
@@ -250,6 +252,7 @@ fn F() {
 // CHECK:STDOUT: $_ZTS4Base = comdat any
 // CHECK:STDOUT:
 // CHECK:STDOUT: @_ZTV7Derived = linkonce_odr dso_local unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZTI7Derived] }, comdat, align 8
+// CHECK:STDOUT: @_ZTT7Derived = linkonce_odr dso_local unnamed_addr constant [1 x ptr] [ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 3)], comdat, align 8
 // CHECK:STDOUT: @_ZTI7Derived = linkonce_odr dso_local constant { ptr, ptr, i32, i32, ptr, i64 } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), ptr @_ZTS7Derived, i32 0, i32 1, ptr @_ZTI4Base, i64 -6141 }, comdat, align 8
 // CHECK:STDOUT: @_ZTVN10__cxxabiv121__vmi_class_type_infoE = external global [0 x ptr]
 // CHECK:STDOUT: @_ZTS7Derived = linkonce_odr dso_local constant [9 x i8] c"7Derived\00", comdat, align 1
@@ -257,42 +260,45 @@ fn F() {
 // CHECK:STDOUT: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
 // CHECK:STDOUT: @_ZTS4Base = linkonce_odr dso_local constant [6 x i8] c"4Base\00", comdat, align 1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_44.1.temp = alloca [8 x i8], align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_44.1.temp), !dbg !15
-// CHECK:STDOUT:   call void @_ZN7DerivedC1Ev.carbon_thunk(ptr %.loc7_44.1.temp), !dbg !15
-// CHECK:STDOUT:   ret void, !dbg !16
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_ZN7DerivedC1Ev.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: define dso_local void @_ZN7DerivedC1Ev.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !17
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !17
-// CHECK:STDOUT:   call void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(8) %0) #0
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(8) %0) #2
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #3 comdat align 2 {
+// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr #1 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 !17
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
-// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 3), ptr %this1, align 8, !tbaa !20
+// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 3), ptr %this1, align 8, !tbaa !15
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// 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 = { 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CF.Main() #2 !dbg !17 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc7_44.1.temp = alloca [8 x i8], align 1, !dbg !20
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_44.1.temp), !dbg !20
+// CHECK:STDOUT:   call void @_ZN7DerivedC1Ev.carbon_thunk(ptr %.loc7_44.1.temp), !dbg !20
+// CHECK:STDOUT:   ret void, !dbg !21
+// 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:
+// CHECK:STDOUT: ; uselistorder directives
+// CHECK:STDOUT: uselistorder ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @_ZTV7Derived, i32 0, i32 0, i32 3), { 1, 0 }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { 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 = { 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 #2 = { nounwind }
+// CHECK:STDOUT: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -301,7 +307,7 @@ fn F() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -310,13 +316,13 @@ fn F() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 24, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !17 = !{!18, !18, i64 0}
-// CHECK:STDOUT: !18 = !{!"p1 _ZTS7Derived", !19, i64 0}
-// CHECK:STDOUT: !19 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !20 = !{!21, !21, i64 0}
-// CHECK:STDOUT: !21 = !{!"vtable pointer", !11, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS7Derived", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"vtable pointer", !11, i64 0}
+// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !7, line: 6, type: !18, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
+// CHECK:STDOUT: !19 = !{null}
+// CHECK:STDOUT: !20 = !DILocation(line: 7, column: 24, scope: !17)
+// CHECK:STDOUT: !21 = !DILocation(line: 6, column: 1, scope: !17)

+ 126 - 125
toolchain/lower/testdata/interop/cpp/enum.carbon

@@ -87,63 +87,63 @@ fn Call() {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPass.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_16.1.temp = alloca i16, align 2, !dbg !15
-// CHECK:STDOUT:   %.loc8_16.1.temp = alloca i16, align 2, !dbg !16
-// CHECK:STDOUT:   %.loc9_16.1.temp = alloca i16, align 2, !dbg !17
-// CHECK:STDOUT:   %.loc10_16.1.temp = alloca i16, align 2, !dbg !18
-// CHECK:STDOUT:   %.loc11_18.1.temp = alloca i16, align 2, !dbg !19
-// CHECK:STDOUT:   %.loc12_18.1.temp = alloca i16, align 2, !dbg !20
-// CHECK:STDOUT:   %.loc13_18.1.temp = alloca i16, align 2, !dbg !21
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_16.1.temp), !dbg !15
-// CHECK:STDOUT:   store i16 0, ptr %.loc7_16.1.temp, align 2, !dbg !15
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc7_16.1.temp), !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_16.1.temp), !dbg !16
-// CHECK:STDOUT:   store i16 0, ptr %.loc8_16.1.temp, align 2, !dbg !16
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc8_16.1.temp), !dbg !23
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_16.1.temp), !dbg !17
-// CHECK:STDOUT:   store i16 7, ptr %.loc9_16.1.temp, align 2, !dbg !17
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc9_16.1.temp), !dbg !24
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc10_16.1.temp), !dbg !18
-// CHECK:STDOUT:   store i16 8, ptr %.loc10_16.1.temp, align 2, !dbg !18
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc10_16.1.temp), !dbg !25
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc11_18.1.temp), !dbg !19
-// CHECK:STDOUT:   store i16 0, ptr %.loc11_18.1.temp, align 2, !dbg !19
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc11_18.1.temp), !dbg !26
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.1.temp), !dbg !20
-// CHECK:STDOUT:   store i16 7, ptr %.loc12_18.1.temp, align 2, !dbg !20
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc12_18.1.temp), !dbg !27
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc13_18.1.temp), !dbg !21
-// CHECK:STDOUT:   store i16 8, ptr %.loc13_18.1.temp, align 2, !dbg !21
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc13_18.1.temp), !dbg !28
-// CHECK:STDOUT:   ret void, !dbg !29
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_ZN1C1FENS_1EE.carbon_thunk(ptr noundef %0) #2 {
+// CHECK:STDOUT: define dso_local void @_ZN1C1FENS_1EE.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !30
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !30
-// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !32
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !14
 // CHECK:STDOUT:   call void @_ZN1C1FENS_1EE(i16 noundef signext %2)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1C1FENS_1EE(i16 noundef signext) #3
+// CHECK:STDOUT: declare void @_ZN1C1FENS_1EE(i16 noundef signext) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPass.Main() #2 !dbg !16 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc7_16.1.temp = alloca i16, align 2, !dbg !19
+// CHECK:STDOUT:   %.loc8_16.1.temp = alloca i16, align 2, !dbg !20
+// CHECK:STDOUT:   %.loc9_16.1.temp = alloca i16, align 2, !dbg !21
+// CHECK:STDOUT:   %.loc10_16.1.temp = alloca i16, align 2, !dbg !22
+// CHECK:STDOUT:   %.loc11_18.1.temp = alloca i16, align 2, !dbg !23
+// CHECK:STDOUT:   %.loc12_18.1.temp = alloca i16, align 2, !dbg !24
+// CHECK:STDOUT:   %.loc13_18.1.temp = alloca i16, align 2, !dbg !25
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_16.1.temp), !dbg !19
+// CHECK:STDOUT:   store i16 0, ptr %.loc7_16.1.temp, align 2, !dbg !19
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc7_16.1.temp), !dbg !26
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_16.1.temp), !dbg !20
+// CHECK:STDOUT:   store i16 0, ptr %.loc8_16.1.temp, align 2, !dbg !20
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc8_16.1.temp), !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_16.1.temp), !dbg !21
+// CHECK:STDOUT:   store i16 7, ptr %.loc9_16.1.temp, align 2, !dbg !21
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc9_16.1.temp), !dbg !28
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc10_16.1.temp), !dbg !22
+// CHECK:STDOUT:   store i16 8, ptr %.loc10_16.1.temp, align 2, !dbg !22
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc10_16.1.temp), !dbg !29
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc11_18.1.temp), !dbg !23
+// CHECK:STDOUT:   store i16 0, ptr %.loc11_18.1.temp, align 2, !dbg !23
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc11_18.1.temp), !dbg !30
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.1.temp), !dbg !24
+// CHECK:STDOUT:   store i16 7, ptr %.loc12_18.1.temp, align 2, !dbg !24
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc12_18.1.temp), !dbg !31
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc13_18.1.temp), !dbg !25
+// CHECK:STDOUT:   store i16 8, ptr %.loc13_18.1.temp, align 2, !dbg !25
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc13_18.1.temp), !dbg !32
+// CHECK:STDOUT:   ret void, !dbg !33
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 6, 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -152,7 +152,7 @@ fn Call() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -161,79 +161,79 @@ fn Call() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Pass", linkageName: "_CPass.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 11, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 8, column: 11, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 9, column: 11, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 10, column: 11, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 11, column: 11, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 12, column: 11, scope: !12)
-// CHECK:STDOUT: !21 = !DILocation(line: 13, column: 11, scope: !12)
-// CHECK:STDOUT: !22 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !23 = !DILocation(line: 8, column: 3, scope: !12)
-// CHECK:STDOUT: !24 = !DILocation(line: 9, column: 3, scope: !12)
-// CHECK:STDOUT: !25 = !DILocation(line: 10, column: 3, scope: !12)
-// CHECK:STDOUT: !26 = !DILocation(line: 11, column: 3, scope: !12)
-// CHECK:STDOUT: !27 = !DILocation(line: 12, column: 3, scope: !12)
-// CHECK:STDOUT: !28 = !DILocation(line: 13, column: 3, scope: !12)
-// CHECK:STDOUT: !29 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !30 = !{!31, !31, i64 0}
-// CHECK:STDOUT: !31 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !32 = !{!33, !33, i64 0}
-// CHECK:STDOUT: !33 = !{!"_ZTSN1C1EE", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !14 = !{!15, !15, i64 0}
+// CHECK:STDOUT: !15 = !{!"_ZTSN1C1EE", !10, i64 0}
+// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "Pass", linkageName: "_CPass.Main", scope: null, file: !7, line: 6, type: !17, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !17 = !DISubroutineType(types: !18)
+// CHECK:STDOUT: !18 = !{null}
+// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 11, scope: !16)
+// CHECK:STDOUT: !20 = !DILocation(line: 8, column: 11, scope: !16)
+// CHECK:STDOUT: !21 = !DILocation(line: 9, column: 11, scope: !16)
+// CHECK:STDOUT: !22 = !DILocation(line: 10, column: 11, scope: !16)
+// CHECK:STDOUT: !23 = !DILocation(line: 11, column: 11, scope: !16)
+// CHECK:STDOUT: !24 = !DILocation(line: 12, column: 11, scope: !16)
+// CHECK:STDOUT: !25 = !DILocation(line: 13, column: 11, scope: !16)
+// CHECK:STDOUT: !26 = !DILocation(line: 7, column: 3, scope: !16)
+// CHECK:STDOUT: !27 = !DILocation(line: 8, column: 3, scope: !16)
+// CHECK:STDOUT: !28 = !DILocation(line: 9, column: 3, scope: !16)
+// CHECK:STDOUT: !29 = !DILocation(line: 10, column: 3, scope: !16)
+// CHECK:STDOUT: !30 = !DILocation(line: 11, column: 3, scope: !16)
+// CHECK:STDOUT: !31 = !DILocation(line: 12, column: 3, scope: !16)
+// CHECK:STDOUT: !32 = !DILocation(line: 13, column: 3, scope: !16)
+// CHECK:STDOUT: !33 = !DILocation(line: 6, column: 1, scope: !16)
 // CHECK:STDOUT: ; ModuleID = 'convert.carbon'
 // CHECK:STDOUT: source_filename = "convert.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_ZN1C1FENS_1EE.carbon_thunk(ptr noundef %0) #0 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !14
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE(i16 noundef signext %2)
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_ZN1C1FENS_1EE(i16 noundef signext) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: declare void @_CTakeI16.Main(i16)
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassEnum.Main() #0 !dbg !12 {
+// CHECK:STDOUT: define void @_CPassEnum.Main() #2 !dbg !16 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_CTakeI16.Main(i16 7), !dbg !15
-// CHECK:STDOUT:   ret void, !dbg !16
+// CHECK:STDOUT:   call void @_CTakeI16.Main(i16 7), !dbg !19
+// CHECK:STDOUT:   ret void, !dbg !20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CConvertEnumToI16.Main(i16 %e) #0 !dbg !17 {
+// CHECK:STDOUT: define void @_CConvertEnumToI16.Main(i16 %e) #2 !dbg !21 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_CTakeI16.Main(i16 %e), !dbg !23
-// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT:   call void @_CTakeI16.Main(i16 %e), !dbg !27
+// CHECK:STDOUT:   ret void, !dbg !28
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CConvertI16ToEnum.Main(i16 %n) #0 !dbg !25 {
+// CHECK:STDOUT: define void @_CConvertI16ToEnum.Main(i16 %n) #2 !dbg !29 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc17_13.3.temp = alloca i16, align 2, !dbg !28
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_13.3.temp), !dbg !28
-// CHECK:STDOUT:   store i16 %n, ptr %.loc17_13.3.temp, align 2, !dbg !28
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc17_13.3.temp), !dbg !29
-// CHECK:STDOUT:   ret void, !dbg !30
+// CHECK:STDOUT:   %.loc17_13.3.temp = alloca i16, align 2, !dbg !32
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_13.3.temp), !dbg !32
+// CHECK:STDOUT:   store i16 %n, ptr %.loc17_13.3.temp, align 2, !dbg !32
+// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE.carbon_thunk(ptr %.loc17_13.3.temp), !dbg !33
+// CHECK:STDOUT:   ret void, !dbg !34
 // 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)) #3
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_ZN1C1FENS_1EE.carbon_thunk(ptr noundef %0) #2 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !31
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !31
-// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !33
-// CHECK:STDOUT:   call void @_ZN1C1FENS_1EE(i16 noundef signext %2)
-// CHECK:STDOUT:   ret void
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1C1FENS_1EE(i16 noundef signext) #3
-// CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -242,7 +242,7 @@ fn Call() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -251,29 +251,29 @@ fn Call() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassEnum", linkageName: "_CPassEnum.Main", scope: null, file: !7, line: 8, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 9, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 8, column: 1, scope: !12)
-// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "ConvertEnumToI16", linkageName: "_CConvertEnumToI16.Main", scope: null, file: !7, line: 12, type: !18, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21)
-// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
-// CHECK:STDOUT: !19 = !{null, !20}
-// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !21 = !{!22}
-// CHECK:STDOUT: !22 = !DILocalVariable(arg: 1, scope: !17, type: !20)
-// CHECK:STDOUT: !23 = !DILocation(line: 13, column: 3, scope: !17)
-// CHECK:STDOUT: !24 = !DILocation(line: 12, column: 1, scope: !17)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "ConvertI16ToEnum", linkageName: "_CConvertI16ToEnum.Main", scope: null, file: !7, line: 16, type: !18, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !26)
-// CHECK:STDOUT: !26 = !{!27}
-// CHECK:STDOUT: !27 = !DILocalVariable(arg: 1, scope: !25, type: !20)
-// CHECK:STDOUT: !28 = !DILocation(line: 17, column: 11, scope: !25)
-// CHECK:STDOUT: !29 = !DILocation(line: 17, column: 3, scope: !25)
-// CHECK:STDOUT: !30 = !DILocation(line: 16, column: 1, scope: !25)
-// CHECK:STDOUT: !31 = !{!32, !32, i64 0}
-// CHECK:STDOUT: !32 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !33 = !{!34, !34, i64 0}
-// CHECK:STDOUT: !34 = !{!"_ZTSN1C1EE", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !14 = !{!15, !15, i64 0}
+// CHECK:STDOUT: !15 = !{!"_ZTSN1C1EE", !10, i64 0}
+// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "PassEnum", linkageName: "_CPassEnum.Main", scope: null, file: !7, line: 8, type: !17, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !17 = !DISubroutineType(types: !18)
+// CHECK:STDOUT: !18 = !{null}
+// CHECK:STDOUT: !19 = !DILocation(line: 9, column: 3, scope: !16)
+// CHECK:STDOUT: !20 = !DILocation(line: 8, column: 1, scope: !16)
+// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "ConvertEnumToI16", linkageName: "_CConvertEnumToI16.Main", scope: null, file: !7, line: 12, type: !22, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !25)
+// CHECK:STDOUT: !22 = !DISubroutineType(types: !23)
+// CHECK:STDOUT: !23 = !{null, !24}
+// CHECK:STDOUT: !24 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !25 = !{!26}
+// CHECK:STDOUT: !26 = !DILocalVariable(arg: 1, scope: !21, type: !24)
+// CHECK:STDOUT: !27 = !DILocation(line: 13, column: 3, scope: !21)
+// CHECK:STDOUT: !28 = !DILocation(line: 12, column: 1, scope: !21)
+// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "ConvertI16ToEnum", linkageName: "_CConvertI16ToEnum.Main", scope: null, file: !7, line: 16, type: !22, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !30)
+// CHECK:STDOUT: !30 = !{!31}
+// CHECK:STDOUT: !31 = !DILocalVariable(arg: 1, scope: !29, type: !24)
+// CHECK:STDOUT: !32 = !DILocation(line: 17, column: 11, scope: !29)
+// CHECK:STDOUT: !33 = !DILocation(line: 17, column: 3, scope: !29)
+// CHECK:STDOUT: !34 = !DILocation(line: 16, column: 1, scope: !29)
 // CHECK:STDOUT: ; ModuleID = 'use_bitmask.carbon'
 // CHECK:STDOUT: source_filename = "use_bitmask.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -286,9 +286,10 @@ fn Call() {
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z4Take4Bits(i32)
+// CHECK:STDOUT: declare void @_Z4Take4Bits(i32 noundef) #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -297,7 +298,7 @@ fn Call() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 42 - 39
toolchain/lower/testdata/interop/cpp/extern_c.carbon

@@ -114,9 +114,10 @@ fn MyF() {
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @foo()
+// CHECK:STDOUT: declare void @foo() #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -125,7 +126,7 @@ fn MyF() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -152,11 +153,12 @@ fn MyF() {
 // CHECK:STDOUT:   ret void, !dbg !17
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @foo()
+// CHECK:STDOUT: declare void @foo() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooi(i32)
+// CHECK:STDOUT: declare void @_Z3fooi(i32 noundef) #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -165,7 +167,7 @@ fn MyF() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -203,7 +205,7 @@ fn MyF() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -225,15 +227,8 @@ fn MyF() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %struct.X = type { i8 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CMyF.Main(ptr sret({}) %return, ptr %a, ptr %b) #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Zpl1XS_.carbon_thunk(ptr %a, ptr %b, ptr %return), !dbg !19
-// CHECK:STDOUT:   ret void, !dbg !20
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Zpl1XS_.carbon_thunk(ptr noundef %0, ptr noundef %1, ptr noundef %return) #1 {
+// CHECK:STDOUT: define dso_local void @_Zpl1XS_.carbon_thunk(ptr noundef %0, ptr noundef %1, ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr1 = alloca ptr, align 8
@@ -241,21 +236,28 @@ fn MyF() {
 // CHECK:STDOUT:   %agg.tmp = alloca %struct.X, align 1
 // CHECK:STDOUT:   %agg.tmp2 = alloca %struct.X, align 1
 // CHECK:STDOUT:   %undef.agg.tmp = alloca %struct.X, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !21
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   %2 = load ptr, ptr %return.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   %3 = load ptr, ptr %.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   %4 = load ptr, ptr %.addr1, align 8, !tbaa !21
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %2 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %3 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %4 = load ptr, ptr %.addr1, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Zpl1XS_()
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Zpl1XS_() #2
+// CHECK:STDOUT: declare void @_Zpl1XS_() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CMyF.Main(ptr sret({}) %return, ptr %a, ptr %b) #2 !dbg !15 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @_Zpl1XS_.carbon_thunk(ptr %a, ptr %b, ptr %return), !dbg !22
+// CHECK:STDOUT:   ret void, !dbg !23
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { 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 #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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -264,7 +266,7 @@ fn MyF() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -273,18 +275,18 @@ fn MyF() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "MyF", linkageName: "_CMyF.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15, !15, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17, !18}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocalVariable(arg: 2, scope: !12, type: !15)
-// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 10, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !{!22, !22, i64 0}
-// CHECK:STDOUT: !22 = !{!"p1 _ZTS1X", !23, i64 0}
-// CHECK:STDOUT: !23 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1X", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "MyF", linkageName: "_CMyF.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !19)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{!18, !18, !18}
+// CHECK:STDOUT: !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !19 = !{!20, !21}
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !15, type: !18)
+// CHECK:STDOUT: !21 = !DILocalVariable(arg: 2, scope: !15, type: !18)
+// CHECK:STDOUT: !22 = !DILocation(line: 7, column: 10, scope: !15)
+// CHECK:STDOUT: !23 = !DILocation(line: 7, column: 3, scope: !15)
 // CHECK:STDOUT: ; ModuleID = 'import_extern_c_with_asm_label.carbon'
 // CHECK:STDOUT: source_filename = "import_extern_c_with_asm_label.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -297,9 +299,10 @@ fn MyF() {
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @bar()
+// CHECK:STDOUT: declare void @bar() #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -308,7 +311,7 @@ fn MyF() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 5 - 5
toolchain/lower/testdata/interop/cpp/field.carbon

@@ -138,7 +138,7 @@ fn AccessP(a: Cpp.A) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -191,7 +191,7 @@ fn AccessP(a: Cpp.A) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -243,7 +243,7 @@ fn AccessP(a: Cpp.A) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -296,7 +296,7 @@ fn AccessP(a: Cpp.A) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -349,7 +349,7 @@ fn AccessP(a: Cpp.A) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 50 - 48
toolchain/lower/testdata/interop/cpp/function_decl.carbon

@@ -144,9 +144,10 @@ fn MyF() -> i32 {
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3foov()
+// CHECK:STDOUT: declare void @_Z3foov() #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -155,7 +156,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -199,7 +200,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -222,24 +223,24 @@ fn MyF() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @llvm.compiler.used = appending global [1 x ptr] [ptr @_Z3foov], section "llvm.metadata"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CMyF.Main() #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable
+// CHECK:STDOUT: define linkonce_odr dso_local void @_Z3foov() #0 comdat {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z3foov(), !dbg !15
-// CHECK:STDOUT:   ret void, !dbg !16
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_Z3foov() #1 comdat {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CMyF.Main() #1 !dbg !12 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   call void @_Z3foov(), !dbg !15
+// CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @_Z3foov, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #0 = { 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 #1 = { nounwind }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -248,7 +249,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -310,7 +311,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -366,7 +367,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -385,40 +386,17 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CMyF.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %value.var = alloca i32, align 4, !dbg !16
-// CHECK:STDOUT:   call void @_Z13NoReturnValueii.carbon_thunk0(), !dbg !17
-// CHECK:STDOUT:   call void @_Z13NoReturnValueii.carbon_thunk1(i32 3), !dbg !18
-// CHECK:STDOUT:   call void @_Z13NoReturnValueii(i32 3, i32 4), !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %value.var), !dbg !16
-// CHECK:STDOUT:   %SimpleReturnValue__carbon_thunk.call.loc11 = call i32 @_Z17SimpleReturnValueii.carbon_thunk0(), !dbg !20
-// CHECK:STDOUT:   store i32 %SimpleReturnValue__carbon_thunk.call.loc11, ptr %value.var, align 4, !dbg !16
-// CHECK:STDOUT:   %SimpleReturnValue__carbon_thunk.call.loc12 = call i32 @_Z17SimpleReturnValueii.carbon_thunk1(i32 3), !dbg !21
-// CHECK:STDOUT:   store i32 %SimpleReturnValue__carbon_thunk.call.loc12, ptr %value.var, align 4, !dbg !22
-// CHECK:STDOUT:   %SimpleReturnValue.call = call i32 @_Z17SimpleReturnValueii(i32 3, i32 4), !dbg !23
-// CHECK:STDOUT:   store i32 %SimpleReturnValue.call, ptr %value.var, align 4, !dbg !24
-// CHECK:STDOUT:   %.loc14 = load i32, ptr %value.var, align 4, !dbg !25
-// CHECK:STDOUT:   ret i32 %.loc14, !dbg !26
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z13NoReturnValueii(i32, i32)
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare i32 @_Z17SimpleReturnValueii(i32, i32)
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_Z13NoReturnValueii.carbon_thunk0() #2 {
+// CHECK:STDOUT: define dso_local void @_Z13NoReturnValueii.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   call void @_Z13NoReturnValueii(i32 noundef 1, i32 noundef 2)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z13NoReturnValueii(i32 noundef, i32 noundef) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z13NoReturnValueii.carbon_thunk1(i32 noundef %a) #2 {
+// CHECK:STDOUT: define dso_local void @_Z13NoReturnValueii.carbon_thunk1(i32 noundef %a) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %a.addr = alloca i32, align 4
 // CHECK:STDOUT:   store i32 %a, ptr %a.addr, align 4, !tbaa !8
@@ -428,14 +406,16 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef i32 @_Z17SimpleReturnValueii.carbon_thunk0() #2 {
+// CHECK:STDOUT: define dso_local noundef i32 @_Z17SimpleReturnValueii.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %call = call noundef i32 @_Z17SimpleReturnValueii(i32 noundef 1, i32 noundef 2)
 // CHECK:STDOUT:   ret i32 %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare noundef i32 @_Z17SimpleReturnValueii(i32 noundef, i32 noundef) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef i32 @_Z17SimpleReturnValueii.carbon_thunk1(i32 noundef %a) #2 {
+// CHECK:STDOUT: define dso_local noundef i32 @_Z17SimpleReturnValueii.carbon_thunk1(i32 noundef %a) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %a.addr = alloca i32, align 4
 // CHECK:STDOUT:   store i32 %a, ptr %a.addr, align 4, !tbaa !8
@@ -444,9 +424,31 @@ fn MyF() -> i32 {
 // CHECK:STDOUT:   ret i32 %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CMyF.Main() #2 !dbg !12 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %value.var = alloca i32, align 4, !dbg !16
+// CHECK:STDOUT:   call void @_Z13NoReturnValueii.carbon_thunk0(), !dbg !17
+// CHECK:STDOUT:   call void @_Z13NoReturnValueii.carbon_thunk1(i32 3), !dbg !18
+// CHECK:STDOUT:   call void @_Z13NoReturnValueii(i32 3, i32 4), !dbg !19
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %value.var), !dbg !16
+// CHECK:STDOUT:   %SimpleReturnValue__carbon_thunk.call.loc11 = call i32 @_Z17SimpleReturnValueii.carbon_thunk0(), !dbg !20
+// CHECK:STDOUT:   store i32 %SimpleReturnValue__carbon_thunk.call.loc11, ptr %value.var, align 4, !dbg !16
+// CHECK:STDOUT:   %SimpleReturnValue__carbon_thunk.call.loc12 = call i32 @_Z17SimpleReturnValueii.carbon_thunk1(i32 3), !dbg !21
+// CHECK:STDOUT:   store i32 %SimpleReturnValue__carbon_thunk.call.loc12, ptr %value.var, align 4, !dbg !22
+// CHECK:STDOUT:   %SimpleReturnValue.call = call i32 @_Z17SimpleReturnValueii(i32 3, i32 4), !dbg !23
+// CHECK:STDOUT:   store i32 %SimpleReturnValue.call, ptr %value.var, align 4, !dbg !24
+// CHECK:STDOUT:   %.loc14 = load i32, ptr %value.var, align 4, !dbg !25
+// CHECK:STDOUT:   ret i32 %.loc14, !dbg !26
+// 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:
+// CHECK:STDOUT: attributes #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -455,7 +457,7 @@ fn MyF() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 1 - 1
toolchain/lower/testdata/interop/cpp/function_in_template.carbon

@@ -62,7 +62,7 @@ fn F() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 68 - 63
toolchain/lower/testdata/interop/cpp/globals.carbon

@@ -162,6 +162,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: %class.C = type { i8 }
 // CHECK:STDOUT:
 // CHECK:STDOUT: @global = dso_local global %class.C zeroinitializer, align 1
+// CHECK:STDOUT: @global.1 = external global {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define void @_CMyF.Main() #0 !dbg !12 {
@@ -178,7 +179,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -200,23 +201,15 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $inline_global = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init, ptr @inline_global }]
-// CHECK:STDOUT: @llvm.used = appending global [1 x ptr] [ptr @inline_global], section "llvm.metadata"
 // CHECK:STDOUT: @inline_global = linkonce_odr dso_local global %struct.C zeroinitializer, comdat, align 1
 // CHECK:STDOUT: @_ZGV13inline_global = linkonce_odr dso_local global i64 0, comdat($inline_global), align 8
 // CHECK:STDOUT: @__dso_handle = external hidden global i8
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCallF.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_ZN1C1fEv(ptr @inline_global), !dbg !15
-// CHECK:STDOUT:   ret void, !dbg !16
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1C1fEv(ptr)
+// CHECK:STDOUT: @inline_global.1 = external global {}
+// CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init, ptr @inline_global }]
+// CHECK:STDOUT: @llvm.used = appending global [1 x ptr] [ptr @inline_global], section "llvm.metadata"
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: uwtable
-// CHECK:STDOUT: define internal void @__cxx_global_var_init() #1 section ".text.startup" comdat($inline_global) personality ptr @__gxx_personality_v0 {
+// CHECK:STDOUT: define internal void @__cxx_global_var_init() #0 section ".text.startup" comdat($inline_global) personality ptr @__gxx_personality_v0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %exn.slot = alloca ptr, align 8
 // CHECK:STDOUT:   %ehselector.slot = alloca i32, align 4
@@ -225,7 +218,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:   br i1 %guard.uninitialized, label %init.check, label %init.end
 // CHECK:STDOUT:
 // CHECK:STDOUT: init.check:                                       ; preds = %entry
-// CHECK:STDOUT:   %1 = call i32 @__cxa_guard_acquire(ptr @_ZGV13inline_global) #0
+// CHECK:STDOUT:   %1 = call i32 @__cxa_guard_acquire(ptr @_ZGV13inline_global) #1
 // CHECK:STDOUT:   %tobool = icmp ne i32 %1, 0
 // CHECK:STDOUT:   br i1 %tobool, label %init, label %init.end
 // CHECK:STDOUT:
@@ -234,8 +227,8 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:           to label %invoke.cont unwind label %lpad
 // CHECK:STDOUT:
 // CHECK:STDOUT: invoke.cont:                                      ; preds = %init
-// CHECK:STDOUT:   %2 = call i32 @__cxa_atexit(ptr @_ZN1CD1Ev, ptr @inline_global, ptr @__dso_handle) #0
-// CHECK:STDOUT:   call void @__cxa_guard_release(ptr @_ZGV13inline_global) #0
+// CHECK:STDOUT:   %2 = call i32 @__cxa_atexit(ptr @_ZN1CD1Ev, ptr @inline_global, ptr @__dso_handle) #1
+// CHECK:STDOUT:   call void @__cxa_guard_release(ptr @_ZGV13inline_global) #1
 // CHECK:STDOUT:   br label %init.end
 // CHECK:STDOUT:
 // CHECK:STDOUT: init.end:                                         ; preds = %invoke.cont, %init.check, %entry
@@ -248,7 +241,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:   store ptr %4, ptr %exn.slot, align 8
 // CHECK:STDOUT:   %5 = extractvalue { ptr, i32 } %3, 1
 // CHECK:STDOUT:   store i32 %5, ptr %ehselector.slot, align 4
-// CHECK:STDOUT:   call void @__cxa_guard_abort(ptr @_ZGV13inline_global) #0
+// CHECK:STDOUT:   call void @__cxa_guard_abort(ptr @_ZGV13inline_global) #1
 // CHECK:STDOUT:   br label %eh.resume
 // CHECK:STDOUT:
 // CHECK:STDOUT: eh.resume:                                        ; preds = %lpad
@@ -259,30 +252,40 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:   resume { ptr, i32 } %lpad.val1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare i32 @__gxx_personality_v0(...)
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: declare i32 @__cxa_guard_acquire(ptr) #0
+// CHECK:STDOUT: declare i32 @__cxa_guard_acquire(ptr) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: declare void @_ZN1CC1Ev(ptr noundef nonnull align 1 dereferenceable(1)) unnamed_addr #2
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare i32 @__gxx_personality_v0(...)
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: declare void @_ZN1CD1Ev(ptr noundef nonnull align 1 dereferenceable(1)) unnamed_addr #3
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: declare i32 @__cxa_atexit(ptr, ptr, ptr) #0
+// CHECK:STDOUT: declare i32 @__cxa_atexit(ptr, ptr, ptr) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: declare void @__cxa_guard_abort(ptr) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: declare void @__cxa_guard_release(ptr) #0
+// CHECK:STDOUT: declare void @__cxa_guard_release(ptr) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: declare void @__cxa_guard_abort(ptr) #0
+// CHECK:STDOUT: define void @_CCallF.Main() #1 !dbg !12 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @_ZN1C1fEv(ptr @inline_global.1), !dbg !15
+// CHECK:STDOUT:   ret void, !dbg !16
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_ZN1C1fEv(ptr noundef nonnull align 1 dereferenceable(1)) #2
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
-// CHECK:STDOUT: uselistorder ptr @inline_global, { 1, 2, 4, 3, 0 }
+// CHECK:STDOUT: uselistorder ptr @inline_global, { 2, 3, 0, 1 }
+// CHECK:STDOUT: uselistorder ptr @_ZGV13inline_global, { 1, 0, 2, 3 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #0 = { 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 = { "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:
@@ -293,7 +296,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -318,42 +321,42 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @thread_local_global = dso_local thread_local global i32 0, align 4
 // CHECK:STDOUT: @thread_local_global_with_init = dso_local thread_local global i32 0, align 4
+// CHECK:STDOUT: @thread_local_global.1 = external global i32
+// CHECK:STDOUT: @thread_local_global_with_init.2 = external global i32
 // CHECK:STDOUT: @__tls_guard = internal thread_local global i8 0, align 1
 // CHECK:STDOUT:
 // CHECK:STDOUT: @_ZTH29thread_local_global_with_init = dso_local alias void (), ptr @__tls_init
 // CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: uwtable
+// CHECK:STDOUT: define internal void @__cxx_global_var_init() #0 section ".text.startup" {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %call = call noundef i32 @_Z4initv()
+// CHECK:STDOUT:   %0 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global_with_init)
+// CHECK:STDOUT:   store i32 %call, ptr %0, align 4, !tbaa !8
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare noundef i32 @_Z4initv() #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+// CHECK:STDOUT: declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #2
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CThreadLocalStore.Main() #0 !dbg !12 {
+// CHECK:STDOUT: define void @_CThreadLocalStore.Main() #3 !dbg !12 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   store i32 42, ptr @thread_local_global, align 4, !dbg !15
+// CHECK:STDOUT:   store i32 42, ptr @thread_local_global.1, align 4, !dbg !15
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CThreadLocalTriggerInit.Main() #0 !dbg !17 {
+// CHECK:STDOUT: define i32 @_CThreadLocalTriggerInit.Main() #3 !dbg !17 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc14 = load i32, ptr @thread_local_global_with_init, align 4, !dbg !21
+// CHECK:STDOUT:   %.loc14 = load i32, ptr @thread_local_global_with_init.2, align 4, !dbg !21
 // CHECK:STDOUT:   ret i32 %.loc14, !dbg !22
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: uwtable
-// CHECK:STDOUT: define weak_odr hidden noundef ptr @_ZTW19thread_local_global() #1 comdat {
-// CHECK:STDOUT:   %1 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global)
-// CHECK:STDOUT:   ret ptr %1
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-// CHECK:STDOUT: declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #2
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: uwtable
-// CHECK:STDOUT: define weak_odr hidden noundef ptr @_ZTW29thread_local_global_with_init() #1 comdat {
-// CHECK:STDOUT:   call void @_ZTH29thread_local_global_with_init()
-// CHECK:STDOUT:   %1 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global_with_init)
-// CHECK:STDOUT:   ret ptr %1
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: uwtable
-// CHECK:STDOUT: define internal void @__tls_init() #3 {
+// CHECK:STDOUT: define internal void @__tls_init() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %0 = load i8, ptr @__tls_guard, align 1
 // CHECK:STDOUT:   %guard.uninitialized = icmp eq i8 %0, 0
@@ -373,22 +376,24 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: declare ptr @llvm.invariant.start.p0(i64 immarg, ptr captures(none)) #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: uwtable
-// CHECK:STDOUT: define internal void @__cxx_global_var_init() #3 section ".text.startup" {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %call = call noundef i32 @_Z4initv()
-// CHECK:STDOUT:   %0 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global_with_init)
-// CHECK:STDOUT:   store i32 %call, ptr %0, align 4, !tbaa !8
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: define weak_odr hidden noundef ptr @_ZTW19thread_local_global() #5 comdat {
+// CHECK:STDOUT:   %1 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global)
+// CHECK:STDOUT:   ret ptr %1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef i32 @_Z4initv() #5
+// CHECK:STDOUT: ; Function Attrs: uwtable
+// CHECK:STDOUT: define weak_odr hidden noundef ptr @_ZTW29thread_local_global_with_init() #5 comdat {
+// CHECK:STDOUT:   call void @_ZTH29thread_local_global_with_init()
+// CHECK:STDOUT:   %1 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @thread_local_global_with_init)
+// CHECK:STDOUT:   ret ptr %1
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { uwtable "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 #0 = { 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 = { "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 speculatable willreturn memory(none) }
-// CHECK:STDOUT: attributes #3 = { 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 = { 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: attributes #5 = { uwtable "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.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -397,7 +402,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -441,7 +446,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -488,7 +493,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -540,7 +545,7 @@ fn ReadStaticVarTemplateWithConstructor() -> Cpp.Y* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 32 - 32
toolchain/lower/testdata/interop/cpp/import_inline.carbon

@@ -29,33 +29,33 @@ fn Call() -> i32 {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CCall.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !16
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !16
-// CHECK:STDOUT:   store i32 0, ptr %n.var, align 4, !dbg !16
-// CHECK:STDOUT:   call void @_Z1FPi(ptr %n.var), !dbg !17
-// CHECK:STDOUT:   %.loc24 = load i32, ptr %n.var, align 4, !dbg !18
-// CHECK:STDOUT:   ret i32 %.loc24, !dbg !19
-// 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: mustprogress nounwind uwtable
-// CHECK:STDOUT: define dso_local void @_Z1FPi(ptr noundef %p) #2 {
+// CHECK:STDOUT: define dso_local void @_Z1FPi(ptr noundef %p) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %p.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %p, ptr %p.addr, align 8, !tbaa !20
-// CHECK:STDOUT:   %0 = load ptr, ptr %p.addr, align 8, !tbaa !20
+// CHECK:STDOUT:   store ptr %p, ptr %p.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %p.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   store i32 1, ptr %0, align 4, !tbaa !8
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// CHECK:STDOUT: attributes #2 = { 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CCall.Main() #1 !dbg !15 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !19
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !19
+// CHECK:STDOUT:   store i32 0, ptr %n.var, align 4, !dbg !19
+// CHECK:STDOUT:   call void @_Z1FPi(ptr %n.var), !dbg !20
+// CHECK:STDOUT:   %.loc24 = load i32, ptr %n.var, align 4, !dbg !21
+// CHECK:STDOUT:   ret i32 %.loc24, !dbg !22
+// 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:
+// 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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -64,7 +64,7 @@ fn Call() -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -73,14 +73,14 @@ fn Call() -> i32 {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 21, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15}
-// CHECK:STDOUT: !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !16 = !DILocation(line: 22, column: 3, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 23, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 24, column: 10, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 24, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = !{!21, !21, i64 0}
-// CHECK:STDOUT: !21 = !{!"p1 int", !22, i64 0}
-// CHECK:STDOUT: !22 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 int", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 21, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{!18}
+// CHECK:STDOUT: !18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !19 = !DILocation(line: 22, column: 3, scope: !15)
+// CHECK:STDOUT: !20 = !DILocation(line: 23, column: 3, scope: !15)
+// CHECK:STDOUT: !21 = !DILocation(line: 24, column: 10, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 24, column: 3, scope: !15)

+ 93 - 92
toolchain/lower/testdata/interop/cpp/method.carbon

@@ -83,37 +83,37 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_ZNK1A6by_valEv = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CUseVal.Main(ptr %a) #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %by_val__carbon_thunk.call = call i32 @_ZNK1A6by_valEv.carbon_thunk(ptr %a), !dbg !19
-// CHECK:STDOUT:   ret i32 %by_val__carbon_thunk.call, !dbg !20
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef i32 @_ZNK1A6by_valEv.carbon_thunk(ptr noundef nonnull align 8 dereferenceable(12) %this) #1 {
+// CHECK:STDOUT: define dso_local noundef i32 @_ZNK1A6by_valEv.carbon_thunk(ptr noundef nonnull align 8 dereferenceable(12) %this) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %this.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   %0 = load ptr, ptr %this.addr, align 8, !tbaa !21, !nonnull !24, !align !25
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %this.addr, align 8, !tbaa !12, !nonnull !15, !align !16
 // CHECK:STDOUT:   %call = call noundef i32 @_ZNK1A6by_valEv(ptr noundef nonnull align 8 dereferenceable(12) %0)
 // CHECK:STDOUT:   ret i32 %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_ZNK1A6by_valEv(ptr noundef nonnull align 8 dereferenceable(12) %this) #2 comdat align 2 {
+// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_ZNK1A6by_valEv(ptr noundef nonnull align 8 dereferenceable(12) %this) #1 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 !21
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
 // CHECK:STDOUT:   %n = getelementptr inbounds nuw %struct.A, ptr %this1, i32 0, i32 1
-// CHECK:STDOUT:   %0 = load i32, ptr %n, align 8, !tbaa !26
+// CHECK:STDOUT:   %0 = load i32, ptr %n, align 8, !tbaa !17
 // CHECK:STDOUT:   ret i32 %0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #2 = { 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CUseVal.Main(ptr %a) #2 !dbg !20 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %by_val__carbon_thunk.call = call i32 @_ZNK1A6by_valEv.carbon_thunk(ptr %a), !dbg !27
+// CHECK:STDOUT:   ret i32 %by_val__carbon_thunk.call, !dbg !28
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { 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 #1 = { 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -122,7 +122,7 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -131,23 +131,23 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "UseVal", linkageName: "_CUseVal.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !17)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15, !16}
-// CHECK:STDOUT: !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !17 = !{!18}
-// CHECK:STDOUT: !18 = !DILocalVariable(arg: 1, scope: !12, type: !16)
-// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 10, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !{!22, !22, i64 0}
-// CHECK:STDOUT: !22 = !{!"p1 _ZTS1A", !23, i64 0}
-// CHECK:STDOUT: !23 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !24 = !{}
-// CHECK:STDOUT: !25 = !{i64 8}
-// CHECK:STDOUT: !26 = !{!27, !9, i64 8}
-// CHECK:STDOUT: !27 = !{!"_ZTS1A", !28, i64 0, !9, i64 8}
-// CHECK:STDOUT: !28 = !{!"_ZTS4Base"}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1A", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{}
+// CHECK:STDOUT: !16 = !{i64 8}
+// CHECK:STDOUT: !17 = !{!18, !9, i64 8}
+// CHECK:STDOUT: !18 = !{!"_ZTS1A", !19, i64 0, !9, i64 8}
+// CHECK:STDOUT: !19 = !{!"_ZTS4Base"}
+// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "UseVal", linkageName: "_CUseVal.Main", scope: null, file: !7, line: 6, type: !21, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !25)
+// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
+// CHECK:STDOUT: !22 = !{!23, !24}
+// CHECK:STDOUT: !23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !25 = !{!26}
+// CHECK:STDOUT: !26 = !DILocalVariable(arg: 1, scope: !20, type: !24)
+// CHECK:STDOUT: !27 = !DILocation(line: 7, column: 10, scope: !20)
+// CHECK:STDOUT: !28 = !DILocation(line: 7, column: 3, scope: !20)
 // CHECK:STDOUT: ; ModuleID = 'call_by_ref.carbon'
 // CHECK:STDOUT: source_filename = "call_by_ref.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -186,7 +186,7 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -230,11 +230,12 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT:   ret void, !dbg !20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN4Base5virt0Ev(ptr)
+// CHECK:STDOUT: declare void @_ZN4Base5virt0Ev(ptr noundef nonnull align 8 dereferenceable(8)) unnamed_addr #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1A5virt1Ev(ptr)
+// CHECK:STDOUT: declare void @_ZN1A5virt1Ev(ptr noundef nonnull align 8 dereferenceable(12)) unnamed_addr #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -243,7 +244,7 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -268,63 +269,63 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %struct.NeedThunk = type { i8 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCall.Main(ptr %n) #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_14.3.temp = alloca i8, align 1, !dbg !18
-// CHECK:STDOUT:   %.loc8_14.3.temp = alloca i8, align 1, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_14.3.temp), !dbg !18
-// CHECK:STDOUT:   store i8 1, ptr %.loc7_14.3.temp, align 1, !dbg !18
-// CHECK:STDOUT:   call void @_ZNK9NeedThunk8ImplicitEa.carbon_thunk(ptr %n, ptr %.loc7_14.3.temp), !dbg !20
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_14.3.temp), !dbg !19
-// CHECK:STDOUT:   store i8 1, ptr %.loc8_14.3.temp, align 1, !dbg !19
-// CHECK:STDOUT:   call void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk(ptr %n, ptr %.loc8_14.3.temp), !dbg !21
-// CHECK:STDOUT:   ret void, !dbg !22
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_ZNK9NeedThunk8ImplicitEa.carbon_thunk(ptr noundef nonnull align 1 dereferenceable(1) %this, ptr noundef %c) #2 {
+// CHECK:STDOUT: define dso_local void @_ZNK9NeedThunk8ImplicitEa.carbon_thunk(ptr noundef nonnull align 1 dereferenceable(1) %this, ptr noundef %c) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %this.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %c.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !23
-// CHECK:STDOUT:   store ptr %c, ptr %c.addr, align 8, !tbaa !26
-// CHECK:STDOUT:   %0 = load ptr, ptr %this.addr, align 8, !tbaa !23, !nonnull !28
-// CHECK:STDOUT:   %1 = load ptr, ptr %c.addr, align 8, !tbaa !26
-// CHECK:STDOUT:   %2 = load i8, ptr %1, align 1, !tbaa !29
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %c, ptr %c.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %0 = load ptr, ptr %this.addr, align 8, !tbaa !12, !nonnull !17
+// CHECK:STDOUT:   %1 = load ptr, ptr %c.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %2 = load i8, ptr %1, align 1, !tbaa !18
 // CHECK:STDOUT:   call void @_ZNK9NeedThunk8ImplicitEa(ptr noundef nonnull align 1 dereferenceable(1) %0, i8 noundef signext %2)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZNK9NeedThunk8ImplicitEa(ptr noundef nonnull align 1 dereferenceable(1), i8 noundef signext) #3
+// CHECK:STDOUT: declare void @_ZNK9NeedThunk8ImplicitEa(ptr noundef nonnull align 1 dereferenceable(1), i8 noundef signext) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk(ptr noundef %0, ptr noundef %c) #2 {
+// CHECK:STDOUT: define dso_local void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk(ptr noundef %0, ptr noundef %c) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %c.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %struct.NeedThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !23
-// CHECK:STDOUT:   store ptr %c, ptr %c.addr, align 8, !tbaa !26
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !23
-// CHECK:STDOUT:   %2 = load ptr, ptr %c.addr, align 8, !tbaa !26
-// CHECK:STDOUT:   %3 = load i8, ptr %2, align 1, !tbaa !29
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %c, ptr %c.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %2 = load ptr, ptr %c.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %3 = load i8, ptr %2, align 1, !tbaa !18
 // CHECK:STDOUT:   call void @_ZNH9NeedThunk8ExplicitES_a(i8 noundef signext %3)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZNH9NeedThunk8ExplicitES_a(i8 noundef signext) #3
+// CHECK:STDOUT: declare void @_ZNH9NeedThunk8ExplicitES_a(i8 noundef signext) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCall.Main(ptr %n) #2 !dbg !19 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc7_14.3.temp = alloca i8, align 1, !dbg !25
+// CHECK:STDOUT:   %.loc8_14.3.temp = alloca i8, align 1, !dbg !26
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_14.3.temp), !dbg !25
+// CHECK:STDOUT:   store i8 1, ptr %.loc7_14.3.temp, align 1, !dbg !25
+// CHECK:STDOUT:   call void @_ZNK9NeedThunk8ImplicitEa.carbon_thunk(ptr %n, ptr %.loc7_14.3.temp), !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_14.3.temp), !dbg !26
+// CHECK:STDOUT:   store i8 1, ptr %.loc8_14.3.temp, align 1, !dbg !26
+// CHECK:STDOUT:   call void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk(ptr %n, ptr %.loc8_14.3.temp), !dbg !28
+// CHECK:STDOUT:   ret void, !dbg !29
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -333,7 +334,7 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -342,21 +343,21 @@ fn Call(n: Cpp.NeedThunk) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 14, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 8, column: 14, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !DILocation(line: 8, column: 3, scope: !12)
-// CHECK:STDOUT: !22 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !23 = !{!24, !24, i64 0}
-// CHECK:STDOUT: !24 = !{!"p1 _ZTS9NeedThunk", !25, i64 0}
-// CHECK:STDOUT: !25 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !26 = !{!27, !27, i64 0}
-// CHECK:STDOUT: !27 = !{!"p1 omnipotent char", !25, i64 0}
-// CHECK:STDOUT: !28 = !{}
-// CHECK:STDOUT: !29 = !{!10, !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS9NeedThunk", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"p1 omnipotent char", !14, i64 0}
+// CHECK:STDOUT: !17 = !{}
+// CHECK:STDOUT: !18 = !{!10, !10, i64 0}
+// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 6, type: !20, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !23)
+// CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
+// CHECK:STDOUT: !21 = !{null, !22}
+// CHECK:STDOUT: !22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !23 = !{!24}
+// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !19, type: !22)
+// CHECK:STDOUT: !25 = !DILocation(line: 7, column: 14, scope: !19)
+// CHECK:STDOUT: !26 = !DILocation(line: 8, column: 14, scope: !19)
+// CHECK:STDOUT: !27 = !DILocation(line: 7, column: 3, scope: !19)
+// CHECK:STDOUT: !28 = !DILocation(line: 8, column: 3, scope: !19)
+// CHECK:STDOUT: !29 = !DILocation(line: 6, column: 1, scope: !19)

+ 127 - 127
toolchain/lower/testdata/interop/cpp/nullptr.carbon

@@ -54,128 +54,128 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassNullptr.Main() #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z11TakeNullptrDn.carbon_thunk(ptr noundef %n) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc12_18.2.temp = alloca ptr, align 8, !dbg !15
-// CHECK:STDOUT:   %.loc14_22.1.temp = alloca ptr, align 8, !dbg !16
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.2.temp), !dbg !15
-// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, ptr %.loc12_18.2.temp, align 8, !dbg !15
-// CHECK:STDOUT:   %.loc12_18.4 = load ptr, ptr %.loc12_18.2.temp, align 8, !dbg !15
-// CHECK:STDOUT:   call void @_Z7TakePtrPi(ptr %.loc12_18.4), !dbg !17
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc14_22.1.temp), !dbg !16
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !16
-// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.Copy.impl.Op.call, ptr %.loc14_22.1.temp, align 8, !dbg !16
-// CHECK:STDOUT:   call void @_Z11TakeNullptrDn.carbon_thunk(ptr %.loc14_22.1.temp), !dbg !18
-// CHECK:STDOUT:   ret void, !dbg !19
+// CHECK:STDOUT:   %n.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %n, ptr %n.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %n.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_Z11TakeNullptrDn(ptr null)
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z7TakePtrPi(ptr)
+// CHECK:STDOUT: declare void @_Z11TakeNullptrDn(ptr) #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr)
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z13ReturnNullptrv.carbon_thunk(ptr noundef %return) #0 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %call = call ptr @_Z13ReturnNullptrv()
+// CHECK:STDOUT:   store ptr %call, ptr %0, align 8, !tbaa !15
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare ptr @_Z13ReturnNullptrv() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnNullptr.Main() #0 !dbg !20 {
+// CHECK:STDOUT: define void @_CPassNullptr.Main() #2 !dbg !17 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !24
-// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.Copy.impl.Op.call, !dbg !25
+// CHECK:STDOUT:   %.loc12_18.2.temp = alloca ptr, align 8, !dbg !20
+// CHECK:STDOUT:   %.loc14_22.1.temp = alloca ptr, align 8, !dbg !21
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !20
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.2.temp), !dbg !20
+// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, ptr %.loc12_18.2.temp, align 8, !dbg !20
+// CHECK:STDOUT:   %.loc12_18.4 = load ptr, ptr %.loc12_18.2.temp, align 8, !dbg !20
+// CHECK:STDOUT:   call void @_Z7TakePtrPi(ptr %.loc12_18.4), !dbg !22
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc14_22.1.temp), !dbg !21
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !21
+// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.Copy.impl.Op.call, ptr %.loc14_22.1.temp, align 8, !dbg !21
+// CHECK:STDOUT:   call void @_Z11TakeNullptrDn.carbon_thunk(ptr %.loc14_22.1.temp), !dbg !23
+// CHECK:STDOUT:   ret void, !dbg !24
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z7TakePtrPi(ptr noundef) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr)
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnNullptrCopy.Main() #0 !dbg !26 {
+// CHECK:STDOUT: define ptr @_CReturnNullptr.Main() #2 !dbg !25 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %a.var = alloca ptr, align 8, !dbg !27
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %a.var), !dbg !27
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call.loc22 = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !28
-// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.Copy.impl.Op.call.loc22, ptr %a.var, align 8, !dbg !27
-// CHECK:STDOUT:   %.loc23 = load ptr, ptr %a.var, align 8, !dbg !29
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call.loc23 = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr %.loc23), !dbg !29
-// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.Copy.impl.Op.call.loc23, !dbg !30
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !29
+// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.Copy.impl.Op.call, !dbg !30
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnConvertedNullptrIndirectly.Main() #0 !dbg !31 {
+// CHECK:STDOUT: define ptr @_CReturnNullptrCopy.Main() #2 !dbg !31 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %a.var = alloca ptr, align 8, !dbg !32
-// CHECK:STDOUT:   %.loc27_44.1.temp = alloca ptr, align 8, !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %a.var), !dbg !32
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc27_44.1.temp), !dbg !33
-// CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc27_44.1.temp), !dbg !33
-// CHECK:STDOUT:   %.loc27_44.2 = load ptr, ptr %.loc27_44.1.temp, align 8, !dbg !33
-// CHECK:STDOUT:   store ptr %.loc27_44.2, ptr %a.var, align 8, !dbg !32
-// CHECK:STDOUT:   %.loc28_10 = load ptr, ptr %a.var, align 8, !dbg !34
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc28_10), !dbg !35
-// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !35
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call.loc22 = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr poison), !dbg !33
+// CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.Copy.impl.Op.call.loc22, ptr %a.var, align 8, !dbg !32
+// CHECK:STDOUT:   %.loc23 = load ptr, ptr %a.var, align 8, !dbg !34
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.Copy.impl.Op.call.loc23 = call ptr @"_COp.NullptrT.CppCompat.Core:Copy.Core"(ptr %.loc23), !dbg !34
+// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.Copy.impl.Op.call.loc23, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnConvertedNullptrDirectly.Main() #0 !dbg !36 {
+// CHECK:STDOUT: define ptr @_CReturnConvertedNullptrIndirectly.Main() #2 !dbg !36 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc32_28.1.temp = alloca ptr, align 8, !dbg !37
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc32_28.1.temp), !dbg !37
-// CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc32_28.1.temp), !dbg !37
-// CHECK:STDOUT:   %.loc32_28.2 = load ptr, ptr %.loc32_28.1.temp, align 8, !dbg !37
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc32_28.2), !dbg !38
-// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !38
+// CHECK:STDOUT:   %a.var = alloca ptr, align 8, !dbg !37
+// CHECK:STDOUT:   %.loc27_44.1.temp = alloca ptr, align 8, !dbg !38
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %a.var), !dbg !37
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc27_44.1.temp), !dbg !38
+// CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc27_44.1.temp), !dbg !38
+// CHECK:STDOUT:   %.loc27_44.2 = load ptr, ptr %.loc27_44.1.temp, align 8, !dbg !38
+// CHECK:STDOUT:   store ptr %.loc27_44.2, ptr %a.var, align 8, !dbg !37
+// CHECK:STDOUT:   %.loc28_10 = load ptr, ptr %a.var, align 8, !dbg !39
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc28_10), !dbg !40
+// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !40
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CConvertNullptrConstant.Main() #0 !dbg !39 {
+// CHECK:STDOUT: define ptr @_CReturnConvertedNullptrDirectly.Main() #2 !dbg !41 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !40
-// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !40
+// CHECK:STDOUT:   %.loc32_28.1.temp = alloca ptr, align 8, !dbg !42
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc32_28.1.temp), !dbg !42
+// CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc32_28.1.temp), !dbg !42
+// CHECK:STDOUT:   %.loc32_28.2 = load ptr, ptr %.loc32_28.1.temp, align 8, !dbg !42
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc32_28.2), !dbg !43
+// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !43
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define ptr @_CConvertNullptrConstant.Main() #2 !dbg !44 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !45
+// CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !45
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %self) #0 !dbg !41 {
-// CHECK:STDOUT:   %1 = call ptr @_CNone.Optional.Core.7bfe1822cd6dd563(), !dbg !47
-// CHECK:STDOUT:   ret ptr %1, !dbg !48
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %self) #2 !dbg !46 {
+// CHECK:STDOUT:   %1 = call ptr @_CNone.Optional.Core.7bfe1822cd6dd563(), !dbg !52
+// CHECK:STDOUT:   ret ptr %1, !dbg !53
 // 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)) #3
 // CHECK:STDOUT:
 // CHECK:STDOUT: declare ptr @_CMake.NullptrT.CppCompat.Core()
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @_CNone.Optional.Core.7bfe1822cd6dd563() #0 !dbg !49 {
-// CHECK:STDOUT:   ret ptr null, !dbg !51
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z11TakeNullptrDn.carbon_thunk(ptr noundef %n) #2 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %n.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %n, ptr %n.addr, align 8, !tbaa !52
-// CHECK:STDOUT:   %0 = load ptr, ptr %n.addr, align 8, !tbaa !52
-// CHECK:STDOUT:   call void @_Z11TakeNullptrDn(ptr null)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: define linkonce_odr ptr @_CNone.Optional.Core.7bfe1822cd6dd563() #2 !dbg !54 {
+// CHECK:STDOUT:   ret ptr null, !dbg !56
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11TakeNullptrDn(ptr) #3
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z13ReturnNullptrv.carbon_thunk(ptr noundef %return) #2 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !52
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !52
-// CHECK:STDOUT:   %call = call ptr @_Z13ReturnNullptrv()
-// CHECK:STDOUT:   store ptr %call, ptr %0, align 8, !tbaa !55
-// CHECK:STDOUT:   ret void
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z13ReturnNullptrv() #3
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4", { 3, 2, 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -184,7 +184,7 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -193,48 +193,48 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassNullptr", linkageName: "_CPassNullptr.Main", scope: null, file: !7, line: 11, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 12, column: 15, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 14, column: 19, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 12, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 14, column: 3, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 11, column: 1, scope: !12)
-// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "ReturnNullptr", linkageName: "_CReturnNullptr.Main", scope: null, file: !7, line: 17, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
-// CHECK:STDOUT: !22 = !{!23}
-// CHECK:STDOUT: !23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !24 = !DILocation(line: 18, column: 10, scope: !20)
-// CHECK:STDOUT: !25 = !DILocation(line: 18, column: 3, scope: !20)
-// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "ReturnNullptrCopy", linkageName: "_CReturnNullptrCopy.Main", scope: null, file: !7, line: 21, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !27 = !DILocation(line: 22, column: 3, scope: !26)
-// CHECK:STDOUT: !28 = !DILocation(line: 22, column: 26, scope: !26)
-// CHECK:STDOUT: !29 = !DILocation(line: 23, column: 10, scope: !26)
-// CHECK:STDOUT: !30 = !DILocation(line: 23, column: 3, scope: !26)
-// CHECK:STDOUT: !31 = distinct !DISubprogram(name: "ReturnConvertedNullptrIndirectly", linkageName: "_CReturnConvertedNullptrIndirectly.Main", scope: null, file: !7, line: 26, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !32 = !DILocation(line: 27, column: 3, scope: !31)
-// CHECK:STDOUT: !33 = !DILocation(line: 27, column: 26, scope: !31)
-// CHECK:STDOUT: !34 = !DILocation(line: 28, column: 10, scope: !31)
-// CHECK:STDOUT: !35 = !DILocation(line: 28, column: 3, scope: !31)
-// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "ReturnConvertedNullptrDirectly", linkageName: "_CReturnConvertedNullptrDirectly.Main", scope: null, file: !7, line: 31, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !37 = !DILocation(line: 32, column: 10, scope: !36)
-// CHECK:STDOUT: !38 = !DILocation(line: 32, column: 3, scope: !36)
-// CHECK:STDOUT: !39 = distinct !DISubprogram(name: "ConvertNullptrConstant", linkageName: "_CConvertNullptrConstant.Main", scope: null, file: !7, line: 35, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !40 = !DILocation(line: 36, column: 3, scope: !39)
-// CHECK:STDOUT: !41 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4", scope: null, file: !42, line: 46, type: !43, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !45)
-// CHECK:STDOUT: !42 = !DIFile(filename: "{{.*}}/prelude/types/cpp/nullptr.carbon", directory: "")
-// CHECK:STDOUT: !43 = !DISubroutineType(types: !44)
-// CHECK:STDOUT: !44 = !{!23, !23}
-// CHECK:STDOUT: !45 = !{!46}
-// CHECK:STDOUT: !46 = !DILocalVariable(arg: 1, scope: !41, type: !23)
-// CHECK:STDOUT: !47 = !DILocation(line: 47, column: 14, scope: !41)
-// CHECK:STDOUT: !48 = !DILocation(line: 47, column: 7, scope: !41)
-// CHECK:STDOUT: !49 = distinct !DISubprogram(name: "None", linkageName: "_CNone.Optional.Core.7bfe1822cd6dd563", scope: null, file: !50, line: 26, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !50 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
-// CHECK:STDOUT: !51 = !DILocation(line: 27, column: 5, scope: !49)
-// CHECK:STDOUT: !52 = !{!53, !53, i64 0}
-// CHECK:STDOUT: !53 = !{!"p1 std::nullptr_t", !54, i64 0}
-// CHECK:STDOUT: !54 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !55 = !{!56, !56, i64 0}
-// CHECK:STDOUT: !56 = !{!"std::nullptr_t", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 std::nullptr_t", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"std::nullptr_t", !10, i64 0}
+// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "PassNullptr", linkageName: "_CPassNullptr.Main", scope: null, file: !7, line: 11, type: !18, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
+// CHECK:STDOUT: !19 = !{null}
+// CHECK:STDOUT: !20 = !DILocation(line: 12, column: 15, scope: !17)
+// CHECK:STDOUT: !21 = !DILocation(line: 14, column: 19, scope: !17)
+// CHECK:STDOUT: !22 = !DILocation(line: 12, column: 3, scope: !17)
+// CHECK:STDOUT: !23 = !DILocation(line: 14, column: 3, scope: !17)
+// CHECK:STDOUT: !24 = !DILocation(line: 11, column: 1, scope: !17)
+// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "ReturnNullptr", linkageName: "_CReturnNullptr.Main", scope: null, file: !7, line: 17, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !26 = !DISubroutineType(types: !27)
+// CHECK:STDOUT: !27 = !{!28}
+// CHECK:STDOUT: !28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !29 = !DILocation(line: 18, column: 10, scope: !25)
+// CHECK:STDOUT: !30 = !DILocation(line: 18, column: 3, scope: !25)
+// CHECK:STDOUT: !31 = distinct !DISubprogram(name: "ReturnNullptrCopy", linkageName: "_CReturnNullptrCopy.Main", scope: null, file: !7, line: 21, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !32 = !DILocation(line: 22, column: 3, scope: !31)
+// CHECK:STDOUT: !33 = !DILocation(line: 22, column: 26, scope: !31)
+// CHECK:STDOUT: !34 = !DILocation(line: 23, column: 10, scope: !31)
+// CHECK:STDOUT: !35 = !DILocation(line: 23, column: 3, scope: !31)
+// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "ReturnConvertedNullptrIndirectly", linkageName: "_CReturnConvertedNullptrIndirectly.Main", scope: null, file: !7, line: 26, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !37 = !DILocation(line: 27, column: 3, scope: !36)
+// CHECK:STDOUT: !38 = !DILocation(line: 27, column: 26, scope: !36)
+// CHECK:STDOUT: !39 = !DILocation(line: 28, column: 10, scope: !36)
+// CHECK:STDOUT: !40 = !DILocation(line: 28, column: 3, scope: !36)
+// CHECK:STDOUT: !41 = distinct !DISubprogram(name: "ReturnConvertedNullptrDirectly", linkageName: "_CReturnConvertedNullptrDirectly.Main", scope: null, file: !7, line: 31, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !42 = !DILocation(line: 32, column: 10, scope: !41)
+// CHECK:STDOUT: !43 = !DILocation(line: 32, column: 3, scope: !41)
+// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "ConvertNullptrConstant", linkageName: "_CConvertNullptrConstant.Main", scope: null, file: !7, line: 35, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !45 = !DILocation(line: 36, column: 3, scope: !44)
+// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4", scope: null, file: !47, line: 46, type: !48, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !50)
+// CHECK:STDOUT: !47 = !DIFile(filename: "{{.*}}/prelude/types/cpp/nullptr.carbon", directory: "")
+// CHECK:STDOUT: !48 = !DISubroutineType(types: !49)
+// CHECK:STDOUT: !49 = !{!28, !28}
+// CHECK:STDOUT: !50 = !{!51}
+// CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !46, type: !28)
+// CHECK:STDOUT: !52 = !DILocation(line: 47, column: 14, scope: !46)
+// CHECK:STDOUT: !53 = !DILocation(line: 47, column: 7, scope: !46)
+// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "None", linkageName: "_CNone.Optional.Core.7bfe1822cd6dd563", scope: null, file: !55, line: 26, type: !26, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !55 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
+// CHECK:STDOUT: !56 = !DILocation(line: 27, column: 5, scope: !54)

+ 225 - 225
toolchain/lower/testdata/interop/cpp/parameters.carbon

@@ -115,122 +115,122 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @_Cc.Main = global i16 0
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CMyF.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_19.3.temp = alloca i8, align 1, !dbg !15
-// CHECK:STDOUT:   %.loc7_22.3.temp = alloca i16, align 2, !dbg !16
-// CHECK:STDOUT:   %.loc9_21.3.temp = alloca i8, align 1, !dbg !17
-// CHECK:STDOUT:   %.loc9_24.3.temp = alloca i16, align 2, !dbg !18
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_19.3.temp), !dbg !15
-// CHECK:STDOUT:   store i8 1, ptr %.loc7_19.3.temp, align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_22.3.temp), !dbg !16
-// CHECK:STDOUT:   store i16 2, ptr %.loc7_22.3.temp, align 2, !dbg !16
-// CHECK:STDOUT:   call void @_Z11pass_signedasil.carbon_thunk(ptr %.loc7_19.3.temp, ptr %.loc7_22.3.temp, i32 3, i64 4), !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_21.3.temp), !dbg !17
-// CHECK:STDOUT:   store i8 1, ptr %.loc9_21.3.temp, align 1, !dbg !17
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_24.3.temp), !dbg !18
-// CHECK:STDOUT:   store i16 2, ptr %.loc9_24.3.temp, align 2, !dbg !18
-// CHECK:STDOUT:   call void @_Z13pass_unsignedhtjm.carbon_thunk(ptr %.loc9_21.3.temp, ptr %.loc9_24.3.temp, i32 3, i64 4), !dbg !20
-// CHECK:STDOUT:   ret void, !dbg !21
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare i16 @_CMakeShort.Main()
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassShort.Main(i16 %a, ptr %b) #0 !dbg !22 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc17_18.1.temp = alloca i16, align 2, !dbg !30
-// CHECK:STDOUT:   %.loc18_18.3.temp = alloca i16, align 2, !dbg !31
-// CHECK:STDOUT:   %.loc19_18.2.temp = alloca i16, align 2, !dbg !32
-// CHECK:STDOUT:   %.loc20_28.3.temp = alloca i16, align 2, !dbg !33
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_18.1.temp), !dbg !30
-// CHECK:STDOUT:   store i16 %a, ptr %.loc17_18.1.temp, align 2, !dbg !30
-// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc17_18.1.temp), !dbg !34
-// CHECK:STDOUT:   %.loc18_18.2 = load i16, ptr %b, align 2, !dbg !31
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_18.3.temp), !dbg !31
-// CHECK:STDOUT:   store i16 %.loc18_18.2, ptr %.loc18_18.3.temp, align 2, !dbg !31
-// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc18_18.3.temp), !dbg !35
-// CHECK:STDOUT:   %.loc19_18.1 = load i16, ptr @_Cc.Main, align 2, !dbg !32
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_18.2.temp), !dbg !32
-// CHECK:STDOUT:   store i16 %.loc19_18.1, ptr %.loc19_18.2.temp, align 2, !dbg !32
-// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc19_18.2.temp), !dbg !36
-// CHECK:STDOUT:   %MakeShort.call = call i16 @_CMakeShort.Main(), !dbg !33
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_28.3.temp), !dbg !33
-// CHECK:STDOUT:   store i16 %MakeShort.call, ptr %.loc20_28.3.temp, align 2, !dbg !33
-// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc20_28.3.temp), !dbg !37
-// CHECK:STDOUT:   ret void, !dbg !38
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_Z11pass_signedasil.carbon_thunk(ptr noundef %0, ptr noundef %1, i32 noundef %2, i64 noundef %3) #2 {
+// CHECK:STDOUT: define dso_local void @_Z11pass_signedasil.carbon_thunk(ptr noundef %0, ptr noundef %1, i32 noundef %2, i64 noundef %3) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr1 = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr2 = alloca i32, align 4
 // CHECK:STDOUT:   %.addr3 = alloca i64, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !39
-// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !42
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !15
 // CHECK:STDOUT:   store i32 %2, ptr %.addr2, align 4, !tbaa !8
-// CHECK:STDOUT:   store i64 %3, ptr %.addr3, align 8, !tbaa !44
-// CHECK:STDOUT:   %4 = load ptr, ptr %.addr, align 8, !tbaa !39
-// CHECK:STDOUT:   %5 = load i8, ptr %4, align 1, !tbaa !46
-// CHECK:STDOUT:   %6 = load ptr, ptr %.addr1, align 8, !tbaa !42
-// CHECK:STDOUT:   %7 = load i16, ptr %6, align 2, !tbaa !47
+// CHECK:STDOUT:   store i64 %3, ptr %.addr3, align 8, !tbaa !17
+// CHECK:STDOUT:   %4 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %5 = load i8, ptr %4, align 1, !tbaa !19
+// CHECK:STDOUT:   %6 = load ptr, ptr %.addr1, align 8, !tbaa !15
+// CHECK:STDOUT:   %7 = load i16, ptr %6, align 2, !tbaa !20
 // CHECK:STDOUT:   %8 = load i32, ptr %.addr2, align 4, !tbaa !8
-// CHECK:STDOUT:   %9 = load i64, ptr %.addr3, align 8, !tbaa !44
+// CHECK:STDOUT:   %9 = load i64, ptr %.addr3, align 8, !tbaa !17
 // CHECK:STDOUT:   call void @_Z11pass_signedasil(i8 noundef signext %5, i16 noundef signext %7, i32 noundef %8, i64 noundef %9)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11pass_signedasil(i8 noundef signext, i16 noundef signext, i32 noundef, i64 noundef) #3
+// CHECK:STDOUT: declare void @_Z11pass_signedasil(i8 noundef signext, i16 noundef signext, i32 noundef, i64 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z13pass_unsignedhtjm.carbon_thunk(ptr noundef %0, ptr noundef %1, i32 noundef %2, i64 noundef %3) #2 {
+// CHECK:STDOUT: define dso_local void @_Z13pass_unsignedhtjm.carbon_thunk(ptr noundef %0, ptr noundef %1, i32 noundef %2, i64 noundef %3) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr1 = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr2 = alloca i32, align 4
 // CHECK:STDOUT:   %.addr3 = alloca i64, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !39
-// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !42
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %1, ptr %.addr1, align 8, !tbaa !15
 // CHECK:STDOUT:   store i32 %2, ptr %.addr2, align 4, !tbaa !8
-// CHECK:STDOUT:   store i64 %3, ptr %.addr3, align 8, !tbaa !44
-// CHECK:STDOUT:   %4 = load ptr, ptr %.addr, align 8, !tbaa !39
-// CHECK:STDOUT:   %5 = load i8, ptr %4, align 1, !tbaa !46
-// CHECK:STDOUT:   %6 = load ptr, ptr %.addr1, align 8, !tbaa !42
-// CHECK:STDOUT:   %7 = load i16, ptr %6, align 2, !tbaa !47
+// CHECK:STDOUT:   store i64 %3, ptr %.addr3, align 8, !tbaa !17
+// CHECK:STDOUT:   %4 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %5 = load i8, ptr %4, align 1, !tbaa !19
+// CHECK:STDOUT:   %6 = load ptr, ptr %.addr1, align 8, !tbaa !15
+// CHECK:STDOUT:   %7 = load i16, ptr %6, align 2, !tbaa !20
 // CHECK:STDOUT:   %8 = load i32, ptr %.addr2, align 4, !tbaa !8
-// CHECK:STDOUT:   %9 = load i64, ptr %.addr3, align 8, !tbaa !44
+// CHECK:STDOUT:   %9 = load i64, ptr %.addr3, align 8, !tbaa !17
 // CHECK:STDOUT:   call void @_Z13pass_unsignedhtjm(i8 noundef zeroext %5, i16 noundef zeroext %7, i32 noundef %8, i64 noundef %9)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z13pass_unsignedhtjm(i8 noundef zeroext, i16 noundef zeroext, i32 noundef, i64 noundef) #3
+// CHECK:STDOUT: declare void @_Z13pass_unsignedhtjm(i8 noundef zeroext, i16 noundef zeroext, i32 noundef, i64 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z10pass_shorts.carbon_thunk(ptr noundef %0) #2 {
+// CHECK:STDOUT: define dso_local void @_Z10pass_shorts.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !42
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !42
-// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !47
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %2 = load i16, ptr %1, align 2, !tbaa !20
 // CHECK:STDOUT:   call void @_Z10pass_shorts(i16 noundef signext %2)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z10pass_shorts(i16 noundef signext) #3
+// CHECK:STDOUT: declare void @_Z10pass_shorts(i16 noundef signext) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CMyF.Main() #2 !dbg !22 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc7_19.3.temp = alloca i8, align 1, !dbg !25
+// CHECK:STDOUT:   %.loc7_22.3.temp = alloca i16, align 2, !dbg !26
+// CHECK:STDOUT:   %.loc9_21.3.temp = alloca i8, align 1, !dbg !27
+// CHECK:STDOUT:   %.loc9_24.3.temp = alloca i16, align 2, !dbg !28
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_19.3.temp), !dbg !25
+// CHECK:STDOUT:   store i8 1, ptr %.loc7_19.3.temp, align 1, !dbg !25
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_22.3.temp), !dbg !26
+// CHECK:STDOUT:   store i16 2, ptr %.loc7_22.3.temp, align 2, !dbg !26
+// CHECK:STDOUT:   call void @_Z11pass_signedasil.carbon_thunk(ptr %.loc7_19.3.temp, ptr %.loc7_22.3.temp, i32 3, i64 4), !dbg !29
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_21.3.temp), !dbg !27
+// CHECK:STDOUT:   store i8 1, ptr %.loc9_21.3.temp, align 1, !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_24.3.temp), !dbg !28
+// CHECK:STDOUT:   store i16 2, ptr %.loc9_24.3.temp, align 2, !dbg !28
+// CHECK:STDOUT:   call void @_Z13pass_unsignedhtjm.carbon_thunk(ptr %.loc9_21.3.temp, ptr %.loc9_24.3.temp, i32 3, i64 4), !dbg !30
+// CHECK:STDOUT:   ret void, !dbg !31
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare i16 @_CMakeShort.Main()
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassShort.Main(i16 %a, ptr %b) #2 !dbg !32 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc17_18.1.temp = alloca i16, align 2, !dbg !40
+// CHECK:STDOUT:   %.loc18_18.3.temp = alloca i16, align 2, !dbg !41
+// CHECK:STDOUT:   %.loc19_18.2.temp = alloca i16, align 2, !dbg !42
+// CHECK:STDOUT:   %.loc20_28.3.temp = alloca i16, align 2, !dbg !43
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_18.1.temp), !dbg !40
+// CHECK:STDOUT:   store i16 %a, ptr %.loc17_18.1.temp, align 2, !dbg !40
+// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc17_18.1.temp), !dbg !44
+// CHECK:STDOUT:   %.loc18_18.2 = load i16, ptr %b, align 2, !dbg !41
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_18.3.temp), !dbg !41
+// CHECK:STDOUT:   store i16 %.loc18_18.2, ptr %.loc18_18.3.temp, align 2, !dbg !41
+// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc18_18.3.temp), !dbg !45
+// CHECK:STDOUT:   %.loc19_18.1 = load i16, ptr @_Cc.Main, align 2, !dbg !42
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_18.2.temp), !dbg !42
+// CHECK:STDOUT:   store i16 %.loc19_18.1, ptr %.loc19_18.2.temp, align 2, !dbg !42
+// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc19_18.2.temp), !dbg !46
+// CHECK:STDOUT:   %MakeShort.call = call i16 @_CMakeShort.Main(), !dbg !43
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_28.3.temp), !dbg !43
+// CHECK:STDOUT:   store i16 %MakeShort.call, ptr %.loc20_28.3.temp, align 2, !dbg !43
+// CHECK:STDOUT:   call void @_Z10pass_shorts.carbon_thunk(ptr %.loc20_28.3.temp), !dbg !47
+// CHECK:STDOUT:   ret void, !dbg !48
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 7, 6, 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -239,7 +239,7 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -248,43 +248,43 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "MyF", linkageName: "_CMyF.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 19, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 7, column: 22, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 9, column: 21, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 9, column: 24, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 9, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "PassShort", linkageName: "_CPassShort.Main", scope: null, file: !7, line: 16, type: !23, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !27)
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 omnipotent char", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"p1 short", !14, i64 0}
+// CHECK:STDOUT: !17 = !{!18, !18, i64 0}
+// CHECK:STDOUT: !18 = !{!"long", !10, i64 0}
+// CHECK:STDOUT: !19 = !{!10, !10, i64 0}
+// CHECK:STDOUT: !20 = !{!21, !21, i64 0}
+// CHECK:STDOUT: !21 = !{!"short", !10, i64 0}
+// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "MyF", linkageName: "_CMyF.Main", scope: null, file: !7, line: 6, type: !23, spFlags: DISPFlagDefinition, unit: !6)
 // CHECK:STDOUT: !23 = !DISubroutineType(types: !24)
-// CHECK:STDOUT: !24 = !{null, !25, !26}
-// CHECK:STDOUT: !25 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !27 = !{!28, !29}
-// CHECK:STDOUT: !28 = !DILocalVariable(arg: 1, scope: !22, type: !25)
-// CHECK:STDOUT: !29 = !DILocalVariable(arg: 2, scope: !22, type: !26)
-// CHECK:STDOUT: !30 = !DILocation(line: 17, column: 18, scope: !22)
-// CHECK:STDOUT: !31 = !DILocation(line: 18, column: 18, scope: !22)
-// CHECK:STDOUT: !32 = !DILocation(line: 19, column: 18, scope: !22)
-// CHECK:STDOUT: !33 = !DILocation(line: 20, column: 18, scope: !22)
-// CHECK:STDOUT: !34 = !DILocation(line: 17, column: 3, scope: !22)
-// CHECK:STDOUT: !35 = !DILocation(line: 18, column: 3, scope: !22)
-// CHECK:STDOUT: !36 = !DILocation(line: 19, column: 3, scope: !22)
-// CHECK:STDOUT: !37 = !DILocation(line: 20, column: 3, scope: !22)
-// CHECK:STDOUT: !38 = !DILocation(line: 16, column: 1, scope: !22)
-// CHECK:STDOUT: !39 = !{!40, !40, i64 0}
-// CHECK:STDOUT: !40 = !{!"p1 omnipotent char", !41, i64 0}
-// CHECK:STDOUT: !41 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !42 = !{!43, !43, i64 0}
-// CHECK:STDOUT: !43 = !{!"p1 short", !41, i64 0}
-// CHECK:STDOUT: !44 = !{!45, !45, i64 0}
-// CHECK:STDOUT: !45 = !{!"long", !10, i64 0}
-// CHECK:STDOUT: !46 = !{!10, !10, i64 0}
-// CHECK:STDOUT: !47 = !{!48, !48, i64 0}
-// CHECK:STDOUT: !48 = !{!"short", !10, i64 0}
+// CHECK:STDOUT: !24 = !{null}
+// CHECK:STDOUT: !25 = !DILocation(line: 7, column: 19, scope: !22)
+// CHECK:STDOUT: !26 = !DILocation(line: 7, column: 22, scope: !22)
+// CHECK:STDOUT: !27 = !DILocation(line: 9, column: 21, scope: !22)
+// CHECK:STDOUT: !28 = !DILocation(line: 9, column: 24, scope: !22)
+// CHECK:STDOUT: !29 = !DILocation(line: 7, column: 3, scope: !22)
+// CHECK:STDOUT: !30 = !DILocation(line: 9, column: 3, scope: !22)
+// CHECK:STDOUT: !31 = !DILocation(line: 6, column: 1, scope: !22)
+// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "PassShort", linkageName: "_CPassShort.Main", scope: null, file: !7, line: 16, type: !33, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !37)
+// CHECK:STDOUT: !33 = !DISubroutineType(types: !34)
+// CHECK:STDOUT: !34 = !{null, !35, !36}
+// CHECK:STDOUT: !35 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !36 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !37 = !{!38, !39}
+// CHECK:STDOUT: !38 = !DILocalVariable(arg: 1, scope: !32, type: !35)
+// CHECK:STDOUT: !39 = !DILocalVariable(arg: 2, scope: !32, type: !36)
+// CHECK:STDOUT: !40 = !DILocation(line: 17, column: 18, scope: !32)
+// CHECK:STDOUT: !41 = !DILocation(line: 18, column: 18, scope: !32)
+// CHECK:STDOUT: !42 = !DILocation(line: 19, column: 18, scope: !32)
+// CHECK:STDOUT: !43 = !DILocation(line: 20, column: 18, scope: !32)
+// CHECK:STDOUT: !44 = !DILocation(line: 17, column: 3, scope: !32)
+// CHECK:STDOUT: !45 = !DILocation(line: 18, column: 3, scope: !32)
+// CHECK:STDOUT: !46 = !DILocation(line: 19, column: 3, scope: !32)
+// CHECK:STDOUT: !47 = !DILocation(line: 20, column: 3, scope: !32)
+// CHECK:STDOUT: !48 = !DILocation(line: 16, column: 1, scope: !32)
 // CHECK:STDOUT: ; ModuleID = 'import_struct.carbon'
 // CHECK:STDOUT: source_filename = "import_struct.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -292,33 +292,15 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %struct.X = type { i32, i32, i32 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CTest.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %x.var = alloca [12 x i8], align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %x.var), !dbg !15
-// CHECK:STDOUT:   %.loc8_4.a = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 0, !dbg !16
-// CHECK:STDOUT:   store i32 1, ptr %.loc8_4.a, align 4, !dbg !16
-// CHECK:STDOUT:   %.loc9_4.b = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 4, !dbg !17
-// CHECK:STDOUT:   store i32 2, ptr %.loc9_4.b, align 4, !dbg !17
-// CHECK:STDOUT:   %.loc10_4.c = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 8, !dbg !18
-// CHECK:STDOUT:   store i32 3, ptr %.loc10_4.c, align 4, !dbg !18
-// CHECK:STDOUT:   call void @_Z11pass_struct1X.carbon_thunk(ptr %x.var), !dbg !19
-// CHECK:STDOUT:   ret void, !dbg !20
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_Z11pass_struct1X.carbon_thunk(ptr noundef %0) #2 {
+// CHECK:STDOUT: define dso_local void @_Z11pass_struct1X.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %struct.X, align 4
 // CHECK:STDOUT:   %agg.tmp.coerce = alloca { i64, i32 }, align 4
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !21
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %agg.tmp, ptr align 4 %1, i64 12, i1 false), !tbaa.struct !24
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %agg.tmp, ptr align 4 %1, i64 12, i1 false), !tbaa.struct !15
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %agg.tmp.coerce, ptr align 4 %agg.tmp, i64 12, i1 false)
 // CHECK:STDOUT:   %2 = getelementptr inbounds nuw { i64, i32 }, ptr %agg.tmp.coerce, i32 0, i32 0
 // CHECK:STDOUT:   %3 = load i64, ptr %2, align 4
@@ -328,19 +310,37 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z11pass_struct1X(i64, i32) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #3
+// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CTest.Main() #3 !dbg !16 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %x.var = alloca [12 x i8], align 1, !dbg !19
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %x.var), !dbg !19
+// CHECK:STDOUT:   %.loc8_4.a = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 0, !dbg !20
+// CHECK:STDOUT:   store i32 1, ptr %.loc8_4.a, align 4, !dbg !20
+// CHECK:STDOUT:   %.loc9_4.b = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 4, !dbg !21
+// CHECK:STDOUT:   store i32 2, ptr %.loc9_4.b, align 4, !dbg !21
+// CHECK:STDOUT:   %.loc10_4.c = getelementptr inbounds nuw [12 x i8], ptr %x.var, i32 0, i32 8, !dbg !22
+// CHECK:STDOUT:   store i32 3, ptr %.loc10_4.c, align 4, !dbg !22
+// CHECK:STDOUT:   call void @_Z11pass_struct1X.carbon_thunk(ptr %x.var), !dbg !23
+// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11pass_struct1X(i64, i32) #4
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 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 #0 = { 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 #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 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #3 = { nounwind }
+// CHECK:STDOUT: attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -349,7 +349,7 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -358,19 +358,19 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 8, column: 3, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 9, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 10, column: 3, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 11, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !21 = !{!22, !22, i64 0}
-// CHECK:STDOUT: !22 = !{!"p1 _ZTS1X", !23, i64 0}
-// CHECK:STDOUT: !23 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !24 = !{i64 0, i64 4, !8, i64 4, i64 4, !8, i64 8, i64 4, !8}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1X", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{i64 0, i64 4, !8, i64 4, i64 4, !8, i64 8, i64 4, !8}
+// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !7, line: 6, type: !17, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !17 = !DISubroutineType(types: !18)
+// CHECK:STDOUT: !18 = !{null}
+// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 3, scope: !16)
+// CHECK:STDOUT: !20 = !DILocation(line: 8, column: 3, scope: !16)
+// CHECK:STDOUT: !21 = !DILocation(line: 9, column: 3, scope: !16)
+// CHECK:STDOUT: !22 = !DILocation(line: 10, column: 3, scope: !16)
+// CHECK:STDOUT: !23 = !DILocation(line: 11, column: 3, scope: !16)
+// CHECK:STDOUT: !24 = !DILocation(line: 6, column: 1, scope: !16)
 // CHECK:STDOUT: ; ModuleID = 'import_class_with_nontrivial_copy.carbon'
 // CHECK:STDOUT: source_filename = "import_class_with_nontrivial_copy.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -378,66 +378,66 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %class.Y = type { i32, i32, i32 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassRefExpr.Main() #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z11pass_struct1Y.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %y.var = alloca [12 x i8], align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %y.var), !dbg !15
-// CHECK:STDOUT:   %.loc8_4.a = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 0, !dbg !16
-// CHECK:STDOUT:   store i32 1, ptr %.loc8_4.a, align 4, !dbg !16
-// CHECK:STDOUT:   %.loc9_4.b = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 4, !dbg !17
-// CHECK:STDOUT:   store i32 2, ptr %.loc9_4.b, align 4, !dbg !17
-// CHECK:STDOUT:   %.loc10_4.c = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 8, !dbg !18
-// CHECK:STDOUT:   store i32 3, ptr %.loc10_4.c, align 4, !dbg !18
-// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %y.var), !dbg !19
-// CHECK:STDOUT:   ret void, !dbg !20
+// CHECK:STDOUT:   %.addr = alloca ptr, align 8
+// CHECK:STDOUT:   %agg.tmp = alloca %class.Y, align 4
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_ZN1YC1ERKS_(ptr noundef nonnull align 4 dereferenceable(12) %agg.tmp, ptr noundef nonnull align 4 dereferenceable(12) %1)
+// CHECK:STDOUT:   call void @_Z11pass_struct1Y(ptr dead_on_return noundef %agg.tmp)
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_CMake.Main(ptr sret([12 x i8]))
+// CHECK:STDOUT: declare void @_Z11pass_struct1Y(ptr dead_on_return noundef) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_ZN1YC1ERKS_(ptr noundef nonnull align 4 dereferenceable(12), ptr noundef nonnull align 4 dereferenceable(12)) unnamed_addr #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassInitExpr.Main() #0 !dbg !21 {
+// CHECK:STDOUT: define void @_CPassRefExpr.Main() #2 !dbg !15 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc17_24.1.temp = alloca [12 x i8], align 1, !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_24.1.temp), !dbg !22
-// CHECK:STDOUT:   call void @_CMake.Main(ptr %.loc17_24.1.temp), !dbg !22
-// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %.loc17_24.1.temp), !dbg !23
-// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT:   %y.var = alloca [12 x i8], align 1, !dbg !18
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %y.var), !dbg !18
+// CHECK:STDOUT:   %.loc8_4.a = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 0, !dbg !19
+// CHECK:STDOUT:   store i32 1, ptr %.loc8_4.a, align 4, !dbg !19
+// CHECK:STDOUT:   %.loc9_4.b = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 4, !dbg !20
+// CHECK:STDOUT:   store i32 2, ptr %.loc9_4.b, align 4, !dbg !20
+// CHECK:STDOUT:   %.loc10_4.c = getelementptr inbounds nuw [12 x i8], ptr %y.var, i32 0, i32 8, !dbg !21
+// CHECK:STDOUT:   store i32 3, ptr %.loc10_4.c, align 4, !dbg !21
+// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %y.var), !dbg !22
+// CHECK:STDOUT:   ret void, !dbg !23
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_CMake.Main(ptr sret([12 x i8]))
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassValueExpr.Main(ptr %y) #0 !dbg !25 {
+// CHECK:STDOUT: define void @_CPassInitExpr.Main() #2 !dbg !24 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %y), !dbg !31
-// CHECK:STDOUT:   ret void, !dbg !32
+// CHECK:STDOUT:   %.loc17_24.1.temp = alloca [12 x i8], align 1, !dbg !25
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc17_24.1.temp), !dbg !25
+// CHECK:STDOUT:   call void @_CMake.Main(ptr %.loc17_24.1.temp), !dbg !25
+// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %.loc17_24.1.temp), !dbg !26
+// CHECK:STDOUT:   ret void, !dbg !27
 // 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 uwtable
-// CHECK:STDOUT: define dso_local void @_Z11pass_struct1Y.carbon_thunk(ptr noundef %0) #2 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassValueExpr.Main(ptr %y) #2 !dbg !28 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   %agg.tmp = alloca %class.Y, align 4
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !33
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !33
-// CHECK:STDOUT:   call void @_ZN1YC1ERKS_(ptr noundef nonnull align 4 dereferenceable(12) %agg.tmp, ptr noundef nonnull align 4 dereferenceable(12) %1)
-// CHECK:STDOUT:   call void @_Z11pass_struct1Y(ptr dead_on_return noundef %agg.tmp)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   call void @_Z11pass_struct1Y.carbon_thunk(ptr %y), !dbg !34
+// CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1YC1ERKS_(ptr noundef nonnull align 4 dereferenceable(12), ptr noundef nonnull align 4 dereferenceable(12)) unnamed_addr #3
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11pass_struct1Y(ptr dead_on_return noundef) #3
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -446,7 +446,7 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -455,27 +455,27 @@ fn PassValueExpr(y: Cpp.Y) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassRefExpr", linkageName: "_CPassRefExpr.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 8, column: 3, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 9, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 10, column: 3, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 11, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "PassInitExpr", linkageName: "_CPassInitExpr.Main", scope: null, file: !7, line: 16, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !22 = !DILocation(line: 17, column: 19, scope: !21)
-// CHECK:STDOUT: !23 = !DILocation(line: 17, column: 3, scope: !21)
-// CHECK:STDOUT: !24 = !DILocation(line: 16, column: 1, scope: !21)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "PassValueExpr", linkageName: "_CPassValueExpr.Main", scope: null, file: !7, line: 20, type: !26, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !29)
-// CHECK:STDOUT: !26 = !DISubroutineType(types: !27)
-// CHECK:STDOUT: !27 = !{null, !28}
-// CHECK:STDOUT: !28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !29 = !{!30}
-// CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !25, type: !28)
-// CHECK:STDOUT: !31 = !DILocation(line: 21, column: 3, scope: !25)
-// CHECK:STDOUT: !32 = !DILocation(line: 20, column: 1, scope: !25)
-// CHECK:STDOUT: !33 = !{!34, !34, i64 0}
-// CHECK:STDOUT: !34 = !{!"p1 _ZTS1Y", !35, i64 0}
-// CHECK:STDOUT: !35 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1Y", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "PassRefExpr", linkageName: "_CPassRefExpr.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{null}
+// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 3, scope: !15)
+// CHECK:STDOUT: !19 = !DILocation(line: 8, column: 3, scope: !15)
+// CHECK:STDOUT: !20 = !DILocation(line: 9, column: 3, scope: !15)
+// CHECK:STDOUT: !21 = !DILocation(line: 10, column: 3, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 11, column: 3, scope: !15)
+// CHECK:STDOUT: !23 = !DILocation(line: 6, column: 1, scope: !15)
+// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "PassInitExpr", linkageName: "_CPassInitExpr.Main", scope: null, file: !7, line: 16, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !25 = !DILocation(line: 17, column: 19, scope: !24)
+// CHECK:STDOUT: !26 = !DILocation(line: 17, column: 3, scope: !24)
+// CHECK:STDOUT: !27 = !DILocation(line: 16, column: 1, scope: !24)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "PassValueExpr", linkageName: "_CPassValueExpr.Main", scope: null, file: !7, line: 20, type: !29, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !32)
+// CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
+// CHECK:STDOUT: !30 = !{null, !31}
+// CHECK:STDOUT: !31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !32 = !{!33}
+// CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !28, type: !31)
+// CHECK:STDOUT: !34 = !DILocation(line: 21, column: 3, scope: !28)
+// CHECK:STDOUT: !35 = !DILocation(line: 20, column: 1, scope: !28)

+ 188 - 188
toolchain/lower/testdata/interop/cpp/pointer.carbon

@@ -95,62 +95,62 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassPtr.Main(ptr %p) #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z7TakePtrP1C(ptr %p), !dbg !18
-// CHECK:STDOUT:   ret void, !dbg !19
+// CHECK:STDOUT:   %.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci(ptr noundef %1, i32 noundef 0)
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z7TakePtrP1C(ptr)
+// CHECK:STDOUT: declare void @_Z16TakePtrWithThunkP1Ci(ptr noundef, i32 noundef) #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnPtr.Main() #0 !dbg !20 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local noundef ptr @_Z18ReturnPtrWithThunki.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnPtr.call = call ptr @_Z9ReturnPtrv(), !dbg !23
-// CHECK:STDOUT:   ret ptr %ReturnPtr.call, !dbg !24
+// CHECK:STDOUT:   %call = call noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef 0)
+// CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z9ReturnPtrv()
+// CHECK:STDOUT: declare noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassPtrWithThunk.Main(ptr %p) #0 !dbg !25 {
+// CHECK:STDOUT: define void @_CPassPtr.Main(ptr %p) #2 !dbg !15 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %p), !dbg !28
-// CHECK:STDOUT:   ret void, !dbg !29
+// CHECK:STDOUT:   call void @_Z7TakePtrP1C(ptr %p), !dbg !21
+// CHECK:STDOUT:   ret void, !dbg !22
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z7TakePtrP1C(ptr noundef) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnPtrWithThunk.Main() #0 !dbg !30 {
+// CHECK:STDOUT: define ptr @_CReturnPtr.Main() #2 !dbg !23 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnPtrWithThunk__carbon_thunk.call = call ptr @_Z18ReturnPtrWithThunki.carbon_thunk0(), !dbg !31
-// CHECK:STDOUT:   ret ptr %ReturnPtrWithThunk__carbon_thunk.call, !dbg !32
+// CHECK:STDOUT:   %ReturnPtr.call = call ptr @_Z9ReturnPtrv(), !dbg !26
+// CHECK:STDOUT:   ret ptr %ReturnPtr.call, !dbg !27
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr noundef %0) #1 {
+// CHECK:STDOUT: declare noundef ptr @_Z9ReturnPtrv() #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassPtrWithThunk.Main(ptr %p) #2 !dbg !28 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !33
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !33
-// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci(ptr noundef %1, i32 noundef 0)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %p), !dbg !31
+// CHECK:STDOUT:   ret void, !dbg !32
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z16TakePtrWithThunkP1Ci(ptr noundef, i32 noundef) #2
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef ptr @_Z18ReturnPtrWithThunki.carbon_thunk0() #1 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define ptr @_CReturnPtrWithThunk.Main() #2 !dbg !33 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %call = call noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef 0)
-// CHECK:STDOUT:   ret ptr %call
+// CHECK:STDOUT:   %ReturnPtrWithThunk__carbon_thunk.call = call ptr @_Z18ReturnPtrWithThunki.carbon_thunk0(), !dbg !34
+// CHECK:STDOUT:   ret ptr %ReturnPtrWithThunk__carbon_thunk.call, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef) #2
-// CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #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: attributes #0 = { 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 #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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -159,7 +159,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -168,148 +168,148 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassPtr", linkageName: "_CPassPtr.Main", scope: null, file: !7, line: 14, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 15, column: 3, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 14, column: 1, scope: !12)
-// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !7, line: 18, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
-// CHECK:STDOUT: !22 = !{!15}
-// CHECK:STDOUT: !23 = !DILocation(line: 19, column: 10, scope: !20)
-// CHECK:STDOUT: !24 = !DILocation(line: 19, column: 3, scope: !20)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !7, line: 22, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !26)
-// CHECK:STDOUT: !26 = !{!27}
-// CHECK:STDOUT: !27 = !DILocalVariable(arg: 1, scope: !25, type: !15)
-// CHECK:STDOUT: !28 = !DILocation(line: 23, column: 3, scope: !25)
-// CHECK:STDOUT: !29 = !DILocation(line: 22, column: 1, scope: !25)
-// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !7, line: 26, type: !21, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !31 = !DILocation(line: 27, column: 10, scope: !30)
-// CHECK:STDOUT: !32 = !DILocation(line: 27, column: 3, scope: !30)
-// CHECK:STDOUT: !33 = !{!34, !34, i64 0}
-// CHECK:STDOUT: !34 = !{!"p1 _ZTS1C", !35, i64 0}
-// CHECK:STDOUT: !35 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "PassPtr", linkageName: "_CPassPtr.Main", scope: null, file: !7, line: 14, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !19)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{null, !18}
+// CHECK:STDOUT: !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !19 = !{!20}
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !15, type: !18)
+// CHECK:STDOUT: !21 = !DILocation(line: 15, column: 3, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 14, column: 1, scope: !15)
+// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !7, line: 18, type: !24, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !24 = !DISubroutineType(types: !25)
+// CHECK:STDOUT: !25 = !{!18}
+// CHECK:STDOUT: !26 = !DILocation(line: 19, column: 10, scope: !23)
+// CHECK:STDOUT: !27 = !DILocation(line: 19, column: 3, scope: !23)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !7, line: 22, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !29)
+// CHECK:STDOUT: !29 = !{!30}
+// CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !28, type: !18)
+// CHECK:STDOUT: !31 = !DILocation(line: 23, column: 3, scope: !28)
+// CHECK:STDOUT: !32 = !DILocation(line: 22, column: 1, scope: !28)
+// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !7, line: 26, type: !24, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !34 = !DILocation(line: 27, column: 10, scope: !33)
+// CHECK:STDOUT: !35 = !DILocation(line: 27, column: 3, scope: !33)
 // CHECK:STDOUT: ; ModuleID = 'nullable.carbon'
 // CHECK:STDOUT: source_filename = "nullable.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr noundef %0) #0 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci(ptr noundef %1, i32 noundef 0)
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z16TakePtrWithThunkP1Ci(ptr noundef, i32 noundef) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local noundef ptr @_Z18ReturnPtrWithThunki.carbon_thunk0() #0 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %call = call noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef 0)
+// CHECK:STDOUT:   ret ptr %call
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassPtr.Main(ptr %_) #0 !dbg !12 {
+// CHECK:STDOUT: define void @_CPassPtr.Main(ptr %_) #2 !dbg !15 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   ret void, !dbg !18
+// CHECK:STDOUT:   ret void, !dbg !21
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassNonnullPtr.Main(ptr %p) #0 !dbg !19 {
+// CHECK:STDOUT: define void @_CPassNonnullPtr.Main(ptr %p) #2 !dbg !22 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc22_15.2.temp = alloca ptr, align 8, !dbg !22
-// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_15.2.temp), !dbg !22
-// CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc22_15.2.temp, align 8, !dbg !22
-// CHECK:STDOUT:   %.loc22_15.4 = load ptr, ptr %.loc22_15.2.temp, align 8, !dbg !22
-// CHECK:STDOUT:   call void @_Z7TakePtrP1C(ptr %.loc22_15.4), !dbg !23
-// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT:   %.loc22_15.2.temp = alloca ptr, align 8, !dbg !25
+// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !25
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_15.2.temp), !dbg !25
+// CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc22_15.2.temp, align 8, !dbg !25
+// CHECK:STDOUT:   %.loc22_15.4 = load ptr, ptr %.loc22_15.2.temp, align 8, !dbg !25
+// CHECK:STDOUT:   call void @_Z7TakePtrP1C(ptr %.loc22_15.4), !dbg !26
+// CHECK:STDOUT:   ret void, !dbg !27
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z7TakePtrP1C(ptr)
+// CHECK:STDOUT: declare void @_Z7TakePtrP1C(ptr noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnPtr.Main() #0 !dbg !25 {
+// CHECK:STDOUT: define ptr @_CReturnPtr.Main() #2 !dbg !28 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnPtr.call = call ptr @_Z9ReturnPtrv(), !dbg !28
-// CHECK:STDOUT:   ret ptr %ReturnPtr.call, !dbg !29
+// CHECK:STDOUT:   %ReturnPtr.call = call ptr @_Z9ReturnPtrv(), !dbg !31
+// CHECK:STDOUT:   ret ptr %ReturnPtr.call, !dbg !32
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z9ReturnPtrv()
+// CHECK:STDOUT: declare noundef ptr @_Z9ReturnPtrv() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassPtrWithThunk.Main(ptr %_) #0 !dbg !30 {
+// CHECK:STDOUT: define void @_CPassPtrWithThunk.Main(ptr %_) #2 !dbg !33 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   ret void, !dbg !33
+// CHECK:STDOUT:   ret void, !dbg !36
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassNonnullPtrWithThunk.Main(ptr %p) #0 !dbg !34 {
+// CHECK:STDOUT: define void @_CPassNonnullPtrWithThunk.Main(ptr %p) #2 !dbg !37 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc35_24.2.temp = alloca ptr, align 8, !dbg !37
-// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !37
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc35_24.2.temp), !dbg !37
-// CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc35_24.2.temp, align 8, !dbg !37
-// CHECK:STDOUT:   %.loc35_24.4 = load ptr, ptr %.loc35_24.2.temp, align 8, !dbg !37
-// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %.loc35_24.4), !dbg !38
-// CHECK:STDOUT:   ret void, !dbg !39
+// CHECK:STDOUT:   %.loc35_24.2.temp = alloca ptr, align 8, !dbg !40
+// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !40
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc35_24.2.temp), !dbg !40
+// CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc35_24.2.temp, align 8, !dbg !40
+// CHECK:STDOUT:   %.loc35_24.4 = load ptr, ptr %.loc35_24.2.temp, align 8, !dbg !40
+// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr %.loc35_24.4), !dbg !41
+// CHECK:STDOUT:   ret void, !dbg !42
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define ptr @_CReturnPtrWithThunk.Main() #0 !dbg !40 {
+// CHECK:STDOUT: define ptr @_CReturnPtrWithThunk.Main() #2 !dbg !43 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnPtrWithThunk__carbon_thunk.call = call ptr @_Z18ReturnPtrWithThunki.carbon_thunk0(), !dbg !41
-// CHECK:STDOUT:   ret ptr %ReturnPtrWithThunk__carbon_thunk.call, !dbg !42
+// CHECK:STDOUT:   %ReturnPtrWithThunk__carbon_thunk.call = call ptr @_Z18ReturnPtrWithThunki.carbon_thunk0(), !dbg !44
+// CHECK:STDOUT:   ret ptr %ReturnPtrWithThunk__carbon_thunk.call, !dbg !45
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %self) #0 !dbg !43 {
-// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self), !dbg !49
-// CHECK:STDOUT:   ret ptr %1, !dbg !50
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %self) #2 !dbg !46 {
+// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self), !dbg !52
+// CHECK:STDOUT:   ret ptr %1, !dbg !53
 // 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)) #3
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self) #0 !dbg !51 {
-// CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %self), !dbg !54
-// CHECK:STDOUT:   ret ptr %1, !dbg !55
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self) #2 !dbg !54 {
+// CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %self), !dbg !57
+// CHECK:STDOUT:   ret ptr %1, !dbg !58
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %value) #0 !dbg !56 {
-// CHECK:STDOUT:   %1 = call ptr @"_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655"(ptr %value), !dbg !59
-// CHECK:STDOUT:   ret ptr %1, !dbg !60
+// CHECK:STDOUT: define linkonce_odr ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %value) #2 !dbg !59 {
+// CHECK:STDOUT:   %1 = call ptr @"_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655"(ptr %value), !dbg !62
+// CHECK:STDOUT:   ret ptr %1, !dbg !63
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655"(ptr %self) #0 !dbg !61 {
-// CHECK:STDOUT:   %1 = alloca ptr, align 8, !dbg !64
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !64
-// CHECK:STDOUT:   store ptr %self, ptr %1, align 8, !dbg !65
-// CHECK:STDOUT:   %2 = load ptr, ptr %1, align 8, !dbg !66
-// CHECK:STDOUT:   ret ptr %2, !dbg !67
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z16TakePtrWithThunkP1Ci.carbon_thunk1(ptr noundef %0) #2 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !68
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !68
-// CHECK:STDOUT:   call void @_Z16TakePtrWithThunkP1Ci(ptr noundef %1, i32 noundef 0)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: define linkonce_odr ptr @"_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655"(ptr %self) #2 !dbg !64 {
+// CHECK:STDOUT:   %1 = alloca ptr, align 8, !dbg !67
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !67
+// CHECK:STDOUT:   store ptr %self, ptr %1, align 8, !dbg !68
+// CHECK:STDOUT:   %2 = load ptr, ptr %1, align 8, !dbg !69
+// CHECK:STDOUT:   ret ptr %2, !dbg !70
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z16TakePtrWithThunkP1Ci(ptr noundef, i32 noundef) #3
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef ptr @_Z18ReturnPtrWithThunki.carbon_thunk0() #2 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %call = call noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef 0)
-// CHECK:STDOUT:   ret ptr %call
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef ptr @_Z18ReturnPtrWithThunki(i32 noundef) #3
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41", { 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 2, 1 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -318,7 +318,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -327,62 +327,62 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassPtr", linkageName: "_CPassPtr.Main", scope: null, file: !7, line: 14, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 14, column: 1, scope: !12)
-// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "PassNonnullPtr", linkageName: "_CPassNonnullPtr.Main", scope: null, file: !7, line: 19, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !20)
-// CHECK:STDOUT: !20 = !{!21}
-// CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !19, type: !15)
-// CHECK:STDOUT: !22 = !DILocation(line: 22, column: 15, scope: !19)
-// CHECK:STDOUT: !23 = !DILocation(line: 22, column: 3, scope: !19)
-// CHECK:STDOUT: !24 = !DILocation(line: 19, column: 1, scope: !19)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !7, line: 25, type: !26, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !26 = !DISubroutineType(types: !27)
-// CHECK:STDOUT: !27 = !{!15}
-// CHECK:STDOUT: !28 = !DILocation(line: 26, column: 10, scope: !25)
-// CHECK:STDOUT: !29 = !DILocation(line: 26, column: 3, scope: !25)
-// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !7, line: 29, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !31)
-// CHECK:STDOUT: !31 = !{!32}
-// CHECK:STDOUT: !32 = !DILocalVariable(arg: 1, scope: !30, type: !15)
-// CHECK:STDOUT: !33 = !DILocation(line: 29, column: 1, scope: !30)
-// CHECK:STDOUT: !34 = distinct !DISubprogram(name: "PassNonnullPtrWithThunk", linkageName: "_CPassNonnullPtrWithThunk.Main", scope: null, file: !7, line: 34, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !35)
-// CHECK:STDOUT: !35 = !{!36}
-// CHECK:STDOUT: !36 = !DILocalVariable(arg: 1, scope: !34, type: !15)
-// CHECK:STDOUT: !37 = !DILocation(line: 35, column: 24, scope: !34)
-// CHECK:STDOUT: !38 = !DILocation(line: 35, column: 3, scope: !34)
-// CHECK:STDOUT: !39 = !DILocation(line: 34, column: 1, scope: !34)
-// CHECK:STDOUT: !40 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !7, line: 38, type: !26, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !41 = !DILocation(line: 39, column: 10, scope: !40)
-// CHECK:STDOUT: !42 = !DILocation(line: 39, column: 3, scope: !40)
-// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41", scope: null, file: !44, line: 93, type: !45, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !47)
-// CHECK:STDOUT: !44 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
-// CHECK:STDOUT: !45 = !DISubroutineType(types: !46)
-// CHECK:STDOUT: !46 = !{!15, !15}
-// CHECK:STDOUT: !47 = !{!48}
-// CHECK:STDOUT: !48 = !DILocalVariable(arg: 1, scope: !43, type: !15)
-// CHECK:STDOUT: !49 = !DILocation(line: 94, column: 12, scope: !43)
-// CHECK:STDOUT: !50 = !DILocation(line: 94, column: 5, scope: !43)
-// CHECK:STDOUT: !51 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb", scope: null, file: !44, line: 68, type: !45, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !52)
-// CHECK:STDOUT: !52 = !{!53}
-// CHECK:STDOUT: !53 = !DILocalVariable(arg: 1, scope: !51, type: !15)
-// CHECK:STDOUT: !54 = !DILocation(line: 69, column: 12, scope: !51)
-// CHECK:STDOUT: !55 = !DILocation(line: 69, column: 5, scope: !51)
-// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.ea71e3f17b6b4efb", scope: null, file: !44, line: 29, type: !45, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !57)
-// CHECK:STDOUT: !57 = !{!58}
-// CHECK:STDOUT: !58 = !DILocalVariable(arg: 1, scope: !56, type: !15)
-// CHECK:STDOUT: !59 = !DILocation(line: 30, column: 12, scope: !56)
-// CHECK:STDOUT: !60 = !DILocation(line: 30, column: 5, scope: !56)
-// CHECK:STDOUT: !61 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655", scope: null, file: !44, line: 138, type: !45, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !62)
-// CHECK:STDOUT: !62 = !{!63}
-// CHECK:STDOUT: !63 = !DILocalVariable(arg: 1, scope: !61, type: !15)
-// CHECK:STDOUT: !64 = !DILocation(line: 139, column: 14, scope: !61)
-// CHECK:STDOUT: !65 = !DILocation(line: 140, column: 5, scope: !61)
-// CHECK:STDOUT: !66 = !DILocation(line: 139, column: 18, scope: !61)
-// CHECK:STDOUT: !67 = !DILocation(line: 141, column: 5, scope: !61)
-// CHECK:STDOUT: !68 = !{!69, !69, i64 0}
-// CHECK:STDOUT: !69 = !{!"p1 _ZTS1C", !70, i64 0}
-// CHECK:STDOUT: !70 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "PassPtr", linkageName: "_CPassPtr.Main", scope: null, file: !7, line: 14, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !19)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{null, !18}
+// CHECK:STDOUT: !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !19 = !{!20}
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !15, type: !18)
+// CHECK:STDOUT: !21 = !DILocation(line: 14, column: 1, scope: !15)
+// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "PassNonnullPtr", linkageName: "_CPassNonnullPtr.Main", scope: null, file: !7, line: 19, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !23)
+// CHECK:STDOUT: !23 = !{!24}
+// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !22, type: !18)
+// CHECK:STDOUT: !25 = !DILocation(line: 22, column: 15, scope: !22)
+// CHECK:STDOUT: !26 = !DILocation(line: 22, column: 3, scope: !22)
+// CHECK:STDOUT: !27 = !DILocation(line: 19, column: 1, scope: !22)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "ReturnPtr", linkageName: "_CReturnPtr.Main", scope: null, file: !7, line: 25, type: !29, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
+// CHECK:STDOUT: !30 = !{!18}
+// CHECK:STDOUT: !31 = !DILocation(line: 26, column: 10, scope: !28)
+// CHECK:STDOUT: !32 = !DILocation(line: 26, column: 3, scope: !28)
+// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "PassPtrWithThunk", linkageName: "_CPassPtrWithThunk.Main", scope: null, file: !7, line: 29, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !34)
+// CHECK:STDOUT: !34 = !{!35}
+// CHECK:STDOUT: !35 = !DILocalVariable(arg: 1, scope: !33, type: !18)
+// CHECK:STDOUT: !36 = !DILocation(line: 29, column: 1, scope: !33)
+// CHECK:STDOUT: !37 = distinct !DISubprogram(name: "PassNonnullPtrWithThunk", linkageName: "_CPassNonnullPtrWithThunk.Main", scope: null, file: !7, line: 34, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !38)
+// CHECK:STDOUT: !38 = !{!39}
+// CHECK:STDOUT: !39 = !DILocalVariable(arg: 1, scope: !37, type: !18)
+// CHECK:STDOUT: !40 = !DILocation(line: 35, column: 24, scope: !37)
+// CHECK:STDOUT: !41 = !DILocation(line: 35, column: 3, scope: !37)
+// CHECK:STDOUT: !42 = !DILocation(line: 34, column: 1, scope: !37)
+// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !7, line: 38, type: !29, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !44 = !DILocation(line: 39, column: 10, scope: !43)
+// CHECK:STDOUT: !45 = !DILocation(line: 39, column: 3, scope: !43)
+// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41", scope: null, file: !47, line: 93, type: !48, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !50)
+// CHECK:STDOUT: !47 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
+// CHECK:STDOUT: !48 = !DISubroutineType(types: !49)
+// CHECK:STDOUT: !49 = !{!18, !18}
+// CHECK:STDOUT: !50 = !{!51}
+// CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !46, type: !18)
+// CHECK:STDOUT: !52 = !DILocation(line: 94, column: 12, scope: !46)
+// CHECK:STDOUT: !53 = !DILocation(line: 94, column: 5, scope: !46)
+// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb", scope: null, file: !47, line: 68, type: !48, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !55)
+// CHECK:STDOUT: !55 = !{!56}
+// CHECK:STDOUT: !56 = !DILocalVariable(arg: 1, scope: !54, type: !18)
+// CHECK:STDOUT: !57 = !DILocation(line: 69, column: 12, scope: !54)
+// CHECK:STDOUT: !58 = !DILocation(line: 69, column: 5, scope: !54)
+// CHECK:STDOUT: !59 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.Optional.Core.ea71e3f17b6b4efb", scope: null, file: !47, line: 29, type: !48, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !60)
+// CHECK:STDOUT: !60 = !{!61}
+// CHECK:STDOUT: !61 = !DILocalVariable(arg: 1, scope: !59, type: !18)
+// CHECK:STDOUT: !62 = !DILocation(line: 30, column: 12, scope: !59)
+// CHECK:STDOUT: !63 = !DILocation(line: 30, column: 5, scope: !59)
+// CHECK:STDOUT: !64 = distinct !DISubprogram(name: "Some", linkageName: "_CSome.e8f8f92d3d08d149:OptionalStorage.Core.f53db17714b9f655", scope: null, file: !47, line: 138, type: !48, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !65)
+// CHECK:STDOUT: !65 = !{!66}
+// CHECK:STDOUT: !66 = !DILocalVariable(arg: 1, scope: !64, type: !18)
+// CHECK:STDOUT: !67 = !DILocation(line: 139, column: 14, scope: !64)
+// CHECK:STDOUT: !68 = !DILocation(line: 140, column: 5, scope: !64)
+// CHECK:STDOUT: !69 = !DILocation(line: 139, column: 18, scope: !64)
+// CHECK:STDOUT: !70 = !DILocation(line: 141, column: 5, scope: !64)

+ 198 - 197
toolchain/lower/testdata/interop/cpp/reference.carbon

@@ -135,98 +135,98 @@ fn GetRefs() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @C.val.loc19_18.3 = internal constant {} zeroinitializer
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassRefs.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %c.var = alloca {}, align 8, !dbg !15
-// CHECK:STDOUT:   %.loc19_18.2.temp = alloca {}, align 8, !dbg !16
-// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !17
-// CHECK:STDOUT:   %.loc24_22.3.temp = alloca i32, align 4, !dbg !18
-// CHECK:STDOUT:   %.loc25_23.2.temp = alloca i32, align 4, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !15
-// CHECK:STDOUT:   call void @_Z8TakeCRefR1C(ptr %c.var), !dbg !20
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_18.2.temp), !dbg !16
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc19_18.2.temp, ptr align 1 @C.val.loc19_18.3, i64 0, i1 false), !dbg !16
-// CHECK:STDOUT:   call void @_Z9TakeCRRefO1C.carbon_thunk(ptr %.loc19_18.2.temp), !dbg !21
-// CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C.carbon_thunk(ptr %c.var), !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !17
-// CHECK:STDOUT:   call void @_Z10TakeIntRefRi(ptr %n.var), !dbg !23
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_22.3.temp), !dbg !18
-// CHECK:STDOUT:   store i32 42, ptr %.loc24_22.3.temp, align 4, !dbg !18
-// CHECK:STDOUT:   call void @_Z11TakeIntRRefOi.carbon_thunk(ptr %.loc24_22.3.temp), !dbg !24
-// CHECK:STDOUT:   %.loc25_23.1 = load i32, ptr %n.var, align 4, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_23.2.temp), !dbg !19
-// CHECK:STDOUT:   store i32 %.loc25_23.1, ptr %.loc25_23.2.temp, align 4, !dbg !19
-// CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi.carbon_thunk(ptr %.loc25_23.2.temp), !dbg !25
-// CHECK:STDOUT:   ret void, !dbg !26
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z8TakeCRefR1C(ptr)
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z10TakeIntRefRi(ptr)
-// 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: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z9TakeCRRefO1C.carbon_thunk(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z9TakeCRRefO1C.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !27
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z9TakeCRRefO1C(ptr noundef nonnull align 1 dereferenceable(1) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z9TakeCRRefO1C(ptr noundef nonnull align 1 dereferenceable(1)) #4
+// CHECK:STDOUT: declare void @_Z9TakeCRRefO1C(ptr noundef nonnull align 1 dereferenceable(1)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z13TakeConstCRefRK1C.carbon_thunk(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z13TakeConstCRefRK1C.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !27
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C(ptr noundef nonnull align 1 dereferenceable(1) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z13TakeConstCRefRK1C(ptr noundef nonnull align 1 dereferenceable(1)) #4
+// CHECK:STDOUT: declare void @_Z13TakeConstCRefRK1C(ptr noundef nonnull align 1 dereferenceable(1)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z11TakeIntRRefOi.carbon_thunk(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z11TakeIntRRefOi.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !30
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !30
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !15
 // CHECK:STDOUT:   call void @_Z11TakeIntRRefOi(ptr noundef nonnull align 4 dereferenceable(4) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11TakeIntRRefOi(ptr noundef nonnull align 4 dereferenceable(4)) #4
+// CHECK:STDOUT: declare void @_Z11TakeIntRRefOi(ptr noundef nonnull align 4 dereferenceable(4)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z15TakeConstIntRefRKi.carbon_thunk(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z15TakeConstIntRefRKi.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !30
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !30
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !15
 // CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi(ptr noundef nonnull align 4 dereferenceable(4) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z15TakeConstIntRefRKi(ptr noundef nonnull align 4 dereferenceable(4)) #4
+// CHECK:STDOUT: declare void @_Z15TakeConstIntRefRKi(ptr noundef nonnull align 4 dereferenceable(4)) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassRefs.Main() #2 !dbg !17 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %c.var = alloca {}, align 8, !dbg !20
+// CHECK:STDOUT:   %.loc19_18.2.temp = alloca {}, align 8, !dbg !21
+// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !22
+// CHECK:STDOUT:   %.loc24_22.3.temp = alloca i32, align 4, !dbg !23
+// CHECK:STDOUT:   %.loc25_23.2.temp = alloca i32, align 4, !dbg !24
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !20
+// CHECK:STDOUT:   call void @_Z8TakeCRefR1C(ptr %c.var), !dbg !25
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_18.2.temp), !dbg !21
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc19_18.2.temp, ptr align 1 @C.val.loc19_18.3, i64 0, i1 false), !dbg !21
+// CHECK:STDOUT:   call void @_Z9TakeCRRefO1C.carbon_thunk(ptr %.loc19_18.2.temp), !dbg !26
+// CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C.carbon_thunk(ptr %c.var), !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !22
+// CHECK:STDOUT:   call void @_Z10TakeIntRefRi(ptr %n.var), !dbg !28
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_22.3.temp), !dbg !23
+// CHECK:STDOUT:   store i32 42, ptr %.loc24_22.3.temp, align 4, !dbg !23
+// CHECK:STDOUT:   call void @_Z11TakeIntRRefOi.carbon_thunk(ptr %.loc24_22.3.temp), !dbg !29
+// CHECK:STDOUT:   %.loc25_23.1 = load i32, ptr %n.var, align 4, !dbg !24
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_23.2.temp), !dbg !24
+// CHECK:STDOUT:   store i32 %.loc25_23.1, ptr %.loc25_23.2.temp, align 4, !dbg !24
+// CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi.carbon_thunk(ptr %.loc25_23.2.temp), !dbg !30
+// CHECK:STDOUT:   ret void, !dbg !31
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z8TakeCRefR1C(ptr noundef nonnull align 1 dereferenceable(1)) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z10TakeIntRefRi(ptr noundef nonnull align 4 dereferenceable(4)) #1
+// 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:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// CHECK:STDOUT: attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -235,7 +235,7 @@ fn GetRefs() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -244,26 +244,26 @@ fn GetRefs() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassRefs", linkageName: "_CPassRefs.Main", scope: null, file: !7, line: 16, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 17, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 19, column: 17, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 22, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 24, column: 19, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 25, column: 23, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 18, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !DILocation(line: 19, column: 3, scope: !12)
-// CHECK:STDOUT: !22 = !DILocation(line: 20, column: 3, scope: !12)
-// CHECK:STDOUT: !23 = !DILocation(line: 23, column: 3, scope: !12)
-// CHECK:STDOUT: !24 = !DILocation(line: 24, column: 3, scope: !12)
-// CHECK:STDOUT: !25 = !DILocation(line: 25, column: 3, scope: !12)
-// CHECK:STDOUT: !26 = !DILocation(line: 16, column: 1, scope: !12)
-// CHECK:STDOUT: !27 = !{!28, !28, i64 0}
-// CHECK:STDOUT: !28 = !{!"p1 _ZTS1C", !29, i64 0}
-// CHECK:STDOUT: !29 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !30 = !{!31, !31, i64 0}
-// CHECK:STDOUT: !31 = !{!"p1 int", !29, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"p1 int", !14, i64 0}
+// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "PassRefs", linkageName: "_CPassRefs.Main", scope: null, file: !7, line: 16, type: !18, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
+// CHECK:STDOUT: !19 = !{null}
+// CHECK:STDOUT: !20 = !DILocation(line: 17, column: 3, scope: !17)
+// CHECK:STDOUT: !21 = !DILocation(line: 19, column: 17, scope: !17)
+// CHECK:STDOUT: !22 = !DILocation(line: 22, column: 3, scope: !17)
+// CHECK:STDOUT: !23 = !DILocation(line: 24, column: 19, scope: !17)
+// CHECK:STDOUT: !24 = !DILocation(line: 25, column: 23, scope: !17)
+// CHECK:STDOUT: !25 = !DILocation(line: 18, column: 3, scope: !17)
+// CHECK:STDOUT: !26 = !DILocation(line: 19, column: 3, scope: !17)
+// CHECK:STDOUT: !27 = !DILocation(line: 20, column: 3, scope: !17)
+// CHECK:STDOUT: !28 = !DILocation(line: 23, column: 3, scope: !17)
+// CHECK:STDOUT: !29 = !DILocation(line: 24, column: 3, scope: !17)
+// CHECK:STDOUT: !30 = !DILocation(line: 25, column: 3, scope: !17)
+// CHECK:STDOUT: !31 = !DILocation(line: 16, column: 1, scope: !17)
 // CHECK:STDOUT: ; ModuleID = 'pass_references_via_thunk.carbon'
 // CHECK:STDOUT: source_filename = "pass_references_via_thunk.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -273,124 +273,124 @@ fn GetRefs() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @C.val.loc20_18.3 = internal constant {} zeroinitializer
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassRefs.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %c.var = alloca {}, align 8, !dbg !15
-// CHECK:STDOUT:   %.loc20_18.2.temp = alloca {}, align 8, !dbg !16
-// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !17
-// CHECK:STDOUT:   %.loc25_22.3.temp = alloca i32, align 4, !dbg !18
-// CHECK:STDOUT:   %.loc26_23.2.temp = alloca i32, align 4, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !15
-// CHECK:STDOUT:   call void @_Z8TakeCRefR1C10ForceThunk.carbon_thunk1(ptr %c.var), !dbg !20
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_18.2.temp), !dbg !16
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc20_18.2.temp, ptr align 1 @C.val.loc20_18.3, i64 0, i1 false), !dbg !16
-// CHECK:STDOUT:   call void @_Z9TakeCRRefRK1C10ForceThunk.carbon_thunk1(ptr %.loc20_18.2.temp), !dbg !21
-// CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C10ForceThunk.carbon_thunk1(ptr %c.var), !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !17
-// CHECK:STDOUT:   call void @_Z10TakeIntRefRi10ForceThunk.carbon_thunk1(ptr %n.var), !dbg !23
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_22.3.temp), !dbg !18
-// CHECK:STDOUT:   store i32 42, ptr %.loc25_22.3.temp, align 4, !dbg !18
-// CHECK:STDOUT:   call void @_Z11TakeIntRRefOi10ForceThunk.carbon_thunk1(ptr %.loc25_22.3.temp), !dbg !24
-// CHECK:STDOUT:   %.loc26_23.1 = load i32, ptr %n.var, align 4, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc26_23.2.temp), !dbg !19
-// CHECK:STDOUT:   store i32 %.loc26_23.1, ptr %.loc26_23.2.temp, align 4, !dbg !19
-// CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi10ForceThunk.carbon_thunk1(ptr %.loc26_23.2.temp), !dbg !25
-// CHECK:STDOUT:   ret void, !dbg !26
-// 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: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z8TakeCRefR1C10ForceThunk.carbon_thunk1(ptr noundef nonnull align 1 dereferenceable(1) %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z8TakeCRefR1C10ForceThunk.carbon_thunk1(ptr noundef nonnull align 1 dereferenceable(1) %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !27, !nonnull !30
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12, !nonnull !15
 // CHECK:STDOUT:   call void @_Z8TakeCRefR1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z8TakeCRefR1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #4
+// CHECK:STDOUT: declare void @_Z8TakeCRefR1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z9TakeCRRefRK1C10ForceThunk.carbon_thunk1(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z9TakeCRRefRK1C10ForceThunk.carbon_thunk1(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !27
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z9TakeCRRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z9TakeCRRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #4
+// CHECK:STDOUT: declare void @_Z9TakeCRRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z13TakeConstCRefRK1C10ForceThunk.carbon_thunk1(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z13TakeConstCRefRK1C10ForceThunk.carbon_thunk1(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !27
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z13TakeConstCRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #4
+// CHECK:STDOUT: declare void @_Z13TakeConstCRefRK1C10ForceThunk(ptr noundef nonnull align 1 dereferenceable(1)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z10TakeIntRefRi10ForceThunk.carbon_thunk1(ptr noundef nonnull align 4 dereferenceable(4) %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z10TakeIntRefRi10ForceThunk.carbon_thunk1(ptr noundef nonnull align 4 dereferenceable(4) %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !31
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !31, !nonnull !30, !align !33
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !16, !nonnull !15, !align !18
 // CHECK:STDOUT:   call void @_Z10TakeIntRefRi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z10TakeIntRefRi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #4
+// CHECK:STDOUT: declare void @_Z10TakeIntRefRi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z11TakeIntRRefOi10ForceThunk.carbon_thunk1(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z11TakeIntRRefOi10ForceThunk.carbon_thunk1(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !31
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !31
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !16
 // CHECK:STDOUT:   call void @_Z11TakeIntRRefOi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z11TakeIntRRefOi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #4
+// CHECK:STDOUT: declare void @_Z11TakeIntRRefOi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z15TakeConstIntRefRKi10ForceThunk.carbon_thunk1(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z15TakeConstIntRefRKi10ForceThunk.carbon_thunk1(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !31
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !31
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !16
 // CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4) %1)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z15TakeConstIntRefRKi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #4
+// CHECK:STDOUT: declare void @_Z15TakeConstIntRefRKi10ForceThunk(ptr noundef nonnull align 4 dereferenceable(4)) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassRefs.Main() #2 !dbg !19 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %c.var = alloca {}, align 8, !dbg !22
+// CHECK:STDOUT:   %.loc20_18.2.temp = alloca {}, align 8, !dbg !23
+// CHECK:STDOUT:   %n.var = alloca i32, align 4, !dbg !24
+// CHECK:STDOUT:   %.loc25_22.3.temp = alloca i32, align 4, !dbg !25
+// CHECK:STDOUT:   %.loc26_23.2.temp = alloca i32, align 4, !dbg !26
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !22
+// CHECK:STDOUT:   call void @_Z8TakeCRefR1C10ForceThunk.carbon_thunk1(ptr %c.var), !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_18.2.temp), !dbg !23
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc20_18.2.temp, ptr align 1 @C.val.loc20_18.3, i64 0, i1 false), !dbg !23
+// CHECK:STDOUT:   call void @_Z9TakeCRRefRK1C10ForceThunk.carbon_thunk1(ptr %.loc20_18.2.temp), !dbg !28
+// CHECK:STDOUT:   call void @_Z13TakeConstCRefRK1C10ForceThunk.carbon_thunk1(ptr %c.var), !dbg !29
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %n.var), !dbg !24
+// CHECK:STDOUT:   call void @_Z10TakeIntRefRi10ForceThunk.carbon_thunk1(ptr %n.var), !dbg !30
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_22.3.temp), !dbg !25
+// CHECK:STDOUT:   store i32 42, ptr %.loc25_22.3.temp, align 4, !dbg !25
+// CHECK:STDOUT:   call void @_Z11TakeIntRRefOi10ForceThunk.carbon_thunk1(ptr %.loc25_22.3.temp), !dbg !31
+// CHECK:STDOUT:   %.loc26_23.1 = load i32, ptr %n.var, align 4, !dbg !26
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc26_23.2.temp), !dbg !26
+// CHECK:STDOUT:   store i32 %.loc26_23.1, ptr %.loc26_23.2.temp, align 4, !dbg !26
+// CHECK:STDOUT:   call void @_Z15TakeConstIntRefRKi10ForceThunk.carbon_thunk1(ptr %.loc26_23.2.temp), !dbg !32
+// CHECK:STDOUT:   ret void, !dbg !33
+// 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:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// CHECK:STDOUT: attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -399,7 +399,7 @@ fn GetRefs() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -408,28 +408,28 @@ fn GetRefs() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassRefs", linkageName: "_CPassRefs.Main", scope: null, file: !7, line: 17, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 18, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 20, column: 17, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 23, column: 3, scope: !12)
-// CHECK:STDOUT: !18 = !DILocation(line: 25, column: 19, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 26, column: 23, scope: !12)
-// CHECK:STDOUT: !20 = !DILocation(line: 19, column: 3, scope: !12)
-// CHECK:STDOUT: !21 = !DILocation(line: 20, column: 3, scope: !12)
-// CHECK:STDOUT: !22 = !DILocation(line: 21, column: 3, scope: !12)
-// CHECK:STDOUT: !23 = !DILocation(line: 24, column: 3, scope: !12)
-// CHECK:STDOUT: !24 = !DILocation(line: 25, column: 3, scope: !12)
-// CHECK:STDOUT: !25 = !DILocation(line: 26, column: 3, scope: !12)
-// CHECK:STDOUT: !26 = !DILocation(line: 17, column: 1, scope: !12)
-// CHECK:STDOUT: !27 = !{!28, !28, i64 0}
-// CHECK:STDOUT: !28 = !{!"p1 _ZTS1C", !29, i64 0}
-// CHECK:STDOUT: !29 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !30 = !{}
-// CHECK:STDOUT: !31 = !{!32, !32, i64 0}
-// CHECK:STDOUT: !32 = !{!"p1 int", !29, i64 0}
-// CHECK:STDOUT: !33 = !{i64 4}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{}
+// CHECK:STDOUT: !16 = !{!17, !17, i64 0}
+// CHECK:STDOUT: !17 = !{!"p1 int", !14, i64 0}
+// CHECK:STDOUT: !18 = !{i64 4}
+// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "PassRefs", linkageName: "_CPassRefs.Main", scope: null, file: !7, line: 17, type: !20, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
+// CHECK:STDOUT: !21 = !{null}
+// CHECK:STDOUT: !22 = !DILocation(line: 18, column: 3, scope: !19)
+// CHECK:STDOUT: !23 = !DILocation(line: 20, column: 17, scope: !19)
+// CHECK:STDOUT: !24 = !DILocation(line: 23, column: 3, scope: !19)
+// CHECK:STDOUT: !25 = !DILocation(line: 25, column: 19, scope: !19)
+// CHECK:STDOUT: !26 = !DILocation(line: 26, column: 23, scope: !19)
+// CHECK:STDOUT: !27 = !DILocation(line: 19, column: 3, scope: !19)
+// CHECK:STDOUT: !28 = !DILocation(line: 20, column: 3, scope: !19)
+// CHECK:STDOUT: !29 = !DILocation(line: 21, column: 3, scope: !19)
+// CHECK:STDOUT: !30 = !DILocation(line: 24, column: 3, scope: !19)
+// CHECK:STDOUT: !31 = !DILocation(line: 25, column: 3, scope: !19)
+// CHECK:STDOUT: !32 = !DILocation(line: 26, column: 3, scope: !19)
+// CHECK:STDOUT: !33 = !DILocation(line: 17, column: 1, scope: !19)
 // CHECK:STDOUT: ; ModuleID = 'return_references.carbon'
 // CHECK:STDOUT: source_filename = "return_references.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -447,19 +447,20 @@ fn GetRefs() {
 // CHECK:STDOUT:   ret void, !dbg !21
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z10ReturnCRefv()
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRefv() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z11ReturnCRRefv()
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRefv() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z15ReturnConstCRefv()
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRefv() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z12ReturnIntRefv()
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRefv() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z13ReturnIntRRefv()
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRefv() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z17ReturnConstIntRefv()
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRefv() #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -468,7 +469,7 @@ fn GetRefs() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -494,81 +495,81 @@ fn GetRefs() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %class.ForceThunk = type { i8 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CGetRefs.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnCRef__carbon_thunk.call = call ptr @_Z10ReturnCRef10ForceThunk.carbon_thunk0(), !dbg !15
-// CHECK:STDOUT:   %ReturnCRRef__carbon_thunk.call = call ptr @_Z11ReturnCRRef10ForceThunk.carbon_thunk0(), !dbg !16
-// CHECK:STDOUT:   %ReturnConstCRef__carbon_thunk.call = call ptr @_Z15ReturnConstCRef10ForceThunk.carbon_thunk0(), !dbg !17
-// CHECK:STDOUT:   %ReturnIntRef__carbon_thunk.call = call ptr @_Z12ReturnIntRef10ForceThunk.carbon_thunk0(), !dbg !18
-// CHECK:STDOUT:   %ReturnIntRRef__carbon_thunk.call = call ptr @_Z13ReturnIntRRef10ForceThunk.carbon_thunk0(), !dbg !19
-// CHECK:STDOUT:   %ReturnConstIntRef__carbon_thunk.call = call ptr @_Z17ReturnConstIntRef10ForceThunk.carbon_thunk0(), !dbg !20
-// CHECK:STDOUT:   ret void, !dbg !21
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z10ReturnCRef10ForceThunk() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z11ReturnCRRef10ForceThunk() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 1 dereferenceable(1) ptr @_Z15ReturnConstCRef10ForceThunk() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z12ReturnIntRef10ForceThunk() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z13ReturnIntRRef10ForceThunk() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRef10ForceThunk.carbon_thunk0() #1 {
+// CHECK:STDOUT: define dso_local noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRef10ForceThunk.carbon_thunk0() #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %agg.tmp = alloca %class.ForceThunk, align 1
 // CHECK:STDOUT:   %call = call noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRef10ForceThunk()
 // CHECK:STDOUT:   ret ptr %call
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRef10ForceThunk() #2
+// CHECK:STDOUT: declare noundef nonnull align 4 dereferenceable(4) ptr @_Z17ReturnConstIntRef10ForceThunk() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CGetRefs.Main() #2 !dbg !12 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %ReturnCRef__carbon_thunk.call = call ptr @_Z10ReturnCRef10ForceThunk.carbon_thunk0(), !dbg !15
+// CHECK:STDOUT:   %ReturnCRRef__carbon_thunk.call = call ptr @_Z11ReturnCRRef10ForceThunk.carbon_thunk0(), !dbg !16
+// CHECK:STDOUT:   %ReturnConstCRef__carbon_thunk.call = call ptr @_Z15ReturnConstCRef10ForceThunk.carbon_thunk0(), !dbg !17
+// CHECK:STDOUT:   %ReturnIntRef__carbon_thunk.call = call ptr @_Z12ReturnIntRef10ForceThunk.carbon_thunk0(), !dbg !18
+// CHECK:STDOUT:   %ReturnIntRRef__carbon_thunk.call = call ptr @_Z13ReturnIntRRef10ForceThunk.carbon_thunk0(), !dbg !19
+// CHECK:STDOUT:   %ReturnConstIntRef__carbon_thunk.call = call ptr @_Z17ReturnConstIntRef10ForceThunk.carbon_thunk0(), !dbg !20
+// CHECK:STDOUT:   ret void, !dbg !21
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { 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 #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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -577,7 +578,7 @@ fn GetRefs() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)

+ 350 - 347
toolchain/lower/testdata/interop/cpp/return.carbon

@@ -117,232 +117,232 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i8 @_CGetU8.Main() #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z8ReturnU8v.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc6_40.1.temp = alloca i8, align 1, !dbg !16
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc6_40.1.temp), !dbg !16
-// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc6_40.1.temp), !dbg !16
-// CHECK:STDOUT:   %.loc6_40.2 = load i8, ptr %.loc6_40.1.temp, align 1, !dbg !16
-// CHECK:STDOUT:   ret i8 %.loc6_40.2, !dbg !17
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %call = call noundef zeroext i8 @_Z8ReturnU8v()
+// CHECK:STDOUT:   store i8 %call, ptr %0, align 1, !tbaa !15
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i16 @_CGetU16.Main() #0 !dbg !18 {
+// CHECK:STDOUT: declare noundef zeroext i8 @_Z8ReturnU8v() #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z9ReturnU16v.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc7_43.1.temp = alloca i16, align 2, !dbg !22
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_43.1.temp), !dbg !22
-// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc7_43.1.temp), !dbg !22
-// CHECK:STDOUT:   %.loc7_43.2 = load i16, ptr %.loc7_43.1.temp, align 2, !dbg !22
-// CHECK:STDOUT:   ret i16 %.loc7_43.2, !dbg !23
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %call = call noundef zeroext i16 @_Z9ReturnU16v()
+// CHECK:STDOUT:   store i16 %call, ptr %0, align 2, !tbaa !18
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CGetU32.Main() #0 !dbg !24 {
+// CHECK:STDOUT: declare noundef zeroext i16 @_Z9ReturnU16v() #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z8ReturnI8v.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !28
-// CHECK:STDOUT:   ret i32 %ReturnU32.call, !dbg !29
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %call = call noundef signext i8 @_Z8ReturnI8v()
+// CHECK:STDOUT:   store i8 %call, ptr %0, align 1, !tbaa !15
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare i32 @_Z9ReturnU32v()
+// CHECK:STDOUT: declare noundef signext i8 @_Z8ReturnI8v() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i64 @_CGetU64.Main() #0 !dbg !30 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z9ReturnI16v.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !34
-// CHECK:STDOUT:   ret i64 %ReturnU64.call, !dbg !35
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !16
+// CHECK:STDOUT:   %call = call noundef signext i16 @_Z9ReturnI16v()
+// CHECK:STDOUT:   store i16 %call, ptr %0, align 2, !tbaa !18
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare i64 @_Z9ReturnU64v()
+// CHECK:STDOUT: declare noundef signext i16 @_Z9ReturnI16v() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i8 @_CGetI8.Main() #0 !dbg !36 {
+// CHECK:STDOUT: define i8 @_CGetU8.Main() #2 !dbg !20 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc11_40.1.temp = alloca i8, align 1, !dbg !40
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc11_40.1.temp), !dbg !40
-// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc11_40.1.temp), !dbg !40
-// CHECK:STDOUT:   %.loc11_40.2 = load i8, ptr %.loc11_40.1.temp, align 1, !dbg !40
-// CHECK:STDOUT:   ret i8 %.loc11_40.2, !dbg !41
+// CHECK:STDOUT:   %.loc6_40.1.temp = alloca i8, align 1, !dbg !24
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc6_40.1.temp), !dbg !24
+// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc6_40.1.temp), !dbg !24
+// CHECK:STDOUT:   %.loc6_40.2 = load i8, ptr %.loc6_40.1.temp, align 1, !dbg !24
+// CHECK:STDOUT:   ret i8 %.loc6_40.2, !dbg !25
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i16 @_CGetI16.Main() #0 !dbg !42 {
+// CHECK:STDOUT: define i16 @_CGetU16.Main() #2 !dbg !26 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc12_43.1.temp = alloca i16, align 2, !dbg !46
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_43.1.temp), !dbg !46
-// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc12_43.1.temp), !dbg !46
-// CHECK:STDOUT:   %.loc12_43.2 = load i16, ptr %.loc12_43.1.temp, align 2, !dbg !46
-// CHECK:STDOUT:   ret i16 %.loc12_43.2, !dbg !47
+// CHECK:STDOUT:   %.loc7_43.1.temp = alloca i16, align 2, !dbg !30
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_43.1.temp), !dbg !30
+// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc7_43.1.temp), !dbg !30
+// CHECK:STDOUT:   %.loc7_43.2 = load i16, ptr %.loc7_43.1.temp, align 2, !dbg !30
+// CHECK:STDOUT:   ret i16 %.loc7_43.2, !dbg !31
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CGetI32.Main() #0 !dbg !48 {
+// CHECK:STDOUT: define i32 @_CGetU32.Main() #2 !dbg !32 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !52
-// CHECK:STDOUT:   ret i32 %ReturnI32.call, !dbg !53
+// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !36
+// CHECK:STDOUT:   ret i32 %ReturnU32.call, !dbg !37
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare i32 @_Z9ReturnI32v()
+// CHECK:STDOUT: declare noundef i32 @_Z9ReturnU32v() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i64 @_CGetI64.Main() #0 !dbg !54 {
+// CHECK:STDOUT: define i64 @_CGetU64.Main() #2 !dbg !38 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !58
-// CHECK:STDOUT:   ret i64 %ReturnI64.call, !dbg !59
+// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !42
+// CHECK:STDOUT:   ret i64 %ReturnU64.call, !dbg !43
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare i64 @_Z9ReturnI64v()
-// CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_CUse.Main(i8, i16, i32, i64, i8, i16, i32, i64)
+// CHECK:STDOUT: declare noundef i64 @_Z9ReturnU64v() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CLets.Main() #0 !dbg !60 {
+// CHECK:STDOUT: define i8 @_CGetI8.Main() #2 !dbg !44 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc19_32.1.temp = alloca i8, align 1, !dbg !63
-// CHECK:STDOUT:   %.loc20_35.1.temp = alloca i16, align 2, !dbg !64
-// CHECK:STDOUT:   %.loc24_32.1.temp = alloca i8, align 1, !dbg !65
-// CHECK:STDOUT:   %.loc25_35.1.temp = alloca i16, align 2, !dbg !66
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_32.1.temp), !dbg !63
-// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc19_32.1.temp), !dbg !63
-// CHECK:STDOUT:   %.loc19_32.2 = load i8, ptr %.loc19_32.1.temp, align 1, !dbg !63
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_35.1.temp), !dbg !64
-// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc20_35.1.temp), !dbg !64
-// CHECK:STDOUT:   %.loc20_35.2 = load i16, ptr %.loc20_35.1.temp, align 2, !dbg !64
-// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !67
-// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !68
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_32.1.temp), !dbg !65
-// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc24_32.1.temp), !dbg !65
-// CHECK:STDOUT:   %.loc24_32.2 = load i8, ptr %.loc24_32.1.temp, align 1, !dbg !65
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_35.1.temp), !dbg !66
-// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc25_35.1.temp), !dbg !66
-// CHECK:STDOUT:   %.loc25_35.2 = load i16, ptr %.loc25_35.1.temp, align 2, !dbg !66
-// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !69
-// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !70
-// CHECK:STDOUT:   call void @_CUse.Main(i8 %.loc19_32.2, i16 %.loc20_35.2, i32 %ReturnU32.call, i64 %ReturnU64.call, i8 %.loc24_32.2, i16 %.loc25_35.2, i32 %ReturnI32.call, i64 %ReturnI64.call), !dbg !71
-// CHECK:STDOUT:   ret void, !dbg !72
+// CHECK:STDOUT:   %.loc11_40.1.temp = alloca i8, align 1, !dbg !48
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc11_40.1.temp), !dbg !48
+// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc11_40.1.temp), !dbg !48
+// CHECK:STDOUT:   %.loc11_40.2 = load i8, ptr %.loc11_40.1.temp, align 1, !dbg !48
+// CHECK:STDOUT:   ret i8 %.loc11_40.2, !dbg !49
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CVars.Main() #0 !dbg !73 {
+// CHECK:STDOUT: define i16 @_CGetI16.Main() #2 !dbg !50 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %my_u8.var = alloca i8, align 1, !dbg !74
-// CHECK:STDOUT:   %.loc33_32.1.temp = alloca i8, align 1, !dbg !75
-// CHECK:STDOUT:   %my_u16.var = alloca i16, align 2, !dbg !76
-// CHECK:STDOUT:   %.loc34_35.1.temp = alloca i16, align 2, !dbg !77
-// CHECK:STDOUT:   %my_u32.var = alloca i32, align 4, !dbg !78
-// CHECK:STDOUT:   %my_u64.var = alloca i64, align 8, !dbg !79
-// CHECK:STDOUT:   %my_i8.var = alloca i8, align 1, !dbg !80
-// CHECK:STDOUT:   %.loc38_32.1.temp = alloca i8, align 1, !dbg !81
-// CHECK:STDOUT:   %my_i16.var = alloca i16, align 2, !dbg !82
-// CHECK:STDOUT:   %.loc39_35.1.temp = alloca i16, align 2, !dbg !83
-// CHECK:STDOUT:   %my_i32.var = alloca i32, align 4, !dbg !84
-// CHECK:STDOUT:   %my_i64.var = alloca i64, align 8, !dbg !85
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u8.var), !dbg !74
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc33_32.1.temp), !dbg !75
-// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc33_32.1.temp), !dbg !75
-// CHECK:STDOUT:   %.loc33_32.2 = load i8, ptr %.loc33_32.1.temp, align 1, !dbg !75
-// CHECK:STDOUT:   store i8 %.loc33_32.2, ptr %my_u8.var, align 1, !dbg !74
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u16.var), !dbg !76
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc34_35.1.temp), !dbg !77
-// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc34_35.1.temp), !dbg !77
-// CHECK:STDOUT:   %.loc34_35.2 = load i16, ptr %.loc34_35.1.temp, align 2, !dbg !77
-// CHECK:STDOUT:   store i16 %.loc34_35.2, ptr %my_u16.var, align 2, !dbg !76
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u32.var), !dbg !78
-// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !86
-// CHECK:STDOUT:   store i32 %ReturnU32.call, ptr %my_u32.var, align 4, !dbg !78
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u64.var), !dbg !79
-// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !87
-// CHECK:STDOUT:   store i64 %ReturnU64.call, ptr %my_u64.var, align 4, !dbg !79
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i8.var), !dbg !80
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc38_32.1.temp), !dbg !81
-// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc38_32.1.temp), !dbg !81
-// CHECK:STDOUT:   %.loc38_32.2 = load i8, ptr %.loc38_32.1.temp, align 1, !dbg !81
-// CHECK:STDOUT:   store i8 %.loc38_32.2, ptr %my_i8.var, align 1, !dbg !80
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i16.var), !dbg !82
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc39_35.1.temp), !dbg !83
-// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc39_35.1.temp), !dbg !83
-// CHECK:STDOUT:   %.loc39_35.2 = load i16, ptr %.loc39_35.1.temp, align 2, !dbg !83
-// CHECK:STDOUT:   store i16 %.loc39_35.2, ptr %my_i16.var, align 2, !dbg !82
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i32.var), !dbg !84
-// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !88
-// CHECK:STDOUT:   store i32 %ReturnI32.call, ptr %my_i32.var, align 4, !dbg !84
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i64.var), !dbg !85
-// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !89
-// CHECK:STDOUT:   store i64 %ReturnI64.call, ptr %my_i64.var, align 4, !dbg !85
-// CHECK:STDOUT:   %.loc43_7 = load i8, ptr %my_u8.var, align 1, !dbg !90
-// CHECK:STDOUT:   %.loc43_14 = load i16, ptr %my_u16.var, align 2, !dbg !91
-// CHECK:STDOUT:   %.loc43_22 = load i32, ptr %my_u32.var, align 4, !dbg !92
-// CHECK:STDOUT:   %.loc43_30 = load i64, ptr %my_u64.var, align 4, !dbg !93
-// CHECK:STDOUT:   %.loc43_38 = load i8, ptr %my_i8.var, align 1, !dbg !94
-// CHECK:STDOUT:   %.loc43_45 = load i16, ptr %my_i16.var, align 2, !dbg !95
-// CHECK:STDOUT:   %.loc43_53 = load i32, ptr %my_i32.var, align 4, !dbg !96
-// CHECK:STDOUT:   %.loc43_61 = load i64, ptr %my_i64.var, align 4, !dbg !97
-// CHECK:STDOUT:   call void @_CUse.Main(i8 %.loc43_7, i16 %.loc43_14, i32 %.loc43_22, i64 %.loc43_30, i8 %.loc43_38, i16 %.loc43_45, i32 %.loc43_53, i64 %.loc43_61), !dbg !98
-// CHECK:STDOUT:   ret void, !dbg !99
+// CHECK:STDOUT:   %.loc12_43.1.temp = alloca i16, align 2, !dbg !54
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_43.1.temp), !dbg !54
+// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc12_43.1.temp), !dbg !54
+// CHECK:STDOUT:   %.loc12_43.2 = load i16, ptr %.loc12_43.1.temp, align 2, !dbg !54
+// CHECK:STDOUT:   ret i16 %.loc12_43.2, !dbg !55
 // 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 uwtable
-// CHECK:STDOUT: define dso_local void @_Z8ReturnU8v.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CGetI32.Main() #2 !dbg !56 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !100
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !100
-// CHECK:STDOUT:   %call = call noundef zeroext i8 @_Z8ReturnU8v()
-// CHECK:STDOUT:   store i8 %call, ptr %0, align 1, !tbaa !103
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !60
+// CHECK:STDOUT:   ret i32 %ReturnI32.call, !dbg !61
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef zeroext i8 @_Z8ReturnU8v() #3
+// CHECK:STDOUT: declare noundef i32 @_Z9ReturnI32v() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z9ReturnU16v.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i64 @_CGetI64.Main() #2 !dbg !62 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !104
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !104
-// CHECK:STDOUT:   %call = call noundef zeroext i16 @_Z9ReturnU16v()
-// CHECK:STDOUT:   store i16 %call, ptr %0, align 2, !tbaa !106
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !66
+// CHECK:STDOUT:   ret i64 %ReturnI64.call, !dbg !67
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef zeroext i16 @_Z9ReturnU16v() #3
+// CHECK:STDOUT: declare noundef i64 @_Z9ReturnI64v() #1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z8ReturnI8v.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: declare void @_CUse.Main(i8, i16, i32, i64, i8, i16, i32, i64)
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CLets.Main() #2 !dbg !68 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !100
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !100
-// CHECK:STDOUT:   %call = call noundef signext i8 @_Z8ReturnI8v()
-// CHECK:STDOUT:   store i8 %call, ptr %0, align 1, !tbaa !103
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %.loc19_32.1.temp = alloca i8, align 1, !dbg !71
+// CHECK:STDOUT:   %.loc20_35.1.temp = alloca i16, align 2, !dbg !72
+// CHECK:STDOUT:   %.loc24_32.1.temp = alloca i8, align 1, !dbg !73
+// CHECK:STDOUT:   %.loc25_35.1.temp = alloca i16, align 2, !dbg !74
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc19_32.1.temp), !dbg !71
+// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc19_32.1.temp), !dbg !71
+// CHECK:STDOUT:   %.loc19_32.2 = load i8, ptr %.loc19_32.1.temp, align 1, !dbg !71
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_35.1.temp), !dbg !72
+// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc20_35.1.temp), !dbg !72
+// CHECK:STDOUT:   %.loc20_35.2 = load i16, ptr %.loc20_35.1.temp, align 2, !dbg !72
+// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !75
+// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !76
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_32.1.temp), !dbg !73
+// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc24_32.1.temp), !dbg !73
+// CHECK:STDOUT:   %.loc24_32.2 = load i8, ptr %.loc24_32.1.temp, align 1, !dbg !73
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc25_35.1.temp), !dbg !74
+// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc25_35.1.temp), !dbg !74
+// CHECK:STDOUT:   %.loc25_35.2 = load i16, ptr %.loc25_35.1.temp, align 2, !dbg !74
+// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !77
+// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !78
+// CHECK:STDOUT:   call void @_CUse.Main(i8 %.loc19_32.2, i16 %.loc20_35.2, i32 %ReturnU32.call, i64 %ReturnU64.call, i8 %.loc24_32.2, i16 %.loc25_35.2, i32 %ReturnI32.call, i64 %ReturnI64.call), !dbg !79
+// CHECK:STDOUT:   ret void, !dbg !80
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef signext i8 @_Z8ReturnI8v() #3
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z9ReturnI16v.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CVars.Main() #2 !dbg !81 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !104
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !104
-// CHECK:STDOUT:   %call = call noundef signext i16 @_Z9ReturnI16v()
-// CHECK:STDOUT:   store i16 %call, ptr %0, align 2, !tbaa !106
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %my_u8.var = alloca i8, align 1, !dbg !82
+// CHECK:STDOUT:   %.loc33_32.1.temp = alloca i8, align 1, !dbg !83
+// CHECK:STDOUT:   %my_u16.var = alloca i16, align 2, !dbg !84
+// CHECK:STDOUT:   %.loc34_35.1.temp = alloca i16, align 2, !dbg !85
+// CHECK:STDOUT:   %my_u32.var = alloca i32, align 4, !dbg !86
+// CHECK:STDOUT:   %my_u64.var = alloca i64, align 8, !dbg !87
+// CHECK:STDOUT:   %my_i8.var = alloca i8, align 1, !dbg !88
+// CHECK:STDOUT:   %.loc38_32.1.temp = alloca i8, align 1, !dbg !89
+// CHECK:STDOUT:   %my_i16.var = alloca i16, align 2, !dbg !90
+// CHECK:STDOUT:   %.loc39_35.1.temp = alloca i16, align 2, !dbg !91
+// CHECK:STDOUT:   %my_i32.var = alloca i32, align 4, !dbg !92
+// CHECK:STDOUT:   %my_i64.var = alloca i64, align 8, !dbg !93
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u8.var), !dbg !82
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc33_32.1.temp), !dbg !83
+// CHECK:STDOUT:   call void @_Z8ReturnU8v.carbon_thunk(ptr %.loc33_32.1.temp), !dbg !83
+// CHECK:STDOUT:   %.loc33_32.2 = load i8, ptr %.loc33_32.1.temp, align 1, !dbg !83
+// CHECK:STDOUT:   store i8 %.loc33_32.2, ptr %my_u8.var, align 1, !dbg !82
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u16.var), !dbg !84
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc34_35.1.temp), !dbg !85
+// CHECK:STDOUT:   call void @_Z9ReturnU16v.carbon_thunk(ptr %.loc34_35.1.temp), !dbg !85
+// CHECK:STDOUT:   %.loc34_35.2 = load i16, ptr %.loc34_35.1.temp, align 2, !dbg !85
+// CHECK:STDOUT:   store i16 %.loc34_35.2, ptr %my_u16.var, align 2, !dbg !84
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u32.var), !dbg !86
+// CHECK:STDOUT:   %ReturnU32.call = call i32 @_Z9ReturnU32v(), !dbg !94
+// CHECK:STDOUT:   store i32 %ReturnU32.call, ptr %my_u32.var, align 4, !dbg !86
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_u64.var), !dbg !87
+// CHECK:STDOUT:   %ReturnU64.call = call i64 @_Z9ReturnU64v(), !dbg !95
+// CHECK:STDOUT:   store i64 %ReturnU64.call, ptr %my_u64.var, align 8, !dbg !87
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i8.var), !dbg !88
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc38_32.1.temp), !dbg !89
+// CHECK:STDOUT:   call void @_Z8ReturnI8v.carbon_thunk(ptr %.loc38_32.1.temp), !dbg !89
+// CHECK:STDOUT:   %.loc38_32.2 = load i8, ptr %.loc38_32.1.temp, align 1, !dbg !89
+// CHECK:STDOUT:   store i8 %.loc38_32.2, ptr %my_i8.var, align 1, !dbg !88
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i16.var), !dbg !90
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc39_35.1.temp), !dbg !91
+// CHECK:STDOUT:   call void @_Z9ReturnI16v.carbon_thunk(ptr %.loc39_35.1.temp), !dbg !91
+// CHECK:STDOUT:   %.loc39_35.2 = load i16, ptr %.loc39_35.1.temp, align 2, !dbg !91
+// CHECK:STDOUT:   store i16 %.loc39_35.2, ptr %my_i16.var, align 2, !dbg !90
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i32.var), !dbg !92
+// CHECK:STDOUT:   %ReturnI32.call = call i32 @_Z9ReturnI32v(), !dbg !96
+// CHECK:STDOUT:   store i32 %ReturnI32.call, ptr %my_i32.var, align 4, !dbg !92
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %my_i64.var), !dbg !93
+// CHECK:STDOUT:   %ReturnI64.call = call i64 @_Z9ReturnI64v(), !dbg !97
+// CHECK:STDOUT:   store i64 %ReturnI64.call, ptr %my_i64.var, align 8, !dbg !93
+// CHECK:STDOUT:   %.loc43_7 = load i8, ptr %my_u8.var, align 1, !dbg !98
+// CHECK:STDOUT:   %.loc43_14 = load i16, ptr %my_u16.var, align 2, !dbg !99
+// CHECK:STDOUT:   %.loc43_22 = load i32, ptr %my_u32.var, align 4, !dbg !100
+// CHECK:STDOUT:   %.loc43_30 = load i64, ptr %my_u64.var, align 8, !dbg !101
+// CHECK:STDOUT:   %.loc43_38 = load i8, ptr %my_i8.var, align 1, !dbg !102
+// CHECK:STDOUT:   %.loc43_45 = load i16, ptr %my_i16.var, align 2, !dbg !103
+// CHECK:STDOUT:   %.loc43_53 = load i32, ptr %my_i32.var, align 4, !dbg !104
+// CHECK:STDOUT:   %.loc43_61 = load i64, ptr %my_i64.var, align 8, !dbg !105
+// CHECK:STDOUT:   call void @_CUse.Main(i8 %.loc43_7, i16 %.loc43_14, i32 %.loc43_22, i64 %.loc43_30, i8 %.loc43_38, i16 %.loc43_45, i32 %.loc43_53, i64 %.loc43_61), !dbg !106
+// CHECK:STDOUT:   ret void, !dbg !107
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare noundef signext i16 @_Z9ReturnI16v() #3
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -351,7 +351,7 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -360,102 +360,102 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "GetU8", linkageName: "_CGetU8.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15}
-// CHECK:STDOUT: !15 = !DIBasicType(name: "int", size: 8, encoding: DW_ATE_unsigned)
-// CHECK:STDOUT: !16 = !DILocation(line: 6, column: 27, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 6, column: 20, scope: !12)
-// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "GetU16", linkageName: "_CGetU16.Main", scope: null, file: !7, line: 7, type: !19, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !19 = !DISubroutineType(types: !20)
-// CHECK:STDOUT: !20 = !{!21}
-// CHECK:STDOUT: !21 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_unsigned)
-// CHECK:STDOUT: !22 = !DILocation(line: 7, column: 29, scope: !18)
-// CHECK:STDOUT: !23 = !DILocation(line: 7, column: 22, scope: !18)
-// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "GetU32", linkageName: "_CGetU32.Main", scope: null, file: !7, line: 8, type: !25, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !25 = !DISubroutineType(types: !26)
-// CHECK:STDOUT: !26 = !{!27}
-// CHECK:STDOUT: !27 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_unsigned)
-// CHECK:STDOUT: !28 = !DILocation(line: 8, column: 29, scope: !24)
-// CHECK:STDOUT: !29 = !DILocation(line: 8, column: 22, scope: !24)
-// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "GetU64", linkageName: "_CGetU64.Main", scope: null, file: !7, line: 9, type: !31, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !31 = !DISubroutineType(types: !32)
-// CHECK:STDOUT: !32 = !{!33}
-// CHECK:STDOUT: !33 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_unsigned)
-// CHECK:STDOUT: !34 = !DILocation(line: 9, column: 29, scope: !30)
-// CHECK:STDOUT: !35 = !DILocation(line: 9, column: 22, scope: !30)
-// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "GetI8", linkageName: "_CGetI8.Main", scope: null, file: !7, line: 11, type: !37, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !37 = !DISubroutineType(types: !38)
-// CHECK:STDOUT: !38 = !{!39}
-// CHECK:STDOUT: !39 = !DIBasicType(name: "int", size: 8, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !40 = !DILocation(line: 11, column: 27, scope: !36)
-// CHECK:STDOUT: !41 = !DILocation(line: 11, column: 20, scope: !36)
-// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "GetI16", linkageName: "_CGetI16.Main", scope: null, file: !7, line: 12, type: !43, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !43 = !DISubroutineType(types: !44)
-// CHECK:STDOUT: !44 = !{!45}
-// CHECK:STDOUT: !45 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !46 = !DILocation(line: 12, column: 29, scope: !42)
-// CHECK:STDOUT: !47 = !DILocation(line: 12, column: 22, scope: !42)
-// CHECK:STDOUT: !48 = distinct !DISubprogram(name: "GetI32", linkageName: "_CGetI32.Main", scope: null, file: !7, line: 13, type: !49, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !49 = !DISubroutineType(types: !50)
-// CHECK:STDOUT: !50 = !{!51}
-// CHECK:STDOUT: !51 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !52 = !DILocation(line: 13, column: 29, scope: !48)
-// CHECK:STDOUT: !53 = !DILocation(line: 13, column: 22, scope: !48)
-// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "GetI64", linkageName: "_CGetI64.Main", scope: null, file: !7, line: 14, type: !55, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !55 = !DISubroutineType(types: !56)
-// CHECK:STDOUT: !56 = !{!57}
-// CHECK:STDOUT: !57 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !58 = !DILocation(line: 14, column: 29, scope: !54)
-// CHECK:STDOUT: !59 = !DILocation(line: 14, column: 22, scope: !54)
-// CHECK:STDOUT: !60 = distinct !DISubprogram(name: "Lets", linkageName: "_CLets.Main", scope: null, file: !7, line: 18, type: !61, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !61 = !DISubroutineType(types: !62)
-// CHECK:STDOUT: !62 = !{null}
-// CHECK:STDOUT: !63 = !DILocation(line: 19, column: 19, scope: !60)
-// CHECK:STDOUT: !64 = !DILocation(line: 20, column: 21, scope: !60)
-// CHECK:STDOUT: !65 = !DILocation(line: 24, column: 19, scope: !60)
-// CHECK:STDOUT: !66 = !DILocation(line: 25, column: 21, scope: !60)
-// CHECK:STDOUT: !67 = !DILocation(line: 21, column: 21, scope: !60)
-// CHECK:STDOUT: !68 = !DILocation(line: 22, column: 21, scope: !60)
-// CHECK:STDOUT: !69 = !DILocation(line: 26, column: 21, scope: !60)
-// CHECK:STDOUT: !70 = !DILocation(line: 27, column: 21, scope: !60)
-// CHECK:STDOUT: !71 = !DILocation(line: 29, column: 3, scope: !60)
-// CHECK:STDOUT: !72 = !DILocation(line: 18, column: 1, scope: !60)
-// CHECK:STDOUT: !73 = distinct !DISubprogram(name: "Vars", linkageName: "_CVars.Main", scope: null, file: !7, line: 32, type: !61, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !74 = !DILocation(line: 33, column: 3, scope: !73)
-// CHECK:STDOUT: !75 = !DILocation(line: 33, column: 19, scope: !73)
-// CHECK:STDOUT: !76 = !DILocation(line: 34, column: 3, scope: !73)
-// CHECK:STDOUT: !77 = !DILocation(line: 34, column: 21, scope: !73)
-// CHECK:STDOUT: !78 = !DILocation(line: 35, column: 3, scope: !73)
-// CHECK:STDOUT: !79 = !DILocation(line: 36, column: 3, scope: !73)
-// CHECK:STDOUT: !80 = !DILocation(line: 38, column: 3, scope: !73)
-// CHECK:STDOUT: !81 = !DILocation(line: 38, column: 19, scope: !73)
-// CHECK:STDOUT: !82 = !DILocation(line: 39, column: 3, scope: !73)
-// CHECK:STDOUT: !83 = !DILocation(line: 39, column: 21, scope: !73)
-// CHECK:STDOUT: !84 = !DILocation(line: 40, column: 3, scope: !73)
-// CHECK:STDOUT: !85 = !DILocation(line: 41, column: 3, scope: !73)
-// CHECK:STDOUT: !86 = !DILocation(line: 35, column: 21, scope: !73)
-// CHECK:STDOUT: !87 = !DILocation(line: 36, column: 21, scope: !73)
-// CHECK:STDOUT: !88 = !DILocation(line: 40, column: 21, scope: !73)
-// CHECK:STDOUT: !89 = !DILocation(line: 41, column: 21, scope: !73)
-// CHECK:STDOUT: !90 = !DILocation(line: 43, column: 7, scope: !73)
-// CHECK:STDOUT: !91 = !DILocation(line: 43, column: 14, scope: !73)
-// CHECK:STDOUT: !92 = !DILocation(line: 43, column: 22, scope: !73)
-// CHECK:STDOUT: !93 = !DILocation(line: 43, column: 30, scope: !73)
-// CHECK:STDOUT: !94 = !DILocation(line: 43, column: 38, scope: !73)
-// CHECK:STDOUT: !95 = !DILocation(line: 43, column: 45, scope: !73)
-// CHECK:STDOUT: !96 = !DILocation(line: 43, column: 53, scope: !73)
-// CHECK:STDOUT: !97 = !DILocation(line: 43, column: 61, scope: !73)
-// CHECK:STDOUT: !98 = !DILocation(line: 43, column: 3, scope: !73)
-// CHECK:STDOUT: !99 = !DILocation(line: 32, column: 1, scope: !73)
-// CHECK:STDOUT: !100 = !{!101, !101, i64 0}
-// CHECK:STDOUT: !101 = !{!"p1 omnipotent char", !102, i64 0}
-// CHECK:STDOUT: !102 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !103 = !{!10, !10, i64 0}
-// CHECK:STDOUT: !104 = !{!105, !105, i64 0}
-// CHECK:STDOUT: !105 = !{!"p1 short", !102, i64 0}
-// CHECK:STDOUT: !106 = !{!107, !107, i64 0}
-// CHECK:STDOUT: !107 = !{!"short", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 omnipotent char", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!10, !10, i64 0}
+// CHECK:STDOUT: !16 = !{!17, !17, i64 0}
+// CHECK:STDOUT: !17 = !{!"p1 short", !14, i64 0}
+// CHECK:STDOUT: !18 = !{!19, !19, i64 0}
+// CHECK:STDOUT: !19 = !{!"short", !10, i64 0}
+// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "GetU8", linkageName: "_CGetU8.Main", scope: null, file: !7, line: 6, type: !21, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
+// CHECK:STDOUT: !22 = !{!23}
+// CHECK:STDOUT: !23 = !DIBasicType(name: "int", size: 8, encoding: DW_ATE_unsigned)
+// CHECK:STDOUT: !24 = !DILocation(line: 6, column: 27, scope: !20)
+// CHECK:STDOUT: !25 = !DILocation(line: 6, column: 20, scope: !20)
+// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "GetU16", linkageName: "_CGetU16.Main", scope: null, file: !7, line: 7, type: !27, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !27 = !DISubroutineType(types: !28)
+// CHECK:STDOUT: !28 = !{!29}
+// CHECK:STDOUT: !29 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_unsigned)
+// CHECK:STDOUT: !30 = !DILocation(line: 7, column: 29, scope: !26)
+// CHECK:STDOUT: !31 = !DILocation(line: 7, column: 22, scope: !26)
+// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "GetU32", linkageName: "_CGetU32.Main", scope: null, file: !7, line: 8, type: !33, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !33 = !DISubroutineType(types: !34)
+// CHECK:STDOUT: !34 = !{!35}
+// CHECK:STDOUT: !35 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_unsigned)
+// CHECK:STDOUT: !36 = !DILocation(line: 8, column: 29, scope: !32)
+// CHECK:STDOUT: !37 = !DILocation(line: 8, column: 22, scope: !32)
+// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "GetU64", linkageName: "_CGetU64.Main", scope: null, file: !7, line: 9, type: !39, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !39 = !DISubroutineType(types: !40)
+// CHECK:STDOUT: !40 = !{!41}
+// CHECK:STDOUT: !41 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_unsigned)
+// CHECK:STDOUT: !42 = !DILocation(line: 9, column: 29, scope: !38)
+// CHECK:STDOUT: !43 = !DILocation(line: 9, column: 22, scope: !38)
+// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "GetI8", linkageName: "_CGetI8.Main", scope: null, file: !7, line: 11, type: !45, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !45 = !DISubroutineType(types: !46)
+// CHECK:STDOUT: !46 = !{!47}
+// CHECK:STDOUT: !47 = !DIBasicType(name: "int", size: 8, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !48 = !DILocation(line: 11, column: 27, scope: !44)
+// CHECK:STDOUT: !49 = !DILocation(line: 11, column: 20, scope: !44)
+// CHECK:STDOUT: !50 = distinct !DISubprogram(name: "GetI16", linkageName: "_CGetI16.Main", scope: null, file: !7, line: 12, type: !51, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !51 = !DISubroutineType(types: !52)
+// CHECK:STDOUT: !52 = !{!53}
+// CHECK:STDOUT: !53 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !54 = !DILocation(line: 12, column: 29, scope: !50)
+// CHECK:STDOUT: !55 = !DILocation(line: 12, column: 22, scope: !50)
+// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "GetI32", linkageName: "_CGetI32.Main", scope: null, file: !7, line: 13, type: !57, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !57 = !DISubroutineType(types: !58)
+// CHECK:STDOUT: !58 = !{!59}
+// CHECK:STDOUT: !59 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !60 = !DILocation(line: 13, column: 29, scope: !56)
+// CHECK:STDOUT: !61 = !DILocation(line: 13, column: 22, scope: !56)
+// CHECK:STDOUT: !62 = distinct !DISubprogram(name: "GetI64", linkageName: "_CGetI64.Main", scope: null, file: !7, line: 14, type: !63, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !63 = !DISubroutineType(types: !64)
+// CHECK:STDOUT: !64 = !{!65}
+// CHECK:STDOUT: !65 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !66 = !DILocation(line: 14, column: 29, scope: !62)
+// CHECK:STDOUT: !67 = !DILocation(line: 14, column: 22, scope: !62)
+// CHECK:STDOUT: !68 = distinct !DISubprogram(name: "Lets", linkageName: "_CLets.Main", scope: null, file: !7, line: 18, type: !69, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !69 = !DISubroutineType(types: !70)
+// CHECK:STDOUT: !70 = !{null}
+// CHECK:STDOUT: !71 = !DILocation(line: 19, column: 19, scope: !68)
+// CHECK:STDOUT: !72 = !DILocation(line: 20, column: 21, scope: !68)
+// CHECK:STDOUT: !73 = !DILocation(line: 24, column: 19, scope: !68)
+// CHECK:STDOUT: !74 = !DILocation(line: 25, column: 21, scope: !68)
+// CHECK:STDOUT: !75 = !DILocation(line: 21, column: 21, scope: !68)
+// CHECK:STDOUT: !76 = !DILocation(line: 22, column: 21, scope: !68)
+// CHECK:STDOUT: !77 = !DILocation(line: 26, column: 21, scope: !68)
+// CHECK:STDOUT: !78 = !DILocation(line: 27, column: 21, scope: !68)
+// CHECK:STDOUT: !79 = !DILocation(line: 29, column: 3, scope: !68)
+// CHECK:STDOUT: !80 = !DILocation(line: 18, column: 1, scope: !68)
+// CHECK:STDOUT: !81 = distinct !DISubprogram(name: "Vars", linkageName: "_CVars.Main", scope: null, file: !7, line: 32, type: !69, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !82 = !DILocation(line: 33, column: 3, scope: !81)
+// CHECK:STDOUT: !83 = !DILocation(line: 33, column: 19, scope: !81)
+// CHECK:STDOUT: !84 = !DILocation(line: 34, column: 3, scope: !81)
+// CHECK:STDOUT: !85 = !DILocation(line: 34, column: 21, scope: !81)
+// CHECK:STDOUT: !86 = !DILocation(line: 35, column: 3, scope: !81)
+// CHECK:STDOUT: !87 = !DILocation(line: 36, column: 3, scope: !81)
+// CHECK:STDOUT: !88 = !DILocation(line: 38, column: 3, scope: !81)
+// CHECK:STDOUT: !89 = !DILocation(line: 38, column: 19, scope: !81)
+// CHECK:STDOUT: !90 = !DILocation(line: 39, column: 3, scope: !81)
+// CHECK:STDOUT: !91 = !DILocation(line: 39, column: 21, scope: !81)
+// CHECK:STDOUT: !92 = !DILocation(line: 40, column: 3, scope: !81)
+// CHECK:STDOUT: !93 = !DILocation(line: 41, column: 3, scope: !81)
+// CHECK:STDOUT: !94 = !DILocation(line: 35, column: 21, scope: !81)
+// CHECK:STDOUT: !95 = !DILocation(line: 36, column: 21, scope: !81)
+// CHECK:STDOUT: !96 = !DILocation(line: 40, column: 21, scope: !81)
+// CHECK:STDOUT: !97 = !DILocation(line: 41, column: 21, scope: !81)
+// CHECK:STDOUT: !98 = !DILocation(line: 43, column: 7, scope: !81)
+// CHECK:STDOUT: !99 = !DILocation(line: 43, column: 14, scope: !81)
+// CHECK:STDOUT: !100 = !DILocation(line: 43, column: 22, scope: !81)
+// CHECK:STDOUT: !101 = !DILocation(line: 43, column: 30, scope: !81)
+// CHECK:STDOUT: !102 = !DILocation(line: 43, column: 38, scope: !81)
+// CHECK:STDOUT: !103 = !DILocation(line: 43, column: 45, scope: !81)
+// CHECK:STDOUT: !104 = !DILocation(line: 43, column: 53, scope: !81)
+// CHECK:STDOUT: !105 = !DILocation(line: 43, column: 61, scope: !81)
+// CHECK:STDOUT: !106 = !DILocation(line: 43, column: 3, scope: !81)
+// CHECK:STDOUT: !107 = !DILocation(line: 32, column: 1, scope: !81)
 // CHECK:STDOUT: ; ModuleID = 'import_class.carbon'
 // CHECK:STDOUT: source_filename = "import_class.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -463,57 +463,59 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: %struct.X = type { ptr, ptr }
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CGetX.Main(ptr sret([16 x i8]) %return) #0 !dbg !12 {
+// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
+// CHECK:STDOUT: define dso_local void @_Z4Makev.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %return), !dbg !16
-// CHECK:STDOUT:   ret void, !dbg !17
+// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   call void @_Z4Makev(ptr dead_on_unwind writable sret(%struct.X) align 8 %0)
+// CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: declare void @_Z4Makev(ptr dead_on_unwind writable sret(%struct.X) align 8) #1
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CLet.Main() #0 !dbg !18 {
+// CHECK:STDOUT: define void @_CGetX.Main(ptr sret([16 x i8]) %return) #2 !dbg !15 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc9_27.1.temp = alloca [16 x i8], align 1, !dbg !21
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_27.1.temp), !dbg !21
-// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %.loc9_27.1.temp), !dbg !21
-// CHECK:STDOUT:   call void @_ZN1XD1Ev(ptr %.loc9_27.1.temp), !dbg !21
-// CHECK:STDOUT:   ret void, !dbg !22
+// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %return), !dbg !19
+// CHECK:STDOUT:   ret void, !dbg !20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_ZN1XD1Ev(ptr)
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CVar.Main() #0 !dbg !23 {
+// CHECK:STDOUT: define void @_CLet.Main() #2 !dbg !21 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %_.var = alloca [16 x i8], align 1, !dbg !24
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !24
-// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %_.var), !dbg !25
-// CHECK:STDOUT:   call void @_ZN1XD1Ev(ptr %_.var), !dbg !24
-// CHECK:STDOUT:   ret void, !dbg !26
+// CHECK:STDOUT:   %.loc9_27.1.temp = alloca [16 x i8], align 1, !dbg !24
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_27.1.temp), !dbg !24
+// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %.loc9_27.1.temp), !dbg !24
+// CHECK:STDOUT:   call void @_ZN1XD1Ev(ptr %.loc9_27.1.temp), !dbg !24
+// CHECK:STDOUT:   ret void, !dbg !25
 // 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: declare void @_ZN1XD1Ev(ptr noundef nonnull align 8 dereferenceable(16)) unnamed_addr #3
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z4Makev.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CVar.Main() #2 !dbg !26 {
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   call void @_Z4Makev(ptr dead_on_unwind writable sret(%struct.X) align 8 %0)
-// CHECK:STDOUT:   ret void
+// CHECK:STDOUT:   %_.var = alloca [16 x i8], align 1, !dbg !27
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !27
+// CHECK:STDOUT:   call void @_Z4Makev.carbon_thunk(ptr %_.var), !dbg !28
+// CHECK:STDOUT:   call void @_ZN1XD1Ev(ptr %_.var), !dbg !27
+// CHECK:STDOUT:   ret void, !dbg !29
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z4Makev(ptr dead_on_unwind writable sret(%struct.X) align 8) #3
+// 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:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { 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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -522,7 +524,7 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -531,58 +533,59 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "GetX", linkageName: "_CGetX.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !DILocation(line: 6, column: 29, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 6, column: 22, scope: !12)
-// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "Let", linkageName: "_CLet.Main", scope: null, file: !7, line: 8, type: !19, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !19 = !DISubroutineType(types: !20)
-// CHECK:STDOUT: !20 = !{null}
-// CHECK:STDOUT: !21 = !DILocation(line: 9, column: 18, scope: !18)
-// CHECK:STDOUT: !22 = !DILocation(line: 8, column: 1, scope: !18)
-// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "Var", linkageName: "_CVar.Main", scope: null, file: !7, line: 12, type: !19, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !24 = !DILocation(line: 13, column: 3, scope: !23)
-// CHECK:STDOUT: !25 = !DILocation(line: 13, column: 18, scope: !23)
-// CHECK:STDOUT: !26 = !DILocation(line: 12, column: 1, scope: !23)
-// CHECK:STDOUT: !27 = !{!28, !28, i64 0}
-// CHECK:STDOUT: !28 = !{!"p1 _ZTS1X", !29, i64 0}
-// CHECK:STDOUT: !29 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1X", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "GetX", linkageName: "_CGetX.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{!18}
+// CHECK:STDOUT: !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !19 = !DILocation(line: 6, column: 29, scope: !15)
+// CHECK:STDOUT: !20 = !DILocation(line: 6, column: 22, scope: !15)
+// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "Let", linkageName: "_CLet.Main", scope: null, file: !7, line: 8, type: !22, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !22 = !DISubroutineType(types: !23)
+// CHECK:STDOUT: !23 = !{null}
+// CHECK:STDOUT: !24 = !DILocation(line: 9, column: 18, scope: !21)
+// CHECK:STDOUT: !25 = !DILocation(line: 8, column: 1, scope: !21)
+// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "Var", linkageName: "_CVar.Main", scope: null, file: !7, line: 12, type: !22, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !27 = !DILocation(line: 13, column: 3, scope: !26)
+// CHECK:STDOUT: !28 = !DILocation(line: 13, column: 18, scope: !26)
+// CHECK:STDOUT: !29 = !DILocation(line: 12, column: 1, scope: !26)
 // CHECK:STDOUT: ; ModuleID = 'indirect_return_with_args.carbon'
 // CHECK:STDOUT: source_filename = "indirect_return_with_args.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
 // CHECK:STDOUT:
 // CHECK:STDOUT: %class.D = type { i8 }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCall.Main(ptr sret({}) %return, ptr %x) #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z1f1D.carbon_thunk(ptr %x, ptr %return), !dbg !18
-// CHECK:STDOUT:   ret void, !dbg !19
-// CHECK:STDOUT: }
+// CHECK:STDOUT: %class.C = type { i8 }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z1f1D.carbon_thunk(ptr noundef %0, ptr noundef %return) #1 {
+// CHECK:STDOUT: define dso_local void @_Z1f1D.carbon_thunk(ptr noundef %0, ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %return.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.D, align 1
-// CHECK:STDOUT:   %undef.agg.tmp = alloca %class.D, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !20
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !23
-// CHECK:STDOUT:   %1 = load ptr, ptr %return.addr, align 8, !tbaa !23
-// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !20
+// CHECK:STDOUT:   %undef.agg.tmp = alloca %class.C, align 1
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %1 = load ptr, ptr %return.addr, align 8, !tbaa !15
+// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z1f1D()
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z1f1D() #2
+// CHECK:STDOUT: declare void @_Z1f1D() #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCall.Main(ptr sret({}) %return, ptr %x) #2 !dbg !17 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @_Z1f1D.carbon_thunk(ptr %x, ptr %return), !dbg !23
+// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #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: attributes #0 = { 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 #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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -591,7 +594,7 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -600,16 +603,16 @@ fn Call(x: Cpp.D) -> Cpp.C {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 10, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15, !15}
-// CHECK:STDOUT: !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 11, column: 10, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 11, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = !{!21, !21, i64 0}
-// CHECK:STDOUT: !21 = !{!"p1 _ZTS1D", !22, i64 0}
-// CHECK:STDOUT: !22 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !23 = !{!24, !24, i64 0}
-// CHECK:STDOUT: !24 = !{!"p1 _ZTS1C", !22, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1D", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"p1 _ZTS1C", !14, i64 0}
+// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !7, line: 10, type: !18, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21)
+// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
+// CHECK:STDOUT: !19 = !{!20, !20}
+// CHECK:STDOUT: !20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !21 = !{!22}
+// CHECK:STDOUT: !22 = !DILocalVariable(arg: 1, scope: !17, type: !20)
+// CHECK:STDOUT: !23 = !DILocation(line: 11, column: 10, scope: !17)
+// CHECK:STDOUT: !24 = !DILocation(line: 11, column: 3, scope: !17)

+ 120 - 119
toolchain/lower/testdata/interop/cpp/template.carbon

@@ -96,44 +96,37 @@ fn Call3() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: $_Z8identityIiET_S0_ = comdat any
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CPassI32.Main(i32 %a) #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %identity.call = call i32 @_Z8identityIiET_S0_(i32 %a), !dbg !18
-// CHECK:STDOUT:   ret i32 %identity.call, !dbg !19
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CPassClass.Main(ptr sret({}) %return, ptr %a) #0 !dbg !20 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @_Z8identityI5ClassET_S1_.carbon_thunk(ptr %a, ptr %return), !dbg !26
-// CHECK:STDOUT:   ret void, !dbg !27
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z8identityI5ClassET_S1_.carbon_thunk(ptr noundef %x, ptr noundef %return) #1 {
+// CHECK:STDOUT: define dso_local void @_Z8identityI5ClassET_S1_.carbon_thunk(ptr noundef %x, ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %x.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %return.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.Class, align 1
 // CHECK:STDOUT:   %undef.agg.tmp = alloca %class.Class, align 1
-// CHECK:STDOUT:   store ptr %x, ptr %x.addr, align 8, !tbaa !28
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !28
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !28
-// CHECK:STDOUT:   %1 = load ptr, ptr %x.addr, align 8, !tbaa !28
+// CHECK:STDOUT:   store ptr %x, ptr %x.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %x.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z8identityI5ClassET_S1_()
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_Z8identityI5ClassET_S1_() #2 comdat {
+// CHECK:STDOUT: define linkonce_odr dso_local void @_Z8identityI5ClassET_S1_() #1 comdat {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %x = alloca %class.Class, align 1
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CPassI32.Main(i32 %a) #2 !dbg !15 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %identity.call = call i32 @_Z8identityIiET_S0_(i32 %a), !dbg !21
+// CHECK:STDOUT:   ret i32 %identity.call, !dbg !22
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_Z8identityIiET_S0_(i32 noundef %x) #2 comdat {
+// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_Z8identityIiET_S0_(i32 noundef %x) #1 comdat {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %x.addr = alloca i32, align 4
 // CHECK:STDOUT:   store i32 %x, ptr %x.addr, align 4, !tbaa !8
@@ -141,9 +134,16 @@ fn Call3() {
 // CHECK:STDOUT:   ret i32 %0
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { 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 #2 = { 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: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CPassClass.Main(ptr sret({}) %return, ptr %a) #2 !dbg !23 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @_Z8identityI5ClassET_S1_.carbon_thunk(ptr %a, ptr %return), !dbg !29
+// CHECK:STDOUT:   ret void, !dbg !30
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { 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 #1 = { 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -152,7 +152,7 @@ fn Call3() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -161,25 +161,25 @@ fn Call3() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "PassI32", linkageName: "_CPassI32.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !16)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{!15, !15}
-// CHECK:STDOUT: !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !16 = !{!17}
-// CHECK:STDOUT: !17 = !DILocalVariable(arg: 1, scope: !12, type: !15)
-// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 10, scope: !12)
-// CHECK:STDOUT: !19 = !DILocation(line: 7, column: 3, scope: !12)
-// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "PassClass", linkageName: "_CPassClass.Main", scope: null, file: !7, line: 10, type: !21, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !24)
-// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
-// CHECK:STDOUT: !22 = !{!23, !23}
-// CHECK:STDOUT: !23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !24 = !{!25}
-// CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !20, type: !23)
-// CHECK:STDOUT: !26 = !DILocation(line: 11, column: 10, scope: !20)
-// CHECK:STDOUT: !27 = !DILocation(line: 11, column: 3, scope: !20)
-// CHECK:STDOUT: !28 = !{!29, !29, i64 0}
-// CHECK:STDOUT: !29 = !{!"p1 _ZTS5Class", !30, i64 0}
-// CHECK:STDOUT: !30 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS5Class", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "PassI32", linkageName: "_CPassI32.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !19)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{!18, !18}
+// CHECK:STDOUT: !18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !19 = !{!20}
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !15, type: !18)
+// CHECK:STDOUT: !21 = !DILocation(line: 7, column: 10, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 7, column: 3, scope: !15)
+// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "PassClass", linkageName: "_CPassClass.Main", scope: null, file: !7, line: 10, type: !24, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !27)
+// CHECK:STDOUT: !24 = !DISubroutineType(types: !25)
+// CHECK:STDOUT: !25 = !{!26, !26}
+// CHECK:STDOUT: !26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !27 = !{!28}
+// CHECK:STDOUT: !28 = !DILocalVariable(arg: 1, scope: !23, type: !26)
+// CHECK:STDOUT: !29 = !DILocation(line: 11, column: 10, scope: !23)
+// CHECK:STDOUT: !30 = !DILocation(line: 11, column: 3, scope: !23)
 // CHECK:STDOUT: ; ModuleID = 'variadic.carbon'
 // CHECK:STDOUT: source_filename = "variadic.carbon"
 // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -192,7 +192,7 @@ fn Call3() {
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJEEviDpT_(i32)
+// CHECK:STDOUT: declare void @_Z3fooIJEEviDpT_(i32 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define void @_CCall2.Main() #0 !dbg !17 {
@@ -201,7 +201,7 @@ fn Call3() {
 // CHECK:STDOUT:   ret void, !dbg !19
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJiEEviDpT_(i32, i32)
+// CHECK:STDOUT: declare void @_Z3fooIJiEEviDpT_(i32 noundef, i32 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define void @_CCall3.Main() #0 !dbg !20 {
@@ -210,9 +210,10 @@ fn Call3() {
 // CHECK:STDOUT:   ret void, !dbg !22
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJiiEEviDpT_(i32, i32, i32)
+// CHECK:STDOUT: declare void @_Z3fooIJiiEEviDpT_(i32 noundef, i32 noundef, i32 noundef) #1
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -221,7 +222,7 @@ fn Call3() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -250,99 +251,99 @@ fn Call3() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: @X.val.loc12_12.3 = internal constant {} zeroinitializer
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCall1.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc12_12.2.temp = alloca {}, align 8, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_12.2.temp), !dbg !15
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc12_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !15
-// CHECK:STDOUT:   call void @_Z3fooIJEEv1XDpT_.carbon_thunk(ptr %.loc12_12.2.temp), !dbg !16
-// CHECK:STDOUT:   ret void, !dbg !17
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCall2.Main() #0 !dbg !18 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc18_12.2.temp = alloca {}, align 8, !dbg !19
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_12.2.temp), !dbg !19
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc18_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !19
-// CHECK:STDOUT:   call void @_Z3fooIJiEEv1XDpT_.carbon_thunk(ptr %.loc18_12.2.temp, i32 2), !dbg !20
-// CHECK:STDOUT:   ret void, !dbg !21
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CCall3.Main() #0 !dbg !22 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc24_12.2.temp = alloca {}, align 8, !dbg !23
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_12.2.temp), !dbg !23
-// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc24_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !23
-// CHECK:STDOUT:   call void @_Z3fooIJiiEEv1XDpT_.carbon_thunk(ptr %.loc24_12.2.temp, i32 2, i32 3), !dbg !24
-// CHECK:STDOUT:   ret void, !dbg !25
-// 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: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
-// CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z3fooIJEEv1XDpT_.carbon_thunk(ptr noundef %0) #3 {
+// CHECK:STDOUT: define dso_local void @_Z3fooIJEEv1XDpT_.carbon_thunk(ptr noundef %0) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %agg.tmp = alloca %class.X, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !26
-// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !26
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %1 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_Z3fooIJEEv1XDpT_()
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJEEv1XDpT_() #4
+// CHECK:STDOUT: declare void @_Z3fooIJEEv1XDpT_() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z3fooIJiEEv1XDpT_.carbon_thunk(ptr noundef %0, i32 noundef %1) #3 {
+// CHECK:STDOUT: define dso_local void @_Z3fooIJiEEv1XDpT_.carbon_thunk(ptr noundef %0, i32 noundef %1) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr1 = alloca i32, align 4
 // CHECK:STDOUT:   %agg.tmp = alloca %class.X, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !26
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   store i32 %1, ptr %.addr1, align 4, !tbaa !8
-// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !26
+// CHECK:STDOUT:   %2 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %3 = load i32, ptr %.addr1, align 4, !tbaa !8
 // CHECK:STDOUT:   call void @_Z3fooIJiEEv1XDpT_(i32 noundef %3)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJiEEv1XDpT_(i32 noundef) #4
+// CHECK:STDOUT: declare void @_Z3fooIJiEEv1XDpT_(i32 noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
-// CHECK:STDOUT: define dso_local void @_Z3fooIJiiEEv1XDpT_.carbon_thunk(ptr noundef %0, i32 noundef %1, i32 noundef %2) #3 {
+// CHECK:STDOUT: define dso_local void @_Z3fooIJiiEEv1XDpT_.carbon_thunk(ptr noundef %0, i32 noundef %1, i32 noundef %2) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.addr = alloca ptr, align 8
 // CHECK:STDOUT:   %.addr1 = alloca i32, align 4
 // CHECK:STDOUT:   %.addr2 = alloca i32, align 4
 // CHECK:STDOUT:   %agg.tmp = alloca %class.X, align 1
-// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !26
+// CHECK:STDOUT:   store ptr %0, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   store i32 %1, ptr %.addr1, align 4, !tbaa !8
 // CHECK:STDOUT:   store i32 %2, ptr %.addr2, align 4, !tbaa !8
-// CHECK:STDOUT:   %3 = load ptr, ptr %.addr, align 8, !tbaa !26
+// CHECK:STDOUT:   %3 = load ptr, ptr %.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %4 = load i32, ptr %.addr1, align 4, !tbaa !8
 // CHECK:STDOUT:   %5 = load i32, ptr %.addr2, align 4, !tbaa !8
 // CHECK:STDOUT:   call void @_Z3fooIJiiEEv1XDpT_(i32 noundef %4, i32 noundef %5)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z3fooIJiiEEv1XDpT_(i32 noundef, i32 noundef) #4
+// CHECK:STDOUT: declare void @_Z3fooIJiiEEv1XDpT_(i32 noundef, i32 noundef) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCall1.Main() #2 !dbg !15 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc12_12.2.temp = alloca {}, align 8, !dbg !18
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_12.2.temp), !dbg !18
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc12_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !18
+// CHECK:STDOUT:   call void @_Z3fooIJEEv1XDpT_.carbon_thunk(ptr %.loc12_12.2.temp), !dbg !19
+// CHECK:STDOUT:   ret void, !dbg !20
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCall2.Main() #2 !dbg !21 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc18_12.2.temp = alloca {}, align 8, !dbg !22
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_12.2.temp), !dbg !22
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc18_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !22
+// CHECK:STDOUT:   call void @_Z3fooIJiEEv1XDpT_.carbon_thunk(ptr %.loc18_12.2.temp, i32 2), !dbg !23
+// CHECK:STDOUT:   ret void, !dbg !24
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CCall3.Main() #2 !dbg !25 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc24_12.2.temp = alloca {}, align 8, !dbg !26
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_12.2.temp), !dbg !26
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc24_12.2.temp, ptr align 1 @X.val.loc12_12.3, i64 0, i1 false), !dbg !26
+// CHECK:STDOUT:   call void @_Z3fooIJiiEEv1XDpT_.carbon_thunk(ptr %.loc24_12.2.temp, i32 2, i32 3), !dbg !27
+// CHECK:STDOUT:   ret void, !dbg !28
+// 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:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 2, 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// CHECK:STDOUT: attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
-// 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 = { "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 #0 = { 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 #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 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -351,7 +352,7 @@ fn Call3() {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -360,20 +361,20 @@ fn Call3() {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Call1", linkageName: "_CCall1.Main", scope: null, file: !7, line: 10, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 12, column: 11, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 12, column: 3, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 10, column: 1, scope: !12)
-// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "Call2", linkageName: "_CCall2.Main", scope: null, file: !7, line: 16, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !19 = !DILocation(line: 18, column: 11, scope: !18)
-// CHECK:STDOUT: !20 = !DILocation(line: 18, column: 3, scope: !18)
-// CHECK:STDOUT: !21 = !DILocation(line: 16, column: 1, scope: !18)
-// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Call3", linkageName: "_CCall3.Main", scope: null, file: !7, line: 22, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !23 = !DILocation(line: 24, column: 11, scope: !22)
-// CHECK:STDOUT: !24 = !DILocation(line: 24, column: 3, scope: !22)
-// CHECK:STDOUT: !25 = !DILocation(line: 22, column: 1, scope: !22)
-// CHECK:STDOUT: !26 = !{!27, !27, i64 0}
-// CHECK:STDOUT: !27 = !{!"p1 _ZTS1X", !28, i64 0}
-// CHECK:STDOUT: !28 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1X", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "Call1", linkageName: "_CCall1.Main", scope: null, file: !7, line: 10, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{null}
+// CHECK:STDOUT: !18 = !DILocation(line: 12, column: 11, scope: !15)
+// CHECK:STDOUT: !19 = !DILocation(line: 12, column: 3, scope: !15)
+// CHECK:STDOUT: !20 = !DILocation(line: 10, column: 1, scope: !15)
+// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "Call2", linkageName: "_CCall2.Main", scope: null, file: !7, line: 16, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !22 = !DILocation(line: 18, column: 11, scope: !21)
+// CHECK:STDOUT: !23 = !DILocation(line: 18, column: 3, scope: !21)
+// CHECK:STDOUT: !24 = !DILocation(line: 16, column: 1, scope: !21)
+// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Call3", linkageName: "_CCall3.Main", scope: null, file: !7, line: 22, type: !16, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !26 = !DILocation(line: 24, column: 11, scope: !25)
+// CHECK:STDOUT: !27 = !DILocation(line: 24, column: 3, scope: !25)
+// CHECK:STDOUT: !28 = !DILocation(line: 22, column: 1, scope: !25)

+ 54 - 56
toolchain/lower/testdata/interop/cpp/virtual_base.carbon

@@ -108,53 +108,53 @@ fn AccessD(d: Cpp.D) -> i32 {
 // CHECK:STDOUT: @_ZTI1D = linkonce_odr dso_local constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64 } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), ptr @_ZTS1D, i32 2, i32 2, ptr @_ZTI1B, i64 2, ptr @_ZTI1C, i64 4098 }, comdat, align 8
 // CHECK:STDOUT: @_ZTS1D = linkonce_odr dso_local constant [3 x i8] c"1D\00", comdat, align 1
 // CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @_CMake.Main() #0 !dbg !12 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %_.var = alloca [40 x i8], align 1, !dbg !15
-// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !15
-// CHECK:STDOUT:   call void @_ZN1DC1Ev.carbon_thunk(ptr %_.var), !dbg !16
-// CHECK:STDOUT:   ret void, !dbg !17
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @_CAccessD.Main(ptr %d) #0 !dbg !18 {
-// CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc16_11.1.d = getelementptr inbounds nuw [40 x i8], ptr %d, i32 0, i32 28, !dbg !25
-// CHECK:STDOUT:   %.loc16_11.2 = load i32, ptr %.loc16_11.1.d, align 4, !dbg !25
-// CHECK:STDOUT:   ret i32 %.loc16_11.2, !dbg !26
-// 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 uwtable
-// CHECK:STDOUT: define dso_local void @_ZN1DC1Ev.carbon_thunk(ptr noundef %return) #2 {
+// CHECK:STDOUT: define dso_local void @_ZN1DC1Ev.carbon_thunk(ptr noundef %return) #0 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %return.addr = alloca ptr, align 8
-// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !27
-// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !27
+// CHECK:STDOUT:   store ptr %return, ptr %return.addr, align 8, !tbaa !12
+// CHECK:STDOUT:   %0 = load ptr, ptr %return.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   call void @_ZN1DC1Ev(ptr noundef nonnull align 8 dereferenceable(32) %0)
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: inlinehint mustprogress uwtable
-// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1DC1Ev(ptr noundef nonnull align 8 dereferenceable(32) %this) unnamed_addr #3 comdat align 2 {
+// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1DC1Ev(ptr noundef nonnull align 8 dereferenceable(32) %this) unnamed_addr #1 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 !27
+// CHECK:STDOUT:   store ptr %this, ptr %this.addr, align 8, !tbaa !12
 // CHECK:STDOUT:   %this1 = load ptr, ptr %this.addr, align 8
 // CHECK:STDOUT:   %0 = getelementptr inbounds i8, ptr %this1, i64 32
 // CHECK:STDOUT:   call void @_ZN1AC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %0)
 // CHECK:STDOUT:   call void @_ZN1BC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this1, ptr noundef getelementptr inbounds ([4 x ptr], ptr @_ZTT1D, i64 0, i64 1))
 // CHECK:STDOUT:   %1 = getelementptr inbounds i8, ptr %this1, i64 16
 // CHECK:STDOUT:   call void @_ZN1CC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %1, ptr noundef getelementptr inbounds ([4 x ptr], ptr @_ZTT1D, i64 0, i64 2))
-// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3), ptr %this1, align 8, !tbaa !30
+// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3), ptr %this1, align 8, !tbaa !15
 // CHECK:STDOUT:   %add.ptr = getelementptr inbounds i8, ptr %this1, i64 16
-// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 3), ptr %add.ptr, align 8, !tbaa !30
+// CHECK:STDOUT:   store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 3), ptr %add.ptr, align 8, !tbaa !15
 // CHECK:STDOUT:   ret void
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CMake.Main() #2 !dbg !17 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %_.var = alloca [40 x i8], align 1, !dbg !20
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !20
+// CHECK:STDOUT:   call void @_ZN1DC1Ev.carbon_thunk(ptr %_.var), !dbg !21
+// CHECK:STDOUT:   ret void, !dbg !22
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define i32 @_CAccessD.Main(ptr %d) #2 !dbg !23 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %.loc16_11.1.d = getelementptr inbounds nuw [40 x i8], ptr %d, i32 0, i32 28, !dbg !30
+// CHECK:STDOUT:   %.loc16_11.2 = load i32, ptr %.loc16_11.1.d, align 4, !dbg !30
+// CHECK:STDOUT:   ret i32 %.loc16_11.2, !dbg !31
+// 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:
 // CHECK:STDOUT: declare void @_ZN1AC2Ev(ptr noundef nonnull align 4 dereferenceable(4)) unnamed_addr #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: declare void @_ZN1BC2Ev(ptr noundef nonnull align 8 dereferenceable(12), ptr noundef) unnamed_addr #4
@@ -162,18 +162,16 @@ fn AccessD(d: Cpp.D) -> i32 {
 // CHECK:STDOUT: declare void @_ZN1CC2Ev(ptr noundef nonnull align 8 dereferenceable(12), ptr noundef) unnamed_addr #4
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
+// CHECK:STDOUT: uselistorder ptr inttoptr (i64 32 to ptr), { 1, 0 }
+// CHECK:STDOUT: uselistorder ptr inttoptr (i64 16 to ptr), { 1, 0 }
 // CHECK:STDOUT: uselistorder ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3), { 1, 0 }
 // CHECK:STDOUT: uselistorder ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 3), { 1, 0 }
-// CHECK:STDOUT: uselistorder ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), { 2, 1, 0 }
-// CHECK:STDOUT: uselistorder ptr @_ZTI1B, { 1, 0 }
-// CHECK:STDOUT: uselistorder ptr @_ZTI1A, { 1, 0 }
-// CHECK:STDOUT: uselistorder ptr @_ZTI1C, { 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @_ZTI1D, { 1, 0 }
 // CHECK:STDOUT:
-// CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// 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 = { 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 #0 = { 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 #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 = { nounwind }
+// 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
@@ -183,7 +181,7 @@ fn AccessD(d: Cpp.D) -> i32 {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -192,23 +190,23 @@ fn AccessD(d: Cpp.D) -> i32 {
 // CHECK:STDOUT: !9 = !{!"int", !10, i64 0}
 // CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0}
 // CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"}
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Make", linkageName: "_CMake.Main", scope: null, file: !7, line: 6, type: !13, spFlags: DISPFlagDefinition, unit: !6)
-// CHECK:STDOUT: !13 = !DISubroutineType(types: !14)
-// CHECK:STDOUT: !14 = !{null}
-// CHECK:STDOUT: !15 = !DILocation(line: 11, column: 3, scope: !12)
-// CHECK:STDOUT: !16 = !DILocation(line: 11, column: 18, scope: !12)
-// CHECK:STDOUT: !17 = !DILocation(line: 6, column: 1, scope: !12)
-// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "AccessD", linkageName: "_CAccessD.Main", scope: null, file: !7, line: 14, type: !19, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !23)
-// CHECK:STDOUT: !19 = !DISubroutineType(types: !20)
-// CHECK:STDOUT: !20 = !{!21, !22}
-// CHECK:STDOUT: !21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-// CHECK:STDOUT: !22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
-// CHECK:STDOUT: !23 = !{!24}
-// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !18, type: !22)
-// CHECK:STDOUT: !25 = !DILocation(line: 16, column: 10, scope: !18)
-// CHECK:STDOUT: !26 = !DILocation(line: 16, column: 3, scope: !18)
-// CHECK:STDOUT: !27 = !{!28, !28, i64 0}
-// CHECK:STDOUT: !28 = !{!"p1 _ZTS1D", !29, i64 0}
-// CHECK:STDOUT: !29 = !{!"any pointer", !10, i64 0}
-// CHECK:STDOUT: !30 = !{!31, !31, i64 0}
-// CHECK:STDOUT: !31 = !{!"vtable pointer", !11, i64 0}
+// CHECK:STDOUT: !12 = !{!13, !13, i64 0}
+// CHECK:STDOUT: !13 = !{!"p1 _ZTS1D", !14, i64 0}
+// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0}
+// CHECK:STDOUT: !15 = !{!16, !16, i64 0}
+// CHECK:STDOUT: !16 = !{!"vtable pointer", !11, i64 0}
+// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "Make", linkageName: "_CMake.Main", scope: null, file: !7, line: 6, type: !18, spFlags: DISPFlagDefinition, unit: !6)
+// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
+// CHECK:STDOUT: !19 = !{null}
+// CHECK:STDOUT: !20 = !DILocation(line: 11, column: 3, scope: !17)
+// CHECK:STDOUT: !21 = !DILocation(line: 11, column: 18, scope: !17)
+// CHECK:STDOUT: !22 = !DILocation(line: 6, column: 1, scope: !17)
+// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "AccessD", linkageName: "_CAccessD.Main", scope: null, file: !7, line: 14, type: !24, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !28)
+// CHECK:STDOUT: !24 = !DISubroutineType(types: !25)
+// CHECK:STDOUT: !25 = !{!26, !27}
+// CHECK:STDOUT: !26 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK:STDOUT: !27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !28 = !{!29}
+// CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !23, type: !27)
+// CHECK:STDOUT: !30 = !DILocation(line: 16, column: 10, scope: !23)
+// CHECK:STDOUT: !31 = !DILocation(line: 16, column: 3, scope: !23)

+ 11 - 9
toolchain/lower/testdata/interop/cpp/void.carbon

@@ -73,7 +73,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT:   ret void, !dbg !20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z13take_void_ptrPv(ptr)
+// CHECK:STDOUT: declare void @_Z13take_void_ptrPv(ptr noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define void @_CPassIntPtr.Main(ptr %a) #0 !dbg !21 {
@@ -99,7 +99,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT:   ret void, !dbg !32
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @_Z19take_const_void_ptrPKv(ptr)
+// CHECK:STDOUT: declare void @_Z19take_const_void_ptrPKv(ptr noundef) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define void @_CPassConstIntPtrToConstVoidPtr.Main(ptr %a) #0 !dbg !33 {
@@ -120,7 +120,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // 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 ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.63e244d930b21b2a"(ptr %self) #0 !dbg !47 {
@@ -168,7 +168,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert:thunk.e8f8f92d3d08d149:ImplicitAs.ffd58aeb29886b72.Core.b88d1103f417c6d4"(ptr %self) #2 !dbg !79 {
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert:thunk.e8f8f92d3d08d149:ImplicitAs.ffd58aeb29886b72.Core.b88d1103f417c6d4"(ptr %self) #3 !dbg !79 {
 // CHECK:STDOUT:   ret ptr %self, !dbg !83
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -187,8 +187,9 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT: uselistorder ptr @_CSome.Optional.Core.d2075df181ac34c1, { 2, 1, 0 }
 // CHECK:STDOUT:
 // CHECK:STDOUT: attributes #0 = { nounwind }
-// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-// CHECK:STDOUT: attributes #2 = { alwaysinline 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 #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #3 = { alwaysinline nounwind }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -197,7 +198,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
@@ -297,7 +298,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT:   ret ptr %return_void_ptr.call, !dbg !17
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare ptr @_Z15return_void_ptrv()
+// CHECK:STDOUT: declare noundef ptr @_Z15return_void_ptrv() #1
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define ptr @_CConvertFromVoidPtr.Main(ptr %p) #0 !dbg !18 {
@@ -312,6 +313,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT: }
 // 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:
 // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 // CHECK:STDOUT: !llvm.dbg.cu = !{!6}
@@ -320,7 +322,7 @@ fn ConvertFromConstVoidPtr(p: const Cpp.void*) -> const i32* {
 // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
-// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
+// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2}
 // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
 // CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2}
 // CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)