Просмотр исходного кода

Promote FunctionType to a standard instruction. (#3931)

This removes the builtin FunctionType, replacing it with a FunctionType
instruction. The constant for a FunctionDecl is now a StructValue with
type of FunctionType.

Note this means a function declaration produces _both_ a type, and a
value of the type. This has some consequences in terms of circularity,
and makes the importing of function declarations a little more complex.

It'll get particularly peculiar for imports because of the behavior of
the reference, but that's a known issue due to other things such as
`alias`. The impact will hopefully be contained to
ResolvePrevInstForMerge (and ImportRefs).

To note a small formatting change in diagnostics:

```
-  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated <function> in Interface>` is not callable.
+  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated F in Interface>` is not callable.

-  // CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated <function> in Interface>` is not callable.
+  // CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated F in Interface>` is not callable.
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Jon Ross-Perkins 2 лет назад
Родитель
Сommit
76ed3c73cb
100 измененных файлов с 3361 добавлено и 2447 удалено
  1. 2 0
      toolchain/check/BUILD
  2. 9 29
      toolchain/check/call.cpp
  3. 9 1
      toolchain/check/context.cpp
  4. 3 0
      toolchain/check/context.h
  5. 30 13
      toolchain/check/eval.cpp
  6. 55 25
      toolchain/check/handle_function.cpp
  7. 39 27
      toolchain/check/impl.cpp
  8. 20 4
      toolchain/check/import_ref.cpp
  9. 41 55
      toolchain/check/member_access.cpp
  10. 4 2
      toolchain/check/testdata/alias/no_prelude/fail_local_in_namespace.carbon
  11. 4 2
      toolchain/check/testdata/alias/no_prelude/fail_not_constant.carbon
  12. 8 6
      toolchain/check/testdata/alias/no_prelude/in_namespace.carbon
  13. 4 2
      toolchain/check/testdata/alias/no_prelude/local.carbon
  14. 22 17
      toolchain/check/testdata/array/array_in_place.carbon
  15. 34 31
      toolchain/check/testdata/array/array_vs_tuple.carbon
  16. 19 14
      toolchain/check/testdata/array/assign_return_value.carbon
  17. 30 27
      toolchain/check/testdata/array/canonicalize_index.carbon
  18. 10 7
      toolchain/check/testdata/array/fail_bound_negative.carbon
  19. 24 19
      toolchain/check/testdata/array/function_param.carbon
  20. 25 22
      toolchain/check/testdata/as/adapter_conversion.carbon
  21. 7 4
      toolchain/check/testdata/as/basic.carbon
  22. 17 9
      toolchain/check/testdata/as/identity.carbon
  23. 23 17
      toolchain/check/testdata/as/no_prelude/tuple.carbon
  24. 0 2
      toolchain/check/testdata/basics/builtin_insts.carbon
  25. 4 2
      toolchain/check/testdata/basics/fail_bad_run.carbon
  26. 8 2
      toolchain/check/testdata/basics/fail_bad_run_2.carbon
  27. 16 4
      toolchain/check/testdata/basics/multifile.carbon
  28. 8 2
      toolchain/check/testdata/basics/no_prelude/fail_name_lookup.carbon
  29. 44 14
      toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon
  30. 28 10
      toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon
  31. 54 47
      toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon
  32. 12 6
      toolchain/check/testdata/basics/no_prelude/raw_identifier.carbon
  33. 50 45
      toolchain/check/testdata/basics/no_prelude/raw_ir.carbon
  34. 4 2
      toolchain/check/testdata/basics/no_prelude/textual_ir.carbon
  35. 2 2
      toolchain/check/testdata/basics/no_prelude/verbose.carbon
  36. 69 66
      toolchain/check/testdata/basics/numeric_literals.carbon
  37. 8 2
      toolchain/check/testdata/basics/run.carbon
  38. 7 4
      toolchain/check/testdata/basics/run_i32.carbon
  39. 15 6
      toolchain/check/testdata/builtins/bool/make_type.carbon
  40. 52 29
      toolchain/check/testdata/builtins/float/add.carbon
  41. 69 46
      toolchain/check/testdata/builtins/float/div.carbon
  42. 25 13
      toolchain/check/testdata/builtins/float/eq.carbon
  43. 26 18
      toolchain/check/testdata/builtins/float/greater.carbon
  44. 26 18
      toolchain/check/testdata/builtins/float/greater_eq.carbon
  45. 26 18
      toolchain/check/testdata/builtins/float/less.carbon
  46. 26 18
      toolchain/check/testdata/builtins/float/less_eq.carbon
  47. 32 18
      toolchain/check/testdata/builtins/float/make_type.carbon
  48. 52 29
      toolchain/check/testdata/builtins/float/mul.carbon
  49. 52 29
      toolchain/check/testdata/builtins/float/negate.carbon
  50. 25 13
      toolchain/check/testdata/builtins/float/neq.carbon
  51. 52 29
      toolchain/check/testdata/builtins/float/sub.carbon
  52. 23 18
      toolchain/check/testdata/builtins/int/and.carbon
  53. 32 25
      toolchain/check/testdata/builtins/int/complement.carbon
  54. 25 13
      toolchain/check/testdata/builtins/int/eq.carbon
  55. 26 18
      toolchain/check/testdata/builtins/int/greater.carbon
  56. 26 18
      toolchain/check/testdata/builtins/int/greater_eq.carbon
  57. 77 67
      toolchain/check/testdata/builtins/int/left_shift.carbon
  58. 26 18
      toolchain/check/testdata/builtins/int/less.carbon
  59. 26 18
      toolchain/check/testdata/builtins/int/less_eq.carbon
  60. 15 6
      toolchain/check/testdata/builtins/int/make_type_32.carbon
  61. 87 61
      toolchain/check/testdata/builtins/int/make_type_signed.carbon
  62. 87 61
      toolchain/check/testdata/builtins/int/make_type_unsigned.carbon
  63. 17 11
      toolchain/check/testdata/builtins/int/neq.carbon
  64. 23 18
      toolchain/check/testdata/builtins/int/or.carbon
  65. 109 94
      toolchain/check/testdata/builtins/int/right_shift.carbon
  66. 92 69
      toolchain/check/testdata/builtins/int/sadd.carbon
  67. 102 87
      toolchain/check/testdata/builtins/int/sdiv.carbon
  68. 103 88
      toolchain/check/testdata/builtins/int/smod.carbon
  69. 45 37
      toolchain/check/testdata/builtins/int/smul.carbon
  70. 111 86
      toolchain/check/testdata/builtins/int/snegate.carbon
  71. 62 54
      toolchain/check/testdata/builtins/int/ssub.carbon
  72. 92 69
      toolchain/check/testdata/builtins/int/uadd.carbon
  73. 103 88
      toolchain/check/testdata/builtins/int/udiv.carbon
  74. 103 88
      toolchain/check/testdata/builtins/int/umod.carbon
  75. 45 37
      toolchain/check/testdata/builtins/int/umul.carbon
  76. 111 86
      toolchain/check/testdata/builtins/int/unegate.carbon
  77. 62 54
      toolchain/check/testdata/builtins/int/usub.carbon
  78. 23 18
      toolchain/check/testdata/builtins/int/xor.carbon
  79. 10 6
      toolchain/check/testdata/class/adapt.carbon
  80. 29 24
      toolchain/check/testdata/class/base.carbon
  81. 8 5
      toolchain/check/testdata/class/base_field.carbon
  82. 17 11
      toolchain/check/testdata/class/base_function_unqualified.carbon
  83. 22 18
      toolchain/check/testdata/class/base_method.carbon
  84. 50 34
      toolchain/check/testdata/class/base_method_qualified.carbon
  85. 26 18
      toolchain/check/testdata/class/base_method_shadow.carbon
  86. 19 12
      toolchain/check/testdata/class/basic.carbon
  87. 8 5
      toolchain/check/testdata/class/complete_in_member_fn.carbon
  88. 26 17
      toolchain/check/testdata/class/compound_field.carbon
  89. 8 2
      toolchain/check/testdata/class/cross_package_import.carbon
  90. 51 38
      toolchain/check/testdata/class/derived_to_base.carbon
  91. 41 26
      toolchain/check/testdata/class/extend_adapt.carbon
  92. 4 1
      toolchain/check/testdata/class/extern.carbon
  93. 21 16
      toolchain/check/testdata/class/fail_abstract.carbon
  94. 10 4
      toolchain/check/testdata/class/fail_adapt_bad_decl.carbon
  95. 10 5
      toolchain/check/testdata/class/fail_addr_not_self.carbon
  96. 24 18
      toolchain/check/testdata/class/fail_addr_self.carbon
  97. 66 40
      toolchain/check/testdata/class/fail_base_bad_type.carbon
  98. 17 9
      toolchain/check/testdata/class/fail_base_method_define.carbon
  99. 3 0
      toolchain/check/testdata/class/fail_base_misplaced.carbon
  100. 7 4
      toolchain/check/testdata/class/fail_compound_type_mismatch.carbon

+ 2 - 0
toolchain/check/BUILD

@@ -177,6 +177,7 @@ cc_library(
     deps = [
         ":context",
         "//common:check",
+        "//toolchain/base:kind_switch",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/sem_ir:file",
         "//toolchain/sem_ir:ids",
@@ -222,6 +223,7 @@ cc_library(
     deps = [
         ":context",
         "//common:check",
+        "//toolchain/base:kind_switch",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/sem_ir:file",
         "//toolchain/sem_ir:ids",

+ 9 - 29
toolchain/check/call.cpp

@@ -15,38 +15,18 @@ namespace Carbon::Check {
 auto PerformCall(Context& context, Parse::NodeId node_id,
                  SemIR::InstId callee_id, llvm::ArrayRef<SemIR::InstId> arg_ids)
     -> SemIR::InstId {
-  auto diagnose_not_callable = [&] {
-    auto callee_type_id = context.insts().Get(callee_id).type_id();
-    if (callee_type_id != SemIR::TypeId::Error) {
+  // Identify the function we're calling.
+  auto callee_function = GetCalleeFunction(context.sem_ir(), callee_id);
+  if (!callee_function.function_id.is_valid()) {
+    if (!callee_function.is_error) {
       CARBON_DIAGNOSTIC(CallToNonCallable, Error,
                         "Value of type `{0}` is not callable.", SemIR::TypeId);
-      context.emitter().Emit(node_id, CallToNonCallable, callee_type_id);
+      context.emitter().Emit(node_id, CallToNonCallable,
+                             context.insts().Get(callee_id).type_id());
     }
     return SemIR::InstId::BuiltinError;
-  };
-
-  // For a method call, pick out the `self` value.
-  auto function_callee_id = callee_id;
-  SemIR::InstId self_id = SemIR::InstId::Invalid;
-  if (auto bound_method =
-          context.insts().Get(callee_id).TryAs<SemIR::BoundMethod>()) {
-    self_id = bound_method->object_id;
-    function_callee_id = bound_method->function_id;
-  }
-
-  // Identify the function we're calling.
-  auto function_decl_id = context.constant_values().Get(function_callee_id);
-  if (!function_decl_id.is_constant()) {
-    return diagnose_not_callable();
-  }
-  auto function_decl = context.insts()
-                           .Get(function_decl_id.inst_id())
-                           .TryAs<SemIR::FunctionDecl>();
-  if (!function_decl) {
-    return diagnose_not_callable();
   }
-  auto function_id = function_decl->function_id;
-  auto& callable = context.functions().Get(function_id);
+  auto& callable = context.functions().Get(callee_function.function_id);
 
   // For functions with an implicit return type, the return type is the empty
   // tuple type.
@@ -85,8 +65,8 @@ auto PerformCall(Context& context, Parse::NodeId node_id,
 
   // Convert the arguments to match the parameters.
   auto converted_args_id =
-      ConvertCallArgs(context, node_id, self_id, arg_ids, return_storage_id,
-                      function_decl_id.inst_id(),
+      ConvertCallArgs(context, node_id, callee_function.self_id, arg_ids,
+                      return_storage_id, callable.decl_id,
                       callable.implicit_param_refs_id, callable.param_refs_id);
   auto call_inst_id = context.AddInst(
       {node_id, SemIR::Call{type_id, callee_id, converted_args_id}});

+ 9 - 1
toolchain/check/context.cpp

@@ -814,7 +814,6 @@ class TypeCompleter {
       case SemIR::BuiltinKind::IntType:
       case SemIR::BuiltinKind::FloatType:
       case SemIR::BuiltinKind::NamespaceType:
-      case SemIR::BuiltinKind::FunctionType:
       case SemIR::BuiltinKind::BoundMethodType:
       case SemIR::BuiltinKind::WitnessType:
         return MakeCopyValueRepr(type_id);
@@ -956,6 +955,7 @@ class TypeCompleter {
                                     SemIR::ValueRepr::ObjectAggregate);
       }
       case SemIR::AssociatedEntityType::Kind:
+      case SemIR::FunctionType::Kind:
       case SemIR::InterfaceType::Kind:
       case SemIR::UnboundElementType::Kind: {
         // These types have no runtime operations, so we use an empty value
@@ -1065,6 +1065,14 @@ auto Context::GetBuiltinType(SemIR::BuiltinKind kind) -> SemIR::TypeId {
   return type_id;
 }
 
+auto Context::GetFunctionType(SemIR::FunctionId fn_id) -> SemIR::TypeId {
+  auto type_id = GetTypeImpl<SemIR::FunctionType>(*this, fn_id);
+  // To keep client code simpler, complete function types before returning them.
+  bool complete = TryToCompleteType(type_id);
+  CARBON_CHECK(complete) << "Failed to complete function type";
+  return type_id;
+}
+
 auto Context::GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId {
   return GetTypeImpl<SemIR::PointerType>(*this, pointee_type_id);
 }

+ 3 - 0
toolchain/check/context.h

@@ -240,6 +240,9 @@ class Context {
   // Gets a builtin type. The returned type will be complete.
   auto GetBuiltinType(SemIR::BuiltinKind kind) -> SemIR::TypeId;
 
+  // Gets a function type. The returned type will be complete.
+  auto GetFunctionType(SemIR::FunctionId fn_id) -> SemIR::TypeId;
+
   // Returns a pointer type whose pointee type is `pointee_type_id`.
   auto GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId;
 

+ 30 - 13
toolchain/check/eval.cpp

@@ -8,6 +8,7 @@
 #include "toolchain/check/diagnostic_helpers.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/sem_ir/builtin_function_kind.h"
+#include "toolchain/sem_ir/function.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/typed_insts.h"
 
@@ -687,10 +688,12 @@ static auto PerformBuiltinFloatComparison(
   return MakeBoolResult(context, bool_type_id, result);
 }
 
-static auto PerformBuiltinCall(Context& context, SemIRLoc loc, SemIR::Call call,
-                               SemIR::BuiltinFunctionKind builtin_kind,
-                               llvm::ArrayRef<SemIR::InstId> arg_ids,
-                               Phase phase) -> SemIR::ConstantId {
+// Returns a constant for a call to a builtin function.
+static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc,
+                                       SemIR::Call call,
+                                       SemIR::BuiltinFunctionKind builtin_kind,
+                                       llvm::ArrayRef<SemIR::InstId> arg_ids,
+                                       Phase phase) -> SemIR::ConstantId {
   switch (builtin_kind) {
     case SemIR::BuiltinFunctionKind::None:
       CARBON_FATAL() << "Not a builtin function.";
@@ -810,8 +813,9 @@ static auto PerformBuiltinCall(Context& context, SemIRLoc loc, SemIR::Call call,
   return SemIR::ConstantId::NotConstant;
 }
 
-static auto PerformCall(Context& context, SemIRLoc loc, SemIR::Call call)
-    -> SemIR::ConstantId {
+// Makes a constant for a call instruction.
+static auto MakeConstantForCall(Context& context, SemIRLoc loc,
+                                SemIR::Call call) -> SemIR::ConstantId {
   Phase phase = Phase::Template;
 
   // A call with an invalid argument list is used to represent an erroneous
@@ -828,10 +832,15 @@ static auto PerformCall(Context& context, SemIRLoc loc, SemIR::Call call)
     return SemIR::ConstantId::NotConstant;
   }
 
+  auto callee_function =
+      SemIR::GetCalleeFunction(context.sem_ir(), call.callee_id);
+  if (!callee_function.function_id.is_valid()) {
+    return SemIR::ConstantId::Error;
+  }
+  const auto& function = context.functions().Get(callee_function.function_id);
+
   // Handle calls to builtins.
-  if (auto builtin_function_kind = SemIR::BuiltinFunctionKind::ForCallee(
-          context.sem_ir(), call.callee_id);
-      builtin_function_kind != SemIR::BuiltinFunctionKind::None) {
+  if (function.builtin_kind != SemIR::BuiltinFunctionKind::None) {
     if (!ReplaceFieldWithConstantValue(context, &call, &SemIR::Call::args_id,
                                        &phase)) {
       return SemIR::ConstantId::NotConstant;
@@ -839,8 +848,9 @@ static auto PerformCall(Context& context, SemIRLoc loc, SemIR::Call call)
     if (phase == Phase::UnknownDueToError) {
       return SemIR::ConstantId::Error;
     }
-    return PerformBuiltinCall(context, loc, call, builtin_function_kind,
-                              context.inst_blocks().Get(call.args_id), phase);
+    return MakeConstantForBuiltinCall(context, loc, call, function.builtin_kind,
+                                      context.inst_blocks().Get(call.args_id),
+                                      phase);
   }
   return SemIR::ConstantId::NotConstant;
 }
@@ -955,9 +965,17 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
 
     case SemIR::AssociatedEntity::Kind:
     case SemIR::Builtin::Kind:
+    case SemIR::FunctionType::Kind:
       // Builtins are always template constants.
       return MakeConstantResult(context, inst, Phase::Template);
 
+    case CARBON_KIND(SemIR::FunctionDecl fn_decl): {
+      return MakeConstantResult(
+          context,
+          SemIR::StructValue{fn_decl.type_id, SemIR::InstBlockId::Empty},
+          Phase::Template);
+    }
+
     case CARBON_KIND(SemIR::ClassDecl class_decl): {
       // TODO: Once classes have generic arguments, handle them.
       return MakeConstantResult(
@@ -986,7 +1004,6 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::AssociatedConstantDecl::Kind:
     case SemIR::BaseDecl::Kind:
     case SemIR::FieldDecl::Kind:
-    case SemIR::FunctionDecl::Kind:
     case SemIR::Namespace::Kind:
       return SemIR::ConstantId::ForTemplateConstant(inst_id);
 
@@ -1012,7 +1029,7 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
       return PerformAggregateIndex(context, inst);
 
     case CARBON_KIND(SemIR::Call call): {
-      return PerformCall(context, inst_id, call);
+      return MakeConstantForCall(context, inst_id, call);
     }
 
     // TODO: These need special handling.

+ 55 - 25
toolchain/check/handle_function.cpp

@@ -2,6 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+#include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/decl_name_stack.h"
@@ -60,6 +61,55 @@ static auto DiagnoseModifiers(Context& context, bool is_definition,
   return context.decl_state_stack().innermost().modifier_set;
 }
 
+// Returns the function ID for the instruction, or invalid.
+static auto GetRedeclFunctionId(Context& context, SemIR::Inst prev_inst)
+    -> SemIR::FunctionId {
+  CARBON_KIND_SWITCH(prev_inst) {
+    case CARBON_KIND(SemIR::StructValue struct_value): {
+      if (auto fn_type = context.types().TryGetAs<SemIR::FunctionType>(
+              struct_value.type_id)) {
+        return fn_type->function_id;
+      }
+      return SemIR::FunctionId::Invalid;
+    }
+    case CARBON_KIND(SemIR::FunctionDecl fn_decl): {
+      return fn_decl.function_id;
+    }
+    default:
+      // This is a redeclaration of something other than a function. This
+      // includes the case where an associated function redeclares another
+      // associated function.
+      return SemIR::FunctionId::Invalid;
+  }
+}
+
+// Check whether this is a redeclaration, merging if needed.
+static auto TryMergeRedecl(Context& context, Parse::AnyFunctionDeclId node_id,
+                           SemIR::InstId prev_id,
+                           SemIR::FunctionDecl& function_decl,
+                           SemIR::Function& function_info, bool is_definition)
+    -> void {
+  if (!prev_id.is_valid()) {
+    return;
+  }
+
+  auto prev_inst_for_merge = ResolvePrevInstForMerge(context, node_id, prev_id);
+  auto prev_function_id =
+      GetRedeclFunctionId(context, prev_inst_for_merge.inst);
+  if (!prev_function_id.is_valid()) {
+    context.DiagnoseDuplicateName(function_info.decl_id, prev_id);
+    return;
+  }
+
+  if (MergeFunctionRedecl(context, node_id, function_info,
+                          /*new_is_import=*/false, is_definition,
+                          prev_function_id,
+                          prev_inst_for_merge.import_ir_inst_id)) {
+    // When merging, use the existing function rather than adding a new one.
+    function_decl.function_id = prev_function_id;
+  }
+}
+
 // Build a FunctionDecl describing the signature of a function. This
 // handles the common logic shared by function declaration syntax and function
 // definition syntax.
@@ -116,8 +166,7 @@ static auto BuildFunctionDecl(Context& context,
 
   // Add the function declaration.
   auto function_decl = SemIR::FunctionDecl{
-      context.GetBuiltinType(SemIR::BuiltinKind::FunctionType),
-      SemIR::FunctionId::Invalid, decl_block_id};
+      SemIR::TypeId::Invalid, SemIR::FunctionId::Invalid, decl_block_id};
   auto function_info = SemIR::Function{
       .name_id = name_context.name_id_for_new_inst(),
       .enclosing_scope_id = name_context.enclosing_scope_id_for_new_inst(),
@@ -132,40 +181,21 @@ static auto BuildFunctionDecl(Context& context,
     function_info.definition_id = function_info.decl_id;
   }
 
-  // Check whether this is a redeclaration.
-  auto prev_id = name_context.prev_inst_id();
-  if (prev_id.is_valid()) {
-    auto prev_inst_for_merge =
-        ResolvePrevInstForMerge(context, node_id, prev_id);
-
-    if (auto prev_function_decl =
-            prev_inst_for_merge.inst.TryAs<SemIR::FunctionDecl>()) {
-      if (MergeFunctionRedecl(context, node_id, function_info,
-                              /*new_is_import=*/false, is_definition,
-                              prev_function_decl->function_id,
-                              prev_inst_for_merge.import_ir_inst_id)) {
-        // When merging, use the existing function rather than adding a new one.
-        function_decl.function_id = prev_function_decl->function_id;
-      }
-    } else {
-      // This is a redeclaration of something other than a function. This
-      // includes the case where an associated function redeclares another
-      // associated function.
-      context.DiagnoseDuplicateName(function_info.decl_id, prev_id);
-    }
-  }
+  TryMergeRedecl(context, node_id, name_context.prev_inst_id(), function_decl,
+                 function_info, is_definition);
 
   // Create a new function if this isn't a valid redeclaration.
   if (!function_decl.function_id.is_valid()) {
     function_decl.function_id = context.functions().Add(function_info);
   }
+  function_decl.type_id = context.GetFunctionType(function_decl.function_id);
 
   // Write the function ID into the FunctionDecl.
   context.ReplaceInstBeforeConstantUse(function_info.decl_id, function_decl);
 
   // Check if we need to add this to name lookup, now that the function decl is
   // done.
-  if (!prev_id.is_valid()) {
+  if (!name_context.prev_inst_id().is_valid()) {
     // At interface scope, a function declaration introduces an associated
     // function.
     auto lookup_result_id = function_info.decl_id;

+ 39 - 27
toolchain/check/impl.cpp

@@ -4,6 +4,7 @@
 
 #include "toolchain/check/impl.h"
 
+#include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/function.h"
 #include "toolchain/check/import_ref.h"
@@ -93,34 +94,45 @@ static auto BuildInterfaceWitness(
     auto const_id = context.constant_values().Get(decl_id);
     CARBON_CHECK(const_id.is_constant()) << "Non-constant associated entity";
     auto decl = context.insts().Get(const_id.inst_id());
-    if (auto fn_decl = decl.TryAs<SemIR::FunctionDecl>()) {
-      auto& fn = context.functions().Get(fn_decl->function_id);
-      auto impl_decl_id = context.LookupNameInExactScope(
-          decl_id, fn.name_id, impl_scope, /*mark_imports_used=*/true);
-      if (impl_decl_id.is_valid()) {
-        used_decl_ids.push_back(impl_decl_id);
-        table.push_back(CheckAssociatedFunctionImplementation(
-            context, fn_decl->function_id, impl_decl_id, substitutions));
-      } else {
-        CARBON_DIAGNOSTIC(
-            ImplMissingFunction, Error,
-            "Missing implementation of {0} in impl of interface {1}.",
-            SemIR::NameId, SemIR::NameId);
-        auto builder =
-            context.emitter().Build(impl.definition_id, ImplMissingFunction,
-                                    fn.name_id, interface.name_id);
-        NoteAssociatedFunction(context, builder, fn_decl->function_id);
-        builder.Emit();
-
-        table.push_back(SemIR::InstId::BuiltinError);
+    CARBON_KIND_SWITCH(decl) {
+      case CARBON_KIND(SemIR::StructValue struct_value): {
+        if (struct_value.type_id == SemIR::TypeId::Error) {
+          return SemIR::InstId::BuiltinError;
+        }
+        auto type_inst = context.types().GetAsInst(struct_value.type_id);
+        auto fn_type = type_inst.TryAs<SemIR::FunctionType>();
+        if (!fn_type) {
+          CARBON_FATAL() << "Unexpected type: " << type_inst;
+        }
+        auto& fn = context.functions().Get(fn_type->function_id);
+        auto impl_decl_id = context.LookupNameInExactScope(
+            decl_id, fn.name_id, impl_scope, /*mark_imports_used=*/true);
+        if (impl_decl_id.is_valid()) {
+          used_decl_ids.push_back(impl_decl_id);
+          table.push_back(CheckAssociatedFunctionImplementation(
+              context, fn_type->function_id, impl_decl_id, substitutions));
+        } else {
+          CARBON_DIAGNOSTIC(
+              ImplMissingFunction, Error,
+              "Missing implementation of {0} in impl of interface {1}.",
+              SemIR::NameId, SemIR::NameId);
+          auto builder =
+              context.emitter().Build(impl.definition_id, ImplMissingFunction,
+                                      fn.name_id, interface.name_id);
+          NoteAssociatedFunction(context, builder, fn_type->function_id);
+          builder.Emit();
+
+          table.push_back(SemIR::InstId::BuiltinError);
+        }
+        break;
       }
-    } else if (auto const_decl = decl.TryAs<SemIR::AssociatedConstantDecl>()) {
-      // TODO: Check we have a value for this constant in the constraint.
-      context.TODO(impl.definition_id,
-                   "impl of interface with associated constant");
-      return SemIR::InstId::BuiltinError;
-    } else {
-      CARBON_FATAL() << "Unexpected kind of associated entity " << decl;
+      case SemIR::AssociatedConstantDecl::Kind:
+        // TODO: Check we have a value for this constant in the constraint.
+        context.TODO(impl.definition_id,
+                     "impl of interface with associated constant");
+        return SemIR::InstId::BuiltinError;
+      default:
+        CARBON_FATAL() << "Unexpected kind of associated entity " << decl;
     }
   }
 

+ 20 - 4
toolchain/check/import_ref.cpp

@@ -549,6 +549,9 @@ class ImportRefResolver {
       case CARBON_KIND(SemIR::FunctionDecl inst): {
         return TryResolveTypedInst(inst);
       }
+      case CARBON_KIND(SemIR::FunctionType inst): {
+        return TryResolveTypedInst(inst);
+      }
       case CARBON_KIND(SemIR::ImportRefUsed inst): {
         return TryResolveTypedInst(inst, inst_id);
       }
@@ -822,7 +825,6 @@ class ImportRefResolver {
 
   auto TryResolveTypedInst(SemIR::FunctionDecl inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
-    auto type_const_id = GetLocalConstantId(inst.type_id);
 
     const auto& function = import_ir_.functions().Get(inst.function_id);
     auto return_type_const_id = SemIR::ConstantId::Invalid;
@@ -840,9 +842,9 @@ class ImportRefResolver {
     }
 
     // Add the function declaration.
-    auto function_decl = SemIR::FunctionDecl{
-        context_.GetTypeIdForTypeConstant(type_const_id),
-        SemIR::FunctionId::Invalid, SemIR::InstBlockId::Empty};
+    auto function_decl =
+        SemIR::FunctionDecl{SemIR::TypeId::Invalid, SemIR::FunctionId::Invalid,
+                            SemIR::InstBlockId::Empty};
     // Prefer pointing diagnostics towards a definition.
     auto import_ir_inst_id = AddImportIRInst(function.definition_id.is_valid()
                                                  ? function.definition_id
@@ -879,11 +881,25 @@ class ImportRefResolver {
          .definition_id = function.definition_id.is_valid()
                               ? function_decl_id
                               : SemIR::InstId::Invalid});
+    function_decl.type_id = context_.GetFunctionType(function_decl.function_id);
     // Write the function ID into the FunctionDecl.
     context_.ReplaceInstBeforeConstantUse(function_decl_id, function_decl);
     return {context_.constant_values().Get(function_decl_id)};
   }
 
+  auto TryResolveTypedInst(SemIR::FunctionType inst) -> ResolveResult {
+    auto initial_work = work_stack_.size();
+    CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
+    auto fn_const_id = GetLocalConstantId(
+        import_ir_.functions().Get(inst.function_id).decl_id);
+    if (HasNewWork(initial_work)) {
+      return ResolveResult::Retry();
+    }
+    auto fn_val = context_.insts().Get(fn_const_id.inst_id());
+    CARBON_CHECK(context_.types().Is<SemIR::FunctionType>(fn_val.type_id()));
+    return {context_.types().GetConstantId(fn_val.type_id())};
+  }
+
   auto TryResolveTypedInst(SemIR::ImportRefUsed /*inst*/, SemIR::InstId inst_id)
       -> ResolveResult {
     auto initial_work = work_stack_.size();

+ 41 - 55
toolchain/check/member_access.cpp

@@ -3,6 +3,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 #include "llvm/ADT/STLExtras.h"
+#include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/convert.h"
 #include "toolchain/check/import_ref.h"
@@ -243,64 +244,49 @@ static auto PerformInstanceBinding(Context& context, Parse::NodeId node_id,
                                    SemIR::InstId base_id,
                                    SemIR::InstId member_id) -> SemIR::InstId {
   auto member_type_id = context.insts().Get(member_id).type_id();
-  if (auto unbound_element_type =
-          context.types().TryGetAs<SemIR::UnboundElementType>(member_type_id)) {
-    // Convert the base to the type of the element if necessary.
-    base_id = ConvertToValueOrRefOfType(context, node_id, base_id,
-                                        unbound_element_type->class_type_id);
-
-    // Find the specified element, which could be either a field or a base
-    // class, and build an element access expression.
-    auto element_id = context.constant_values().Get(member_id);
-    CARBON_CHECK(element_id.is_constant())
-        << "Non-constant value " << context.insts().Get(member_id)
-        << " of unbound element type";
-    auto index = GetClassElementIndex(context, element_id.inst_id());
-    auto access_id = context.AddInst(
-        {node_id, SemIR::ClassElementAccess{
-                      unbound_element_type->element_type_id, base_id, index}});
-    if (SemIR::GetExprCategory(context.sem_ir(), base_id) ==
-            SemIR::ExprCategory::Value &&
-        SemIR::GetExprCategory(context.sem_ir(), access_id) !=
-            SemIR::ExprCategory::Value) {
-      // Class element access on a value expression produces an ephemeral
-      // reference if the class's value representation is a pointer to the
-      // object representation. Add a value binding in that case so that the
-      // expression category of the result matches the expression category of
-      // the base.
-      access_id = ConvertToValueExpr(context, access_id);
-    }
-    return access_id;
-  }
-
-  if (member_type_id ==
-      context.GetBuiltinType(SemIR::BuiltinKind::FunctionType)) {
-    // Find the named function and check whether it's an instance method.
-    auto function_name_id = context.constant_values().Get(member_id);
-    if (function_name_id == SemIR::ConstantId::Error) {
-      return SemIR::InstId::BuiltinError;
+  CARBON_KIND_SWITCH(context.types().GetAsInst(member_type_id)) {
+    case CARBON_KIND(SemIR::UnboundElementType unbound_element_type): {
+      // Convert the base to the type of the element if necessary.
+      base_id = ConvertToValueOrRefOfType(context, node_id, base_id,
+                                          unbound_element_type.class_type_id);
+
+      // Find the specified element, which could be either a field or a base
+      // class, and build an element access expression.
+      auto element_id = context.constant_values().Get(member_id);
+      CARBON_CHECK(element_id.is_constant())
+          << "Non-constant value " << context.insts().Get(member_id)
+          << " of unbound element type";
+      auto index = GetClassElementIndex(context, element_id.inst_id());
+      auto access_id = context.AddInst(
+          {node_id, SemIR::ClassElementAccess{
+                        unbound_element_type.element_type_id, base_id, index}});
+      if (SemIR::GetExprCategory(context.sem_ir(), base_id) ==
+              SemIR::ExprCategory::Value &&
+          SemIR::GetExprCategory(context.sem_ir(), access_id) !=
+              SemIR::ExprCategory::Value) {
+        // Class element access on a value expression produces an ephemeral
+        // reference if the class's value representation is a pointer to the
+        // object representation. Add a value binding in that case so that the
+        // expression category of the result matches the expression category of
+        // the base.
+        access_id = ConvertToValueExpr(context, access_id);
+      }
+      return access_id;
     }
-
-    CARBON_CHECK(function_name_id.is_constant())
-        << "Non-constant value " << context.insts().Get(member_id)
-        << " of function type";
-    auto function_decl = context.insts()
-                             .Get(function_name_id.inst_id())
-                             .TryAs<SemIR::FunctionDecl>();
-    CARBON_CHECK(function_decl)
-        << "Unexpected value "
-        << context.insts().Get(function_name_id.inst_id())
-        << " of function type";
-    if (IsInstanceMethod(context.sem_ir(), function_decl->function_id)) {
-      return context.AddInst(
-          {node_id, SemIR::BoundMethod{context.GetBuiltinType(
-                                           SemIR::BuiltinKind::BoundMethodType),
-                                       base_id, member_id}});
+    case CARBON_KIND(SemIR::FunctionType fn_type): {
+      if (IsInstanceMethod(context.sem_ir(), fn_type.function_id)) {
+        return context.AddInst(
+            {node_id,
+             SemIR::BoundMethod{
+                 context.GetBuiltinType(SemIR::BuiltinKind::BoundMethodType),
+                 base_id, member_id}});
+      }
+      [[fallthrough]];
     }
+    default:
+      // Not an instance member: no instance binding.
+      return member_id;
   }
-
-  // Not an instance member: no instance binding.
-  return member_id;
 }
 
 auto PerformMemberAccess(Context& context, Parse::NodeId node_id,

+ 4 - 2
toolchain/check/testdata/alias/no_prelude/fail_local_in_namespace.carbon

@@ -26,16 +26,18 @@ fn F() -> {} {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %NS
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %NS: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
 // CHECK:STDOUT:     %.loc9_12.1: {} = struct_literal ()
 // CHECK:STDOUT:     %.loc9_12.2: type = converted %.loc9_12.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     @F.%return: ref {} = var <return slot>

+ 4 - 2
toolchain/check/testdata/alias/no_prelude/fail_not_constant.carbon

@@ -16,16 +16,18 @@ fn F() {
 // CHECK:STDOUT: --- fail_not_constant.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
 // CHECK:STDOUT:   %tuple: () = tuple_value () [template]
 // CHECK:STDOUT:   %.2: type = ptr_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {

+ 8 - 6
toolchain/check/testdata/alias/no_prelude/in_namespace.carbon

@@ -24,14 +24,16 @@ fn F() -> NS.a {
 // CHECK:STDOUT:   %.3: type = struct_type {.v: ()} [template]
 // CHECK:STDOUT:   %.4: type = ptr_type {.v: ()} [template]
 // CHECK:STDOUT:   %tuple: () = tuple_value () [template]
-// CHECK:STDOUT:   %struct: C = struct_value (%tuple) [template]
+// CHECK:STDOUT:   %struct.1: C = struct_value (%tuple) [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .C = %C.decl
 // CHECK:STDOUT:     .NS = %NS
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %NS: <namespace> = namespace [template] {
@@ -47,12 +49,12 @@ fn F() -> NS.a {
 // CHECK:STDOUT:   %.loc12_23.3: ref () = class_element_access %.loc12_23.2, element0
 // CHECK:STDOUT:   %.loc12_22.2: init () = tuple_init () to %.loc12_23.3 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc12_23.4: init () = converted %.loc12_22.1, %.loc12_22.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc12_23.5: init C = class_init (%.loc12_23.4), %.loc12_23.2 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_23.5: init C = class_init (%.loc12_23.4), %.loc12_23.2 [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc12_23.6: ref C = temporary %.loc12_23.2, %.loc12_23.5
 // CHECK:STDOUT:   %.loc12_24.1: ref C = converted %.loc12_23.1, %.loc12_23.6
 // CHECK:STDOUT:   %.loc12_24.2: C = bind_value %.loc12_24.1
 // CHECK:STDOUT:   %b: C = bind_name b, %.loc12_24.2
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // CHECK:STDOUT:     %NS.ref.loc14: <namespace> = name_ref NS, %NS [template = %NS]
 // CHECK:STDOUT:     %a.ref.loc14: type = name_ref a, %a [template = constants.%C]
 // CHECK:STDOUT:     @F.%return: ref C = var <return slot>
@@ -76,8 +78,8 @@ fn F() -> NS.a {
 // CHECK:STDOUT:   %.loc15_18.2: ref () = class_element_access %return, element0
 // CHECK:STDOUT:   %.loc15_17.2: init () = tuple_init () to %.loc15_18.2 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc15_18.3: init () = converted %.loc15_17.1, %.loc15_17.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc15_18.4: init C = class_init (%.loc15_18.3), %return [template = constants.%struct]
-// CHECK:STDOUT:   %.loc15_19: init C = converted %.loc15_18.1, %.loc15_18.4 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc15_18.4: init C = class_init (%.loc15_18.3), %return [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc15_19: init C = converted %.loc15_18.1, %.loc15_18.4 [template = constants.%struct.1]
 // CHECK:STDOUT:   return %.loc15_19 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 2
toolchain/check/testdata/alias/no_prelude/local.carbon

@@ -14,14 +14,16 @@ fn F() -> () {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
 // CHECK:STDOUT:   %tuple: () = tuple_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
 // CHECK:STDOUT:     %.loc7_12.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc7_12.2: type = converted %.loc7_12.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     @F.%return: ref () = var <return slot>

+ 22 - 17
toolchain/check/testdata/array/array_in_place.carbon

@@ -15,28 +15,33 @@ fn G() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type (type, type, type) [template]
 // CHECK:STDOUT:   %.2: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.5: type = ptr_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.6: type = ptr_type [(i32, i32, i32); 2] [template]
-// CHECK:STDOUT:   %.7: type = tuple_type ((i32, i32, i32), (i32, i32, i32)) [template]
-// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.6: type = ptr_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.7: type = ptr_type [(i32, i32, i32); 2] [template]
+// CHECK:STDOUT:   %.8: type = tuple_type ((i32, i32, i32), (i32, i32, i32)) [template]
+// CHECK:STDOUT:   %.9: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .G = %G
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %.loc7_25.1: (type, type, type) = tuple_literal (i32, i32, i32)
 // CHECK:STDOUT:     %.loc7_25.2: type = converted %.loc7_25.1, constants.%.2 [template = constants.%.2]
 // CHECK:STDOUT:     @F.%return: ref (i32, i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {}
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> (i32, i32, i32);
@@ -44,20 +49,20 @@ fn G() {
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc10_25.1: (type, type, type) = tuple_literal (i32, i32, i32)
-// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_25.2: type = converted %.loc10_25.1, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_29: type = array_type %.loc10_28, (i32, i32, i32) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_29: type = array_type %.loc10_28, (i32, i32, i32) [template = constants.%.5]
 // CHECK:STDOUT:   %v.var: ref [(i32, i32, i32); 2] = var v
 // CHECK:STDOUT:   %v: ref [(i32, i32, i32); 2] = bind_name v, %v.var
-// CHECK:STDOUT:   %F.ref.loc10_34: <function> = name_ref F, file.%F [template = file.%F]
+// CHECK:STDOUT:   %F.ref.loc10_34: F = name_ref F, file.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_42.3: ref (i32, i32, i32) = splice_block %.loc10_42.2 {
-// CHECK:STDOUT:     %.loc10_42.1: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:     %.loc10_42.1: i32 = int_literal 0 [template = constants.%.9]
 // CHECK:STDOUT:     %.loc10_42.2: ref (i32, i32, i32) = array_index %v.var, %.loc10_42.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.call.loc10_35: init (i32, i32, i32) = call %F.ref.loc10_34() to %.loc10_42.3
-// CHECK:STDOUT:   %F.ref.loc10_39: <function> = name_ref F, file.%F [template = file.%F]
+// CHECK:STDOUT:   %F.ref.loc10_39: F = name_ref F, file.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_42.6: ref (i32, i32, i32) = splice_block %.loc10_42.5 {
-// CHECK:STDOUT:     %.loc10_42.4: i32 = int_literal 1 [template = constants.%.9]
+// CHECK:STDOUT:     %.loc10_42.4: i32 = int_literal 1 [template = constants.%.10]
 // CHECK:STDOUT:     %.loc10_42.5: ref (i32, i32, i32) = array_index %v.var, %.loc10_42.4
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %F.call.loc10_40: init (i32, i32, i32) = call %F.ref.loc10_39() to %.loc10_42.6

+ 34 - 31
toolchain/check/testdata/array/array_vs_tuple.carbon

@@ -13,64 +13,67 @@ fn G() {
 // CHECK:STDOUT: --- array_vs_tuple.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 3] [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.6: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.4, %.5, %.1) [template]
-// CHECK:STDOUT:   %.8: type = tuple_type (type, type, type) [template]
-// CHECK:STDOUT:   %.9: type = ptr_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %tuple: (i32, i32, i32) = tuple_value (%.4, %.5, %.1) [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: G = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.5, %.6, %.2) [template]
+// CHECK:STDOUT:   %.9: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.10: type = ptr_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %tuple: (i32, i32, i32) = tuple_value (%.5, %.6, %.2) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .G = %G
+// CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {}
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9_16: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_17: type = array_type %.loc9_16, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_16: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_17: type = array_type %.loc9_16, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref [i32; 3] = var a
 // CHECK:STDOUT:   %a: ref [i32; 3] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc9_22: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_28: i32 = int_literal 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_22: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_28: i32 = int_literal 3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc9_29.1: (i32, i32, i32) = tuple_literal (%.loc9_22, %.loc9_25, %.loc9_28)
-// CHECK:STDOUT:   %.loc9_29.2: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_29.2: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc9_29.3: ref i32 = array_index %a.var, %.loc9_29.2
-// CHECK:STDOUT:   %.loc9_29.4: init i32 = initialize_from %.loc9_22 to %.loc9_29.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_29.5: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_29.4: init i32 = initialize_from %.loc9_22 to %.loc9_29.3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_29.5: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc9_29.6: ref i32 = array_index %a.var, %.loc9_29.5
-// CHECK:STDOUT:   %.loc9_29.7: init i32 = initialize_from %.loc9_25 to %.loc9_29.6 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_29.8: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_29.7: init i32 = initialize_from %.loc9_25 to %.loc9_29.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_29.8: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc9_29.9: ref i32 = array_index %a.var, %.loc9_29.8
-// CHECK:STDOUT:   %.loc9_29.10: init i32 = initialize_from %.loc9_28 to %.loc9_29.9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_29.10: init i32 = initialize_from %.loc9_28 to %.loc9_29.9 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc9_29.11: init [i32; 3] = array_init (%.loc9_29.4, %.loc9_29.7, %.loc9_29.10) to %a.var [template = constants.%array]
 // CHECK:STDOUT:   %.loc9_30: init [i32; 3] = converted %.loc9_29.1, %.loc9_29.11 [template = constants.%array]
 // CHECK:STDOUT:   assign %a.var, %.loc9_30
 // CHECK:STDOUT:   %.loc10_24.1: (type, type, type) = tuple_literal (i32, i32, i32)
-// CHECK:STDOUT:   %.loc10_24.2: type = converted %.loc10_24.1, constants.%.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_24.2: type = converted %.loc10_24.1, constants.%.7 [template = constants.%.7]
 // CHECK:STDOUT:   %b.var: ref (i32, i32, i32) = var b
 // CHECK:STDOUT:   %b: ref (i32, i32, i32) = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc10_29: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_32: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc10_35: i32 = int_literal 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_29: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_32: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_35: i32 = int_literal 3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc10_36.1: (i32, i32, i32) = tuple_literal (%.loc10_29, %.loc10_32, %.loc10_35)
 // CHECK:STDOUT:   %.loc10_36.2: ref i32 = tuple_access %b.var, element0
-// CHECK:STDOUT:   %.loc10_36.3: init i32 = initialize_from %.loc10_29 to %.loc10_36.2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_36.3: init i32 = initialize_from %.loc10_29 to %.loc10_36.2 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc10_36.4: ref i32 = tuple_access %b.var, element1
-// CHECK:STDOUT:   %.loc10_36.5: init i32 = initialize_from %.loc10_32 to %.loc10_36.4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_36.5: init i32 = initialize_from %.loc10_32 to %.loc10_36.4 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc10_36.6: ref i32 = tuple_access %b.var, element2
-// CHECK:STDOUT:   %.loc10_36.7: init i32 = initialize_from %.loc10_35 to %.loc10_36.6 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc10_36.7: init i32 = initialize_from %.loc10_35 to %.loc10_36.6 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc10_36.8: init (i32, i32, i32) = tuple_init (%.loc10_36.3, %.loc10_36.5, %.loc10_36.7) to %b.var [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc10_37: init (i32, i32, i32) = converted %.loc10_36.1, %.loc10_36.8 [template = constants.%tuple]
 // CHECK:STDOUT:   assign %b.var, %.loc10_37

+ 19 - 14
toolchain/check/testdata/array/assign_return_value.carbon

@@ -15,31 +15,36 @@ fn Run() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type (type) [template]
 // CHECK:STDOUT:   %.2: type = tuple_type (i32) [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %tuple: (i32,) = tuple_value (%.3) [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
-// CHECK:STDOUT:   %.6: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %tuple: (i32,) = tuple_value (%.4) [template]
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %struct.2: Run = struct_value () [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: type = array_type %.5, i32 [template]
+// CHECK:STDOUT:   %.7: type = ptr_type [i32; 1] [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %.loc7_16.1: (type,) = tuple_literal (i32)
 // CHECK:STDOUT:     %.loc7_16.2: type = converted %.loc7_16.1, constants.%.2 [template = constants.%.2]
 // CHECK:STDOUT:     @F.%return: ref (i32,) = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.2] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> (i32,) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc7_30: (i32,) = tuple_literal (%.loc7_28)
 // CHECK:STDOUT:   %tuple: (i32,) = tuple_value (%.loc7_28) [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc7_31: (i32,) = converted %.loc7_30, %tuple [template = constants.%tuple]
@@ -48,17 +53,17 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_17: type = array_type %.loc10_16, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_17: type = array_type %.loc10_16, i32 [template = constants.%.6]
 // CHECK:STDOUT:   %t.var: ref [i32; 1] = var t
 // CHECK:STDOUT:   %t: ref [i32; 1] = bind_name t, %t.var
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F [template = file.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, file.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %F.call: init (i32,) = call %F.ref()
 // CHECK:STDOUT:   %.loc10_22.1: ref (i32,) = temporary_storage
 // CHECK:STDOUT:   %.loc10_22.2: ref (i32,) = temporary %.loc10_22.1, %F.call
 // CHECK:STDOUT:   %.loc10_22.3: ref i32 = tuple_access %.loc10_22.2, element0
 // CHECK:STDOUT:   %.loc10_22.4: i32 = bind_value %.loc10_22.3
-// CHECK:STDOUT:   %.loc10_22.5: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_22.5: i32 = int_literal 0 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_22.6: ref i32 = array_index %t.var, %.loc10_22.5
 // CHECK:STDOUT:   %.loc10_22.7: init i32 = initialize_from %.loc10_22.4 to %.loc10_22.6
 // CHECK:STDOUT:   %.loc10_22.8: init [i32; 1] = array_init (%.loc10_22.7) to %t.var

+ 30 - 27
toolchain/check/testdata/array/canonicalize_index.carbon

@@ -12,40 +12,43 @@ let b: [i32; 3]* = &a;
 // CHECK:STDOUT: --- canonicalize_index.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 3] [template]
-// CHECK:STDOUT:   %.6: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.1, %.2, %.3) [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.2, %.3, %.4) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
+// CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:     .a = %a.loc9
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc7_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc7_8.1
 // CHECK:STDOUT:     %b.loc7_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc7_16.1
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc9_18: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_21: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc9_18, %.loc9_21) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc9_23: type = array_type %int.sadd, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_18: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_21: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc9_18, %.loc9_21) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_23: type = array_type %int.sadd, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %a.var: ref [i32; 3] = var a
 // CHECK:STDOUT:   %a.loc9: ref [i32; 3] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_16: type = ptr_type [i32; 3] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_16: type = ptr_type [i32; 3] [template = constants.%.6]
 // CHECK:STDOUT:   %a.ref: ref [i32; 3] = name_ref a, %a.loc9
 // CHECK:STDOUT:   %.loc10_20: [i32; 3]* = addr_of %a.ref
 // CHECK:STDOUT:   %b.loc10: [i32; 3]* = bind_name b, %.loc10_20
@@ -55,19 +58,19 @@ let b: [i32; 3]* = &a;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9_28: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_31: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_34: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_28: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_31: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_34: i32 = int_literal 3 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_35.1: (i32, i32, i32) = tuple_literal (%.loc9_28, %.loc9_31, %.loc9_34)
-// CHECK:STDOUT:   %.loc9_35.2: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_35.2: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc9_35.3: ref i32 = array_index file.%a.var, %.loc9_35.2
-// CHECK:STDOUT:   %.loc9_35.4: init i32 = initialize_from %.loc9_28 to %.loc9_35.3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_35.5: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_35.4: init i32 = initialize_from %.loc9_28 to %.loc9_35.3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_35.5: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc9_35.6: ref i32 = array_index file.%a.var, %.loc9_35.5
-// CHECK:STDOUT:   %.loc9_35.7: init i32 = initialize_from %.loc9_31 to %.loc9_35.6 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_35.8: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_35.7: init i32 = initialize_from %.loc9_31 to %.loc9_35.6 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_35.8: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %.loc9_35.9: ref i32 = array_index file.%a.var, %.loc9_35.8
-// CHECK:STDOUT:   %.loc9_35.10: init i32 = initialize_from %.loc9_34 to %.loc9_35.9 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_35.10: init i32 = initialize_from %.loc9_34 to %.loc9_35.9 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_35.11: init [i32; 3] = array_init (%.loc9_35.4, %.loc9_35.7, %.loc9_35.10) to file.%a.var [template = constants.%array]
 // CHECK:STDOUT:   %.loc9_36: init [i32; 3] = converted %.loc9_35.1, %.loc9_35.11 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc9_36

+ 10 - 7
toolchain/check/testdata/array/fail_bound_negative.carbon

@@ -14,25 +14,28 @@ var a: [i32; Negate(1)];
 // CHECK:STDOUT: --- fail_bound_negative.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct] {
 // CHECK:STDOUT:     %n.loc7_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc7_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_21) [template = constants.%.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_21) [template = constants.%.3]
 // CHECK:STDOUT:   %.loc12_23: type = array_type %int.snegate, i32 [template = <error>]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var

+ 24 - 19
toolchain/check/testdata/array/function_param.carbon

@@ -17,22 +17,27 @@ fn G() -> i32 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
 // CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 3] [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.6: type = tuple_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.4, %.5, %.1) [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %array: [i32; 3] = tuple_value (%.5, %.6, %.1) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .G = %G
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %.loc7_17: i32 = int_literal 3 [template = constants.%.1]
 // CHECK:STDOUT:     %.loc7_18: type = array_type %.loc7_17, i32 [template = constants.%.2]
 // CHECK:STDOUT:     %arr.loc7_6.1: [i32; 3] = param arr
@@ -41,7 +46,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:     @F.%i: i32 = bind_name i, %i.loc7_21.1
 // CHECK:STDOUT:     @F.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -58,20 +63,20 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F [template = file.%F]
-// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, file.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc12_19: i32 = int_literal 3 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc12_20.1: (i32, i32, i32) = tuple_literal (%.loc12_13, %.loc12_16, %.loc12_19)
-// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc12_20.2: ref [i32; 3] = temporary_storage
-// CHECK:STDOUT:   %.loc12_20.3: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_20.3: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc12_20.4: ref i32 = array_index %.loc12_20.2, %.loc12_20.3
-// CHECK:STDOUT:   %.loc12_20.5: init i32 = initialize_from %.loc12_13 to %.loc12_20.4 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc12_20.6: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_20.5: init i32 = initialize_from %.loc12_13 to %.loc12_20.4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_20.6: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc12_20.7: ref i32 = array_index %.loc12_20.2, %.loc12_20.6
-// CHECK:STDOUT:   %.loc12_20.8: init i32 = initialize_from %.loc12_16 to %.loc12_20.7 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_20.9: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12_20.8: init i32 = initialize_from %.loc12_16 to %.loc12_20.7 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_20.9: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc12_20.10: ref i32 = array_index %.loc12_20.2, %.loc12_20.9
 // CHECK:STDOUT:   %.loc12_20.11: init i32 = initialize_from %.loc12_19 to %.loc12_20.10 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc12_20.12: init [i32; 3] = array_init (%.loc12_20.5, %.loc12_20.8, %.loc12_20.11) to %.loc12_20.2 [template = constants.%array]

+ 25 - 22
toolchain/check/testdata/as/adapter_conversion.carbon

@@ -103,13 +103,16 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %.1: type = unbound_element_type A, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.x: i32, .y: i32} [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.x: i32, .y: i32} [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %struct: A = struct_value (%.4, %.5) [template]
+// CHECK:STDOUT:   %Make: type = fn_type @Make [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Make = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.x: i32, .y: i32} [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.x: i32, .y: i32} [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %struct.2: A = struct_value (%.5, %.6) [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.6: type = ptr_type B [template]
+// CHECK:STDOUT:   %.7: type = ptr_type B [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -137,7 +140,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   %.loc21_22.2: B = converted %a_val.ref, %.loc21_22.1
 // CHECK:STDOUT:   %b_val: B = bind_name b_val, %.loc21_22.2
 // CHECK:STDOUT:   %B.ref.loc22_12: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT:   %.loc22_13: type = ptr_type B [template = constants.%.6]
+// CHECK:STDOUT:   %.loc22_13: type = ptr_type B [template = constants.%.7]
 // CHECK:STDOUT:   %a_ref.ref.loc22: ref A = name_ref a_ref, %a_ref
 // CHECK:STDOUT:   %B.ref.loc22_28: type = name_ref B, %B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc22_25.1: ref B = as_compatible %a_ref.ref.loc22
@@ -152,7 +155,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: class @A {
 // CHECK:STDOUT:   %.loc5: <unbound element of class A> = field_decl x, element0 [template]
 // CHECK:STDOUT:   %.loc6: <unbound element of class A> = field_decl y, element1 [template]
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template] {
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
 // CHECK:STDOUT:     %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:     %return.var: ref A = var <return slot>
 // CHECK:STDOUT:   }
@@ -161,7 +164,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT:   .x = %.loc5
 // CHECK:STDOUT:   .y = %.loc6
-// CHECK:STDOUT:   .Make = %Make
+// CHECK:STDOUT:   .Make = %Make.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
@@ -174,32 +177,32 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> @A.%return.var: A {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9_18: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_26: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_18: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_26: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc9_27.1: {.x: i32, .y: i32} = struct_literal (%.loc9_18, %.loc9_26)
 // CHECK:STDOUT:   %.loc9_27.2: ref i32 = class_element_access @A.%return.var, element0
-// CHECK:STDOUT:   %.loc9_27.3: init i32 = initialize_from %.loc9_18 to %.loc9_27.2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9_27.3: init i32 = initialize_from %.loc9_18 to %.loc9_27.2 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc9_27.4: ref i32 = class_element_access @A.%return.var, element1
-// CHECK:STDOUT:   %.loc9_27.5: init i32 = initialize_from %.loc9_26 to %.loc9_27.4 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_27.6: init A = class_init (%.loc9_27.3, %.loc9_27.5), @A.%return.var [template = constants.%struct]
-// CHECK:STDOUT:   %.loc9_28: init A = converted %.loc9_27.1, %.loc9_27.6 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_27.5: init i32 = initialize_from %.loc9_26 to %.loc9_27.4 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_27.6: init A = class_init (%.loc9_27.3, %.loc9_27.5), @A.%return.var [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc9_28: init A = converted %.loc9_27.1, %.loc9_27.6 [template = constants.%struct.2]
 // CHECK:STDOUT:   return %.loc9_28 to @A.%return.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc17_22: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_30: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_22: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_30: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc17_31.1: {.x: i32, .y: i32} = struct_literal (%.loc17_22, %.loc17_30)
 // CHECK:STDOUT:   %.loc17_31.2: ref i32 = class_element_access file.%a_ref.var, element0
-// CHECK:STDOUT:   %.loc17_31.3: init i32 = initialize_from %.loc17_22 to %.loc17_31.2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc17_31.3: init i32 = initialize_from %.loc17_22 to %.loc17_31.2 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc17_31.4: ref i32 = class_element_access file.%a_ref.var, element1
-// CHECK:STDOUT:   %.loc17_31.5: init i32 = initialize_from %.loc17_30 to %.loc17_31.4 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_31.6: init A = class_init (%.loc17_31.3, %.loc17_31.5), file.%a_ref.var [template = constants.%struct]
-// CHECK:STDOUT:   %.loc17_32: init A = converted %.loc17_31.1, %.loc17_31.6 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_31.5: init i32 = initialize_from %.loc17_30 to %.loc17_31.4 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc17_31.6: init A = class_init (%.loc17_31.3, %.loc17_31.5), file.%a_ref.var [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc17_32: init A = converted %.loc17_31.1, %.loc17_31.6 [template = constants.%struct.2]
 // CHECK:STDOUT:   assign file.%a_ref.var, %.loc17_32
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, @A.%Make [template = @A.%Make]
+// CHECK:STDOUT:   %Make.ref: Make = name_ref Make, @A.%Make.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc24_5: ref B = splice_block file.%b_factory.var {}
 // CHECK:STDOUT:   %Make.call: init A = call %Make.ref() to %.loc24_5
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]

+ 7 - 4
toolchain/check/testdata/as/basic.carbon

@@ -11,23 +11,26 @@ fn Main() -> i32 {
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %Main: type = fn_type @Main [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Main = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Main = %Main
+// CHECK:STDOUT:     .Main = %Main.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template] {
+// CHECK:STDOUT:   %Main.decl: Main = fn_decl @Main [template = constants.%struct] {
 // CHECK:STDOUT:     @Main.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   return %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 17 - 9
toolchain/check/testdata/as/identity.carbon

@@ -29,38 +29,46 @@ fn Initializing() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %Value: type = fn_type @Value [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Value = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = ptr_type X [template]
+// CHECK:STDOUT:   %Reference: type = fn_type @Reference [template]
+// CHECK:STDOUT:   %struct.2: Reference = struct_value () [template]
+// CHECK:STDOUT:   %Make: type = fn_type @Make [template]
+// CHECK:STDOUT:   %struct.3: Make = struct_value () [template]
+// CHECK:STDOUT:   %Initializing: type = fn_type @Initializing [template]
+// CHECK:STDOUT:   %struct.4: Initializing = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .X = %X.decl
-// CHECK:STDOUT:     .Value = %Value
-// CHECK:STDOUT:     .Reference = %Reference
-// CHECK:STDOUT:     .Make = %Make
-// CHECK:STDOUT:     .Initializing = %Initializing
+// CHECK:STDOUT:     .Value = %Value.decl
+// CHECK:STDOUT:     .Reference = %Reference.decl
+// CHECK:STDOUT:     .Make = %Make.decl
+// CHECK:STDOUT:     .Initializing = %Initializing.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %X.decl: type = class_decl @X [template = constants.%X] {}
-// CHECK:STDOUT:   %Value: <function> = fn_decl @Value [template] {
+// CHECK:STDOUT:   %Value.decl: Value = fn_decl @Value [template = constants.%struct.1] {
 // CHECK:STDOUT:     %X.ref.loc13: type = name_ref X, %X.decl [template = constants.%X]
 // CHECK:STDOUT:     %n.loc13_10.1: X = param n
 // CHECK:STDOUT:     @Value.%n: X = bind_name n, %n.loc13_10.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Reference: <function> = fn_decl @Reference [template] {
+// CHECK:STDOUT:   %Reference.decl: Reference = fn_decl @Reference [template = constants.%struct.2] {
 // CHECK:STDOUT:     %X.ref.loc17: type = name_ref X, %X.decl [template = constants.%X]
 // CHECK:STDOUT:     %.loc17: type = ptr_type X [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc17_14.1: X* = param p
 // CHECK:STDOUT:     @Reference.%p: X* = bind_name p, %p.loc17_14.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template] {
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.3] {
 // CHECK:STDOUT:     %X.ref.loc21: type = name_ref X, %X.decl [template = constants.%X]
 // CHECK:STDOUT:     @Make.%return: ref X = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Initializing: <function> = fn_decl @Initializing [template] {}
+// CHECK:STDOUT:   %Initializing.decl: Initializing = fn_decl @Initializing [template = constants.%struct.4] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @X {
@@ -96,7 +104,7 @@ fn Initializing() {
 // CHECK:STDOUT:   %X.ref.loc24_10: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %x.var: ref X = var x
 // CHECK:STDOUT:   %x: ref X = bind_name x, %x.var
-// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make [template = file.%Make]
+// CHECK:STDOUT:   %Make.ref: Make = name_ref Make, file.%Make.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc24: ref X = splice_block %x.var {}
 // CHECK:STDOUT:   %Make.call: init X = call %Make.ref() to %.loc24
 // CHECK:STDOUT:   %X.ref.loc24_25: type = name_ref X, file.%X.decl [template = constants.%X]

+ 23 - 17
toolchain/check/testdata/as/no_prelude/tuple.carbon

@@ -25,28 +25,34 @@ fn Var() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
-// CHECK:STDOUT:   %.2: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.3: type = tuple_type (X, X) [template]
-// CHECK:STDOUT:   %.4: type = tuple_type () [template]
+// CHECK:STDOUT:   %Make: type = fn_type @Make [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Make = struct_value () [template]
+// CHECK:STDOUT:   %Let: type = fn_type @Let [template]
+// CHECK:STDOUT:   %struct.2: Let = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.4: type = tuple_type (X, X) [template]
 // CHECK:STDOUT:   %.5: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.6: type = tuple_type ({}*, {}*) [template]
 // CHECK:STDOUT:   %.7: type = ptr_type ({}*, {}*) [template]
+// CHECK:STDOUT:   %Var: type = fn_type @Var [template]
+// CHECK:STDOUT:   %struct.3: Var = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .X = %X.decl
-// CHECK:STDOUT:     .Make = %Make
-// CHECK:STDOUT:     .Let = %Let
-// CHECK:STDOUT:     .Var = %Var
+// CHECK:STDOUT:     .Make = %Make.decl
+// CHECK:STDOUT:     .Let = %Let.decl
+// CHECK:STDOUT:     .Var = %Var.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %X.decl: type = class_decl @X [template = constants.%X] {}
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template] {
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
 // CHECK:STDOUT:     %X.ref: type = name_ref X, %X.decl [template = constants.%X]
 // CHECK:STDOUT:     @Make.%return: ref X = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Let: <function> = fn_decl @Let [template] {}
-// CHECK:STDOUT:   %Var: <function> = fn_decl @Var [template] {}
+// CHECK:STDOUT:   %Let.decl: Let = fn_decl @Let [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %Var.decl: Var = fn_decl @Var [template = constants.%struct.3] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @X {
@@ -61,18 +67,18 @@ fn Var() {
 // CHECK:STDOUT:   %X.ref.loc15_11: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %X.ref.loc15_14: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %.loc15_15.1: (type, type) = tuple_literal (%X.ref.loc15_11, %X.ref.loc15_14)
-// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc15_15.1, constants.%.3 [template = constants.%.3]
-// CHECK:STDOUT:   %Make.ref.loc15_20: <function> = name_ref Make, file.%Make [template = file.%Make]
+// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc15_15.1, constants.%.4 [template = constants.%.4]
+// CHECK:STDOUT:   %Make.ref.loc15_20: Make = name_ref Make, file.%Make.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc15_24.1: ref X = temporary_storage
 // CHECK:STDOUT:   %Make.call.loc15_24: init X = call %Make.ref.loc15_20() to %.loc15_24.1
-// CHECK:STDOUT:   %Make.ref.loc15_28: <function> = name_ref Make, file.%Make [template = file.%Make]
+// CHECK:STDOUT:   %Make.ref.loc15_28: Make = name_ref Make, file.%Make.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc15_32.1: ref X = temporary_storage
 // CHECK:STDOUT:   %Make.call.loc15_32: init X = call %Make.ref.loc15_28() to %.loc15_32.1
 // CHECK:STDOUT:   %.loc15_34: (X, X) = tuple_literal (%Make.call.loc15_24, %Make.call.loc15_32)
 // CHECK:STDOUT:   %X.ref.loc15_40: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %X.ref.loc15_43: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %.loc15_44.1: (type, type) = tuple_literal (%X.ref.loc15_40, %X.ref.loc15_43)
-// CHECK:STDOUT:   %.loc15_44.2: type = converted %.loc15_44.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_44.2: type = converted %.loc15_44.1, constants.%.4 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc15_24.2: ref X = temporary %.loc15_24.1, %Make.call.loc15_24
 // CHECK:STDOUT:   %.loc15_24.3: X = bind_value %.loc15_24.2
 // CHECK:STDOUT:   %.loc15_32.2: ref X = temporary %.loc15_32.1, %Make.call.loc15_32
@@ -88,20 +94,20 @@ fn Var() {
 // CHECK:STDOUT:   %X.ref.loc20_11: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %X.ref.loc20_14: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %.loc20_15.1: (type, type) = tuple_literal (%X.ref.loc20_11, %X.ref.loc20_14)
-// CHECK:STDOUT:   %.loc20_15.2: type = converted %.loc20_15.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc20_15.2: type = converted %.loc20_15.1, constants.%.4 [template = constants.%.4]
 // CHECK:STDOUT:   %b.var: ref (X, X) = var b
 // CHECK:STDOUT:   %b: ref (X, X) = bind_name b, %b.var
-// CHECK:STDOUT:   %Make.ref.loc20_20: <function> = name_ref Make, file.%Make [template = file.%Make]
+// CHECK:STDOUT:   %Make.ref.loc20_20: Make = name_ref Make, file.%Make.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc20_34.1: ref X = tuple_access %b.var, element0
 // CHECK:STDOUT:   %Make.call.loc20_24: init X = call %Make.ref.loc20_20() to %.loc20_34.1
-// CHECK:STDOUT:   %Make.ref.loc20_28: <function> = name_ref Make, file.%Make [template = file.%Make]
+// CHECK:STDOUT:   %Make.ref.loc20_28: Make = name_ref Make, file.%Make.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc20_34.2: ref X = tuple_access %b.var, element1
 // CHECK:STDOUT:   %Make.call.loc20_32: init X = call %Make.ref.loc20_28() to %.loc20_34.2
 // CHECK:STDOUT:   %.loc20_34.3: (X, X) = tuple_literal (%Make.call.loc20_24, %Make.call.loc20_32)
 // CHECK:STDOUT:   %X.ref.loc20_40: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %X.ref.loc20_43: type = name_ref X, file.%X.decl [template = constants.%X]
 // CHECK:STDOUT:   %.loc20_44.1: (type, type) = tuple_literal (%X.ref.loc20_40, %X.ref.loc20_43)
-// CHECK:STDOUT:   %.loc20_44.2: type = converted %.loc20_44.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc20_44.2: type = converted %.loc20_44.1, constants.%.4 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc20_34.4: init (X, X) = tuple_init (%Make.call.loc20_24, %Make.call.loc20_32) to %b.var
 // CHECK:STDOUT:   %.loc20_45: init (X, X) = converted %.loc20_34.3, %.loc20_34.4
 // CHECK:STDOUT:   assign %b.var, %.loc20_45

+ 0 - 2
toolchain/check/testdata/basics/builtin_insts.carbon

@@ -25,7 +25,6 @@
 // CHECK:STDOUT:     instIntType:     {kind: Builtin, arg0: IntType, type: typeTypeType}
 // CHECK:STDOUT:     instFloatType:   {kind: Builtin, arg0: FloatType, type: typeTypeType}
 // CHECK:STDOUT:     instStringType:  {kind: Builtin, arg0: StringType, type: typeTypeType}
-// CHECK:STDOUT:     instFunctionType: {kind: Builtin, arg0: FunctionType, type: typeTypeType}
 // CHECK:STDOUT:     instBoundMethodType: {kind: Builtin, arg0: BoundMethodType, type: typeTypeType}
 // CHECK:STDOUT:     instNamespaceType: {kind: Builtin, arg0: NamespaceType, type: typeTypeType}
 // CHECK:STDOUT:     instWitnessType: {kind: Builtin, arg0: WitnessType, type: typeTypeType}
@@ -37,7 +36,6 @@
 // CHECK:STDOUT:     instIntType:     template instIntType
 // CHECK:STDOUT:     instFloatType:   template instFloatType
 // CHECK:STDOUT:     instStringType:  template instStringType
-// CHECK:STDOUT:     instFunctionType: template instFunctionType
 // CHECK:STDOUT:     instBoundMethodType: template instBoundMethodType
 // CHECK:STDOUT:     instNamespaceType: template instNamespaceType
 // CHECK:STDOUT:     instWitnessType: template instWitnessType

+ 4 - 2
toolchain/check/testdata/basics/fail_bad_run.carbon

@@ -16,17 +16,19 @@ fn Run() -> String {}
 // CHECK:STDOUT: --- fail_bad_run.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Run = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = ptr_type String [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {
 // CHECK:STDOUT:     @Run.%return: ref String = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }

+ 8 - 2
toolchain/check/testdata/basics/fail_bad_run_2.carbon

@@ -11,13 +11,19 @@ fn Run(n: i32) {}
 
 // CHECK:STDOUT: --- fail_bad_run_2.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Run = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {
 // CHECK:STDOUT:     %n.loc10_8.1: i32 = param n
 // CHECK:STDOUT:     @Run.%n: i32 = bind_name n, %n.loc10_8.1
 // CHECK:STDOUT:   }

+ 16 - 4
toolchain/check/testdata/basics/multifile.carbon

@@ -16,13 +16,19 @@ fn B() {}
 
 // CHECK:STDOUT: --- a.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %A: type = fn_type @A [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: A = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .A = %A
+// CHECK:STDOUT:     .A = %A.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {}
+// CHECK:STDOUT:   %A.decl: A = fn_decl @A [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @A() {
@@ -32,13 +38,19 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %B: type = fn_type @B [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: B = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .B = %B
+// CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {}
+// CHECK:STDOUT:   %B.decl: B = fn_decl @B [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @B() {

+ 8 - 2
toolchain/check/testdata/basics/no_prelude/fail_name_lookup.carbon

@@ -13,11 +13,17 @@ fn Main() {
 
 // CHECK:STDOUT: --- fail_name_lookup.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Main: type = fn_type @Main [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Main = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Main = %Main
+// CHECK:STDOUT:     .Main = %Main.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template] {}
+// CHECK:STDOUT:   %Main.decl: Main = fn_decl @Main [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() {

+ 44 - 14
toolchain/check/testdata/basics/no_prelude/multifile_raw_and_textual_ir.carbon

@@ -30,22 +30,31 @@ fn B() {}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   types:
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
-// CHECK:STDOUT:     type1:           {constant: template instFunctionType, value_rep: {kind: copy, type: type1}}
-// CHECK:STDOUT:   type_blocks:     {}
+// CHECK:STDOUT:     type1:           {constant: template inst+2, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:     type2:           {constant: template inst+3, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:   type_blocks:
+// CHECK:STDOUT:     typeBlock0:      {}
+// CHECK:STDOUT:     typeBlock1:      {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     'inst+0':          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type0}
 // CHECK:STDOUT:     'inst+1':          {kind: FunctionDecl, arg0: function0, arg1: empty, type: type1}
-// CHECK:STDOUT:     'inst+2':          {kind: Return}
+// CHECK:STDOUT:     'inst+2':          {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+3':          {kind: TupleType, arg0: typeBlock0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+4':          {kind: StructValue, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+5':          {kind: Return}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
-// CHECK:STDOUT:     'inst+1':          template inst+1
+// CHECK:STDOUT:     'inst+1':          template inst+4
+// CHECK:STDOUT:     'inst+2':          template inst+2
+// CHECK:STDOUT:     'inst+3':          template inst+3
+// CHECK:STDOUT:     'inst+4':          template inst+4
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     block3:
-// CHECK:STDOUT:       0:               inst+2
+// CHECK:STDOUT:       0:               inst+5
 // CHECK:STDOUT:     block4:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+1
@@ -53,11 +62,17 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- a.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %A: type = fn_type @A [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: A = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .A = %A
+// CHECK:STDOUT:     .A = %A.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {}
+// CHECK:STDOUT:   %A.decl: A = fn_decl @A [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @A() {
@@ -77,22 +92,31 @@ fn B() {}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   types:
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
-// CHECK:STDOUT:     type1:           {constant: template instFunctionType, value_rep: {kind: copy, type: type1}}
-// CHECK:STDOUT:   type_blocks:     {}
+// CHECK:STDOUT:     type1:           {constant: template inst+2, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:     type2:           {constant: template inst+3, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:   type_blocks:
+// CHECK:STDOUT:     typeBlock0:      {}
+// CHECK:STDOUT:     typeBlock1:      {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     'inst+0':          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type0}
 // CHECK:STDOUT:     'inst+1':          {kind: FunctionDecl, arg0: function0, arg1: empty, type: type1}
-// CHECK:STDOUT:     'inst+2':          {kind: Return}
+// CHECK:STDOUT:     'inst+2':          {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+3':          {kind: TupleType, arg0: typeBlock0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+4':          {kind: StructValue, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+5':          {kind: Return}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
-// CHECK:STDOUT:     'inst+1':          template inst+1
+// CHECK:STDOUT:     'inst+1':          template inst+4
+// CHECK:STDOUT:     'inst+2':          template inst+2
+// CHECK:STDOUT:     'inst+3':          template inst+3
+// CHECK:STDOUT:     'inst+4':          template inst+4
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     block3:
-// CHECK:STDOUT:       0:               inst+2
+// CHECK:STDOUT:       0:               inst+5
 // CHECK:STDOUT:     block4:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+1
@@ -100,11 +124,17 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %B: type = fn_type @B [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: B = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .B = %B
+// CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {}
+// CHECK:STDOUT:   %B.decl: B = fn_decl @B [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @B() {

+ 28 - 10
toolchain/check/testdata/basics/no_prelude/multifile_raw_ir.carbon

@@ -30,22 +30,31 @@ fn B() {}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   types:
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
-// CHECK:STDOUT:     type1:           {constant: template instFunctionType, value_rep: {kind: copy, type: type1}}
-// CHECK:STDOUT:   type_blocks:     {}
+// CHECK:STDOUT:     type1:           {constant: template inst+2, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:     type2:           {constant: template inst+3, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:   type_blocks:
+// CHECK:STDOUT:     typeBlock0:      {}
+// CHECK:STDOUT:     typeBlock1:      {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     'inst+0':          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type0}
 // CHECK:STDOUT:     'inst+1':          {kind: FunctionDecl, arg0: function0, arg1: empty, type: type1}
-// CHECK:STDOUT:     'inst+2':          {kind: Return}
+// CHECK:STDOUT:     'inst+2':          {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+3':          {kind: TupleType, arg0: typeBlock0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+4':          {kind: StructValue, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+5':          {kind: Return}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
-// CHECK:STDOUT:     'inst+1':          template inst+1
+// CHECK:STDOUT:     'inst+1':          template inst+4
+// CHECK:STDOUT:     'inst+2':          template inst+2
+// CHECK:STDOUT:     'inst+3':          template inst+3
+// CHECK:STDOUT:     'inst+4':          template inst+4
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     block3:
-// CHECK:STDOUT:       0:               inst+2
+// CHECK:STDOUT:       0:               inst+5
 // CHECK:STDOUT:     block4:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+1
@@ -62,22 +71,31 @@ fn B() {}
 // CHECK:STDOUT:   classes:         {}
 // CHECK:STDOUT:   types:
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
-// CHECK:STDOUT:     type1:           {constant: template instFunctionType, value_rep: {kind: copy, type: type1}}
-// CHECK:STDOUT:   type_blocks:     {}
+// CHECK:STDOUT:     type1:           {constant: template inst+2, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:     type2:           {constant: template inst+3, value_rep: {kind: none, type: type2}}
+// CHECK:STDOUT:   type_blocks:
+// CHECK:STDOUT:     typeBlock0:      {}
+// CHECK:STDOUT:     typeBlock1:      {}
 // CHECK:STDOUT:   insts:
 // CHECK:STDOUT:     'inst+0':          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type0}
 // CHECK:STDOUT:     'inst+1':          {kind: FunctionDecl, arg0: function0, arg1: empty, type: type1}
-// CHECK:STDOUT:     'inst+2':          {kind: Return}
+// CHECK:STDOUT:     'inst+2':          {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+3':          {kind: TupleType, arg0: typeBlock0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+4':          {kind: StructValue, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+5':          {kind: Return}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
-// CHECK:STDOUT:     'inst+1':          template inst+1
+// CHECK:STDOUT:     'inst+1':          template inst+4
+// CHECK:STDOUT:     'inst+2':          template inst+2
+// CHECK:STDOUT:     'inst+3':          template inst+3
+// CHECK:STDOUT:     'inst+4':          template inst+4
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
 // CHECK:STDOUT:       0:               inst+1
 // CHECK:STDOUT:     global_init:     {}
 // CHECK:STDOUT:     block3:
-// CHECK:STDOUT:       0:               inst+2
+// CHECK:STDOUT:       0:               inst+5
 // CHECK:STDOUT:     block4:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+1

+ 54 - 47
toolchain/check/testdata/basics/no_prelude/raw_and_textual_ir.carbon

@@ -27,8 +27,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
 // CHECK:STDOUT:     type1:           {constant: template inst+1, value_rep: {kind: none, type: type1}}
 // CHECK:STDOUT:     type2:           {constant: template inst+8, value_rep: {kind: pointer, type: type4}}
-// CHECK:STDOUT:     type3:           {constant: template instFunctionType, value_rep: {kind: copy, type: type3}}
-// CHECK:STDOUT:     type4:           {constant: template inst+15, value_rep: {kind: copy, type: type4}}
+// CHECK:STDOUT:     type3:           {constant: template inst+15, value_rep: {kind: none, type: type1}}
+// CHECK:STDOUT:     type4:           {constant: template inst+17, value_rep: {kind: copy, type: type4}}
 // CHECK:STDOUT:   type_blocks:
 // CHECK:STDOUT:     typeBlock0:      {}
 // CHECK:STDOUT:     typeBlock1:      {}
@@ -44,7 +44,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       1:               type1
 // CHECK:STDOUT:     typeBlock8:      {}
 // CHECK:STDOUT:     typeBlock9:      {}
-// CHECK:STDOUT:     typeBlock10:
+// CHECK:STDOUT:     typeBlock10:     {}
+// CHECK:STDOUT:     typeBlock11:
 // CHECK:STDOUT:       0:               type1
 // CHECK:STDOUT:       1:               type1
 // CHECK:STDOUT:   insts:
@@ -63,21 +64,23 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     'inst+12':         {kind: Converted, arg0: inst+9, arg1: inst+8, type: typeTypeType}
 // CHECK:STDOUT:     'inst+13':         {kind: VarStorage, arg0: nameReturnSlot, type: type2}
 // CHECK:STDOUT:     'inst+14':         {kind: FunctionDecl, arg0: function0, arg1: block5, type: type3}
-// CHECK:STDOUT:     'inst+15':         {kind: PointerType, arg0: type2, type: typeTypeType}
-// CHECK:STDOUT:     'inst+16':         {kind: NameRef, arg0: name1, arg1: inst+5, type: type1}
-// CHECK:STDOUT:     'inst+17':         {kind: TupleLiteral, arg0: empty, type: type1}
-// CHECK:STDOUT:     'inst+18':         {kind: TupleLiteral, arg0: block7, type: type2}
-// CHECK:STDOUT:     'inst+19':         {kind: TupleAccess, arg0: inst+13, arg1: element0, type: type1}
-// CHECK:STDOUT:     'inst+20':         {kind: TupleInit, arg0: block8, arg1: inst+19, type: type1}
-// CHECK:STDOUT:     'inst+21':         {kind: TupleValue, arg0: block9, type: type1}
-// CHECK:STDOUT:     'inst+22':         {kind: Converted, arg0: inst+16, arg1: inst+20, type: type1}
-// CHECK:STDOUT:     'inst+23':         {kind: TupleAccess, arg0: inst+13, arg1: element1, type: type1}
-// CHECK:STDOUT:     'inst+24':         {kind: TupleInit, arg0: empty, arg1: inst+23, type: type1}
-// CHECK:STDOUT:     'inst+25':         {kind: Converted, arg0: inst+17, arg1: inst+24, type: type1}
-// CHECK:STDOUT:     'inst+26':         {kind: TupleInit, arg0: block10, arg1: inst+13, type: type2}
-// CHECK:STDOUT:     'inst+27':         {kind: TupleValue, arg0: block12, type: type2}
-// CHECK:STDOUT:     'inst+28':         {kind: Converted, arg0: inst+18, arg1: inst+26, type: type2}
-// CHECK:STDOUT:     'inst+29':         {kind: ReturnExpr, arg0: inst+28, arg1: inst+13}
+// CHECK:STDOUT:     'inst+15':         {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+16':         {kind: StructValue, arg0: empty, type: type3}
+// CHECK:STDOUT:     'inst+17':         {kind: PointerType, arg0: type2, type: typeTypeType}
+// CHECK:STDOUT:     'inst+18':         {kind: NameRef, arg0: name1, arg1: inst+5, type: type1}
+// CHECK:STDOUT:     'inst+19':         {kind: TupleLiteral, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+20':         {kind: TupleLiteral, arg0: block7, type: type2}
+// CHECK:STDOUT:     'inst+21':         {kind: TupleAccess, arg0: inst+13, arg1: element0, type: type1}
+// CHECK:STDOUT:     'inst+22':         {kind: TupleInit, arg0: block8, arg1: inst+21, type: type1}
+// CHECK:STDOUT:     'inst+23':         {kind: TupleValue, arg0: block9, type: type1}
+// CHECK:STDOUT:     'inst+24':         {kind: Converted, arg0: inst+18, arg1: inst+22, type: type1}
+// CHECK:STDOUT:     'inst+25':         {kind: TupleAccess, arg0: inst+13, arg1: element1, type: type1}
+// CHECK:STDOUT:     'inst+26':         {kind: TupleInit, arg0: empty, arg1: inst+25, type: type1}
+// CHECK:STDOUT:     'inst+27':         {kind: Converted, arg0: inst+19, arg1: inst+26, type: type1}
+// CHECK:STDOUT:     'inst+28':         {kind: TupleInit, arg0: block10, arg1: inst+13, type: type2}
+// CHECK:STDOUT:     'inst+29':         {kind: TupleValue, arg0: block12, type: type2}
+// CHECK:STDOUT:     'inst+30':         {kind: Converted, arg0: inst+20, arg1: inst+28, type: type2}
+// CHECK:STDOUT:     'inst+31':         {kind: ReturnExpr, arg0: inst+30, arg1: inst+13}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
 // CHECK:STDOUT:     'inst+1':          template inst+1
@@ -86,16 +89,18 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     'inst+10':         template inst+1
 // CHECK:STDOUT:     'inst+11':         template inst+1
 // CHECK:STDOUT:     'inst+12':         template inst+8
-// CHECK:STDOUT:     'inst+14':         template inst+14
+// CHECK:STDOUT:     'inst+14':         template inst+16
 // CHECK:STDOUT:     'inst+15':         template inst+15
-// CHECK:STDOUT:     'inst+20':         template inst+21
-// CHECK:STDOUT:     'inst+21':         template inst+21
-// CHECK:STDOUT:     'inst+22':         template inst+21
-// CHECK:STDOUT:     'inst+24':         template inst+21
-// CHECK:STDOUT:     'inst+25':         template inst+21
-// CHECK:STDOUT:     'inst+26':         template inst+27
-// CHECK:STDOUT:     'inst+27':         template inst+27
-// CHECK:STDOUT:     'inst+28':         template inst+27
+// CHECK:STDOUT:     'inst+16':         template inst+16
+// CHECK:STDOUT:     'inst+17':         template inst+17
+// CHECK:STDOUT:     'inst+22':         template inst+23
+// CHECK:STDOUT:     'inst+23':         template inst+23
+// CHECK:STDOUT:     'inst+24':         template inst+23
+// CHECK:STDOUT:     'inst+26':         template inst+23
+// CHECK:STDOUT:     'inst+27':         template inst+23
+// CHECK:STDOUT:     'inst+28':         template inst+29
+// CHECK:STDOUT:     'inst+29':         template inst+29
+// CHECK:STDOUT:     'inst+30':         template inst+29
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -119,30 +124,30 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       9:               inst+12
 // CHECK:STDOUT:       10:              inst+13
 // CHECK:STDOUT:     block6:
-// CHECK:STDOUT:       0:               inst+16
-// CHECK:STDOUT:       1:               inst+17
-// CHECK:STDOUT:       2:               inst+18
-// CHECK:STDOUT:       3:               inst+19
-// CHECK:STDOUT:       4:               inst+20
-// CHECK:STDOUT:       5:               inst+22
-// CHECK:STDOUT:       6:               inst+23
-// CHECK:STDOUT:       7:               inst+24
-// CHECK:STDOUT:       8:               inst+25
-// CHECK:STDOUT:       9:               inst+26
-// CHECK:STDOUT:       10:              inst+28
-// CHECK:STDOUT:       11:              inst+29
+// CHECK:STDOUT:       0:               inst+18
+// CHECK:STDOUT:       1:               inst+19
+// CHECK:STDOUT:       2:               inst+20
+// CHECK:STDOUT:       3:               inst+21
+// CHECK:STDOUT:       4:               inst+22
+// CHECK:STDOUT:       5:               inst+24
+// CHECK:STDOUT:       6:               inst+25
+// CHECK:STDOUT:       7:               inst+26
+// CHECK:STDOUT:       8:               inst+27
+// CHECK:STDOUT:       9:               inst+28
+// CHECK:STDOUT:       10:              inst+30
+// CHECK:STDOUT:       11:              inst+31
 // CHECK:STDOUT:     block7:
-// CHECK:STDOUT:       0:               inst+16
-// CHECK:STDOUT:       1:               inst+17
+// CHECK:STDOUT:       0:               inst+18
+// CHECK:STDOUT:       1:               inst+19
 // CHECK:STDOUT:     block8:          {}
 // CHECK:STDOUT:     block9:          {}
 // CHECK:STDOUT:     block10:
-// CHECK:STDOUT:       0:               inst+22
-// CHECK:STDOUT:       1:               inst+25
+// CHECK:STDOUT:       0:               inst+24
+// CHECK:STDOUT:       1:               inst+27
 // CHECK:STDOUT:     block11:         {}
 // CHECK:STDOUT:     block12:
-// CHECK:STDOUT:       0:               inst+21
-// CHECK:STDOUT:       1:               inst+21
+// CHECK:STDOUT:       0:               inst+23
+// CHECK:STDOUT:       1:               inst+23
 // CHECK:STDOUT:     block13:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+14
@@ -153,6 +158,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %.2: type = tuple_type ((), ()) [template]
+// CHECK:STDOUT:   %Foo: type = fn_type @Foo [template]
+// CHECK:STDOUT:   %struct: Foo = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type ((), ()) [template]
 // CHECK:STDOUT:   %tuple.1: () = tuple_value () [template]
 // CHECK:STDOUT:   %tuple.2: ((), ()) = tuple_value (%tuple.1, %tuple.1) [template]
@@ -160,9 +167,9 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Foo = %Foo
+// CHECK:STDOUT:     .Foo = %Foo.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo [template] {
+// CHECK:STDOUT:   %Foo.decl: Foo = fn_decl @Foo [template = constants.%struct] {
 // CHECK:STDOUT:     %.loc11_12.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc11_12.2: type = converted %.loc11_12.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %n.loc11_8.1: () = param n

+ 12 - 6
toolchain/check/testdata/basics/no_prelude/raw_identifier.carbon

@@ -24,15 +24,21 @@ fn C(r#if: ()) -> () {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %A: type = fn_type @A [template]
+// CHECK:STDOUT:   %struct.1: A = struct_value () [template]
+// CHECK:STDOUT:   %B: type = fn_type @B [template]
+// CHECK:STDOUT:   %struct.2: B = struct_value () [template]
+// CHECK:STDOUT:   %C: type = fn_type @C [template]
+// CHECK:STDOUT:   %struct.3: C = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .A = %A
-// CHECK:STDOUT:     .B = %B
-// CHECK:STDOUT:     .C = %C
+// CHECK:STDOUT:     .A = %A.decl
+// CHECK:STDOUT:     .B = %B.decl
+// CHECK:STDOUT:     .C = %C.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {
+// CHECK:STDOUT:   %A.decl: A = fn_decl @A [template = constants.%struct.1] {
 // CHECK:STDOUT:     %.loc11_10.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc11_10.2: type = converted %.loc11_10.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %n.loc11_6.1: () = param n
@@ -41,7 +47,7 @@ fn C(r#if: ()) -> () {
 // CHECK:STDOUT:     %.loc11_17.2: type = converted %.loc11_17.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     @A.%return: ref () = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {
+// CHECK:STDOUT:   %B.decl: B = fn_decl @B [template = constants.%struct.2] {
 // CHECK:STDOUT:     %.loc15_12.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc15_12.2: type = converted %.loc15_12.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %n.loc15_6.1: () = param n
@@ -50,7 +56,7 @@ fn C(r#if: ()) -> () {
 // CHECK:STDOUT:     %.loc15_19.2: type = converted %.loc15_19.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     @B.%return: ref () = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %C: <function> = fn_decl @C [template] {
+// CHECK:STDOUT:   %C.decl: C = fn_decl @C [template = constants.%struct.3] {
 // CHECK:STDOUT:     %.loc19_13.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc19_13.2: type = converted %.loc19_13.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %if.loc19_6.1: () = param r#if

+ 50 - 45
toolchain/check/testdata/basics/no_prelude/raw_ir.carbon

@@ -27,8 +27,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
 // CHECK:STDOUT:     type1:           {constant: template inst+1, value_rep: {kind: none, type: type1}}
 // CHECK:STDOUT:     type2:           {constant: template inst+8, value_rep: {kind: pointer, type: type4}}
-// CHECK:STDOUT:     type3:           {constant: template instFunctionType, value_rep: {kind: copy, type: type3}}
-// CHECK:STDOUT:     type4:           {constant: template inst+15, value_rep: {kind: copy, type: type4}}
+// CHECK:STDOUT:     type3:           {constant: template inst+15, value_rep: {kind: none, type: type1}}
+// CHECK:STDOUT:     type4:           {constant: template inst+17, value_rep: {kind: copy, type: type4}}
 // CHECK:STDOUT:   type_blocks:
 // CHECK:STDOUT:     typeBlock0:      {}
 // CHECK:STDOUT:     typeBlock1:      {}
@@ -44,7 +44,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       1:               type1
 // CHECK:STDOUT:     typeBlock8:      {}
 // CHECK:STDOUT:     typeBlock9:      {}
-// CHECK:STDOUT:     typeBlock10:
+// CHECK:STDOUT:     typeBlock10:     {}
+// CHECK:STDOUT:     typeBlock11:
 // CHECK:STDOUT:       0:               type1
 // CHECK:STDOUT:       1:               type1
 // CHECK:STDOUT:   insts:
@@ -63,21 +64,23 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     'inst+12':         {kind: Converted, arg0: inst+9, arg1: inst+8, type: typeTypeType}
 // CHECK:STDOUT:     'inst+13':         {kind: VarStorage, arg0: nameReturnSlot, type: type2}
 // CHECK:STDOUT:     'inst+14':         {kind: FunctionDecl, arg0: function0, arg1: block5, type: type3}
-// CHECK:STDOUT:     'inst+15':         {kind: PointerType, arg0: type2, type: typeTypeType}
-// CHECK:STDOUT:     'inst+16':         {kind: NameRef, arg0: name1, arg1: inst+5, type: type1}
-// CHECK:STDOUT:     'inst+17':         {kind: TupleLiteral, arg0: empty, type: type1}
-// CHECK:STDOUT:     'inst+18':         {kind: TupleLiteral, arg0: block7, type: type2}
-// CHECK:STDOUT:     'inst+19':         {kind: TupleAccess, arg0: inst+13, arg1: element0, type: type1}
-// CHECK:STDOUT:     'inst+20':         {kind: TupleInit, arg0: block8, arg1: inst+19, type: type1}
-// CHECK:STDOUT:     'inst+21':         {kind: TupleValue, arg0: block9, type: type1}
-// CHECK:STDOUT:     'inst+22':         {kind: Converted, arg0: inst+16, arg1: inst+20, type: type1}
-// CHECK:STDOUT:     'inst+23':         {kind: TupleAccess, arg0: inst+13, arg1: element1, type: type1}
-// CHECK:STDOUT:     'inst+24':         {kind: TupleInit, arg0: empty, arg1: inst+23, type: type1}
-// CHECK:STDOUT:     'inst+25':         {kind: Converted, arg0: inst+17, arg1: inst+24, type: type1}
-// CHECK:STDOUT:     'inst+26':         {kind: TupleInit, arg0: block10, arg1: inst+13, type: type2}
-// CHECK:STDOUT:     'inst+27':         {kind: TupleValue, arg0: block12, type: type2}
-// CHECK:STDOUT:     'inst+28':         {kind: Converted, arg0: inst+18, arg1: inst+26, type: type2}
-// CHECK:STDOUT:     'inst+29':         {kind: ReturnExpr, arg0: inst+28, arg1: inst+13}
+// CHECK:STDOUT:     'inst+15':         {kind: FunctionType, arg0: function0, type: typeTypeType}
+// CHECK:STDOUT:     'inst+16':         {kind: StructValue, arg0: empty, type: type3}
+// CHECK:STDOUT:     'inst+17':         {kind: PointerType, arg0: type2, type: typeTypeType}
+// CHECK:STDOUT:     'inst+18':         {kind: NameRef, arg0: name1, arg1: inst+5, type: type1}
+// CHECK:STDOUT:     'inst+19':         {kind: TupleLiteral, arg0: empty, type: type1}
+// CHECK:STDOUT:     'inst+20':         {kind: TupleLiteral, arg0: block7, type: type2}
+// CHECK:STDOUT:     'inst+21':         {kind: TupleAccess, arg0: inst+13, arg1: element0, type: type1}
+// CHECK:STDOUT:     'inst+22':         {kind: TupleInit, arg0: block8, arg1: inst+21, type: type1}
+// CHECK:STDOUT:     'inst+23':         {kind: TupleValue, arg0: block9, type: type1}
+// CHECK:STDOUT:     'inst+24':         {kind: Converted, arg0: inst+18, arg1: inst+22, type: type1}
+// CHECK:STDOUT:     'inst+25':         {kind: TupleAccess, arg0: inst+13, arg1: element1, type: type1}
+// CHECK:STDOUT:     'inst+26':         {kind: TupleInit, arg0: empty, arg1: inst+25, type: type1}
+// CHECK:STDOUT:     'inst+27':         {kind: Converted, arg0: inst+19, arg1: inst+26, type: type1}
+// CHECK:STDOUT:     'inst+28':         {kind: TupleInit, arg0: block10, arg1: inst+13, type: type2}
+// CHECK:STDOUT:     'inst+29':         {kind: TupleValue, arg0: block12, type: type2}
+// CHECK:STDOUT:     'inst+30':         {kind: Converted, arg0: inst+20, arg1: inst+28, type: type2}
+// CHECK:STDOUT:     'inst+31':         {kind: ReturnExpr, arg0: inst+30, arg1: inst+13}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     'inst+0':          template inst+0
 // CHECK:STDOUT:     'inst+1':          template inst+1
@@ -86,16 +89,18 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:     'inst+10':         template inst+1
 // CHECK:STDOUT:     'inst+11':         template inst+1
 // CHECK:STDOUT:     'inst+12':         template inst+8
-// CHECK:STDOUT:     'inst+14':         template inst+14
+// CHECK:STDOUT:     'inst+14':         template inst+16
 // CHECK:STDOUT:     'inst+15':         template inst+15
-// CHECK:STDOUT:     'inst+20':         template inst+21
-// CHECK:STDOUT:     'inst+21':         template inst+21
-// CHECK:STDOUT:     'inst+22':         template inst+21
-// CHECK:STDOUT:     'inst+24':         template inst+21
-// CHECK:STDOUT:     'inst+25':         template inst+21
-// CHECK:STDOUT:     'inst+26':         template inst+27
-// CHECK:STDOUT:     'inst+27':         template inst+27
-// CHECK:STDOUT:     'inst+28':         template inst+27
+// CHECK:STDOUT:     'inst+16':         template inst+16
+// CHECK:STDOUT:     'inst+17':         template inst+17
+// CHECK:STDOUT:     'inst+22':         template inst+23
+// CHECK:STDOUT:     'inst+23':         template inst+23
+// CHECK:STDOUT:     'inst+24':         template inst+23
+// CHECK:STDOUT:     'inst+26':         template inst+23
+// CHECK:STDOUT:     'inst+27':         template inst+23
+// CHECK:STDOUT:     'inst+28':         template inst+29
+// CHECK:STDOUT:     'inst+29':         template inst+29
+// CHECK:STDOUT:     'inst+30':         template inst+29
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -119,30 +124,30 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:       9:               inst+12
 // CHECK:STDOUT:       10:              inst+13
 // CHECK:STDOUT:     block6:
-// CHECK:STDOUT:       0:               inst+16
-// CHECK:STDOUT:       1:               inst+17
-// CHECK:STDOUT:       2:               inst+18
-// CHECK:STDOUT:       3:               inst+19
-// CHECK:STDOUT:       4:               inst+20
-// CHECK:STDOUT:       5:               inst+22
-// CHECK:STDOUT:       6:               inst+23
-// CHECK:STDOUT:       7:               inst+24
-// CHECK:STDOUT:       8:               inst+25
-// CHECK:STDOUT:       9:               inst+26
-// CHECK:STDOUT:       10:              inst+28
-// CHECK:STDOUT:       11:              inst+29
+// CHECK:STDOUT:       0:               inst+18
+// CHECK:STDOUT:       1:               inst+19
+// CHECK:STDOUT:       2:               inst+20
+// CHECK:STDOUT:       3:               inst+21
+// CHECK:STDOUT:       4:               inst+22
+// CHECK:STDOUT:       5:               inst+24
+// CHECK:STDOUT:       6:               inst+25
+// CHECK:STDOUT:       7:               inst+26
+// CHECK:STDOUT:       8:               inst+27
+// CHECK:STDOUT:       9:               inst+28
+// CHECK:STDOUT:       10:              inst+30
+// CHECK:STDOUT:       11:              inst+31
 // CHECK:STDOUT:     block7:
-// CHECK:STDOUT:       0:               inst+16
-// CHECK:STDOUT:       1:               inst+17
+// CHECK:STDOUT:       0:               inst+18
+// CHECK:STDOUT:       1:               inst+19
 // CHECK:STDOUT:     block8:          {}
 // CHECK:STDOUT:     block9:          {}
 // CHECK:STDOUT:     block10:
-// CHECK:STDOUT:       0:               inst+22
-// CHECK:STDOUT:       1:               inst+25
+// CHECK:STDOUT:       0:               inst+24
+// CHECK:STDOUT:       1:               inst+27
 // CHECK:STDOUT:     block11:         {}
 // CHECK:STDOUT:     block12:
-// CHECK:STDOUT:       0:               inst+21
-// CHECK:STDOUT:       1:               inst+21
+// CHECK:STDOUT:       0:               inst+23
+// CHECK:STDOUT:       1:               inst+23
 // CHECK:STDOUT:     block13:
 // CHECK:STDOUT:       0:               inst+0
 // CHECK:STDOUT:       1:               inst+14

+ 4 - 2
toolchain/check/testdata/basics/no_prelude/textual_ir.carbon

@@ -17,6 +17,8 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
 // CHECK:STDOUT:   %.2: type = tuple_type ((), ()) [template]
+// CHECK:STDOUT:   %Foo: type = fn_type @Foo [template]
+// CHECK:STDOUT:   %struct: Foo = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type ((), ()) [template]
 // CHECK:STDOUT:   %tuple.1: () = tuple_value () [template]
 // CHECK:STDOUT:   %tuple.2: ((), ()) = tuple_value (%tuple.1, %tuple.1) [template]
@@ -24,9 +26,9 @@ fn Foo(n: ()) -> ((), ()) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Foo = %Foo
+// CHECK:STDOUT:     .Foo = %Foo.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo [template] {
+// CHECK:STDOUT:   %Foo.decl: Foo = fn_decl @Foo [template = constants.%struct] {
 // CHECK:STDOUT:     %.loc11_12.1: () = tuple_literal ()
 // CHECK:STDOUT:     %.loc11_12.2: type = converted %.loc11_12.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:     %n.loc11_8.1: () = param n

+ 2 - 2
toolchain/check/testdata/basics/no_prelude/verbose.carbon

@@ -8,8 +8,8 @@
 // NOAUTOUPDATE
 // SET-CHECK-SUBSET
 // CHECK:STDERR: Node Push 0: FunctionIntroducer -> <none>
-// CHECK:STDERR: AddPlaceholderInst: {kind: FunctionDecl, arg0: {{.*}}, type: type{{[0-9]+}}}
-// CHECK:STDERR: ReplaceInst: inst+{{[0-9]+}} -> {kind: FunctionDecl, arg0: {{.*}}, type: type{{[0-9]+}}}
+// CHECK:STDERR: AddPlaceholderInst: {kind: FunctionDecl, arg0: function<invalid>, arg1: empty}
+// CHECK:STDERR: ReplaceInst: inst+{{[0-9]+}} -> {kind: FunctionDecl, arg0: function{{[0-9]+}}, arg1: empty, type: type{{[0-9]+}}}
 // CHECK:STDERR: inst_block_stack_ Push 1
 // CHECK:STDERR: AddInst: {kind: Return}
 // CHECK:STDERR: inst_block_stack_ Pop 1: block{{[0-9]+}}

+ 69 - 66
toolchain/check/testdata/basics/numeric_literals.carbon

@@ -28,104 +28,107 @@ fn F() {
 // CHECK:STDOUT: --- numeric_literals.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 6 [template]
-// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 6] [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 8 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 9 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.10: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.11: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.12: i32 = int_literal 4 [template]
-// CHECK:STDOUT:   %.13: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %array.1: [i32; 6] = tuple_value (%.4, %.5, %.4, %.4, %.6, %.6) [template]
-// CHECK:STDOUT:   %.14: type = array_type %.1, f64 [template]
-// CHECK:STDOUT:   %.15: type = ptr_type [f64; 6] [template]
-// CHECK:STDOUT:   %.16: f64 = float_literal 0.90000000000000002 [template]
-// CHECK:STDOUT:   %.17: f64 = float_literal 8 [template]
-// CHECK:STDOUT:   %.18: f64 = float_literal 80 [template]
-// CHECK:STDOUT:   %.19: f64 = float_literal 1.0E+7 [template]
-// CHECK:STDOUT:   %.20: f64 = float_literal 1.0E+8 [template]
-// CHECK:STDOUT:   %.21: f64 = float_literal 1.0E-8 [template]
-// CHECK:STDOUT:   %.22: type = tuple_type (f64, f64, f64, f64, f64, f64) [template]
-// CHECK:STDOUT:   %array.2: [f64; 6] = tuple_value (%.16, %.17, %.18, %.19, %.20, %.21) [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 9 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.8: type = tuple_type (i32, i32, i32, i32, i32, i32) [template]
+// CHECK:STDOUT:   %.9: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.11: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.12: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.13: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.14: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %array.1: [i32; 6] = tuple_value (%.5, %.6, %.5, %.5, %.7, %.7) [template]
+// CHECK:STDOUT:   %.15: type = array_type %.2, f64 [template]
+// CHECK:STDOUT:   %.16: type = ptr_type [f64; 6] [template]
+// CHECK:STDOUT:   %.17: f64 = float_literal 0.90000000000000002 [template]
+// CHECK:STDOUT:   %.18: f64 = float_literal 8 [template]
+// CHECK:STDOUT:   %.19: f64 = float_literal 80 [template]
+// CHECK:STDOUT:   %.20: f64 = float_literal 1.0E+7 [template]
+// CHECK:STDOUT:   %.21: f64 = float_literal 1.0E+8 [template]
+// CHECK:STDOUT:   %.22: f64 = float_literal 1.0E-8 [template]
+// CHECK:STDOUT:   %.23: type = tuple_type (f64, f64, f64, f64, f64, f64) [template]
+// CHECK:STDOUT:   %array.2: [f64; 6] = tuple_value (%.17, %.18, %.19, %.20, %.21, %.22) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 6 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_20: type = array_type %.loc10_19, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 6 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_20: type = array_type %.loc10_19, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %ints.var: ref [i32; 6] = var ints
 // CHECK:STDOUT:   %ints: ref [i32; 6] = bind_name ints, %ints.var
-// CHECK:STDOUT:   %.loc11: i32 = int_literal 8 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc12: i32 = int_literal 9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc13: i32 = int_literal 8 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 8 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15: i32 = int_literal 2147483647 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc16: i32 = int_literal 2147483647 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc11: i32 = int_literal 8 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc12: i32 = int_literal 9 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13: i32 = int_literal 8 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 8 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15: i32 = int_literal 2147483647 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc16: i32 = int_literal 2147483647 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc17_3.1: (i32, i32, i32, i32, i32, i32) = tuple_literal (%.loc11, %.loc12, %.loc13, %.loc14, %.loc15, %.loc16)
-// CHECK:STDOUT:   %.loc17_3.2: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc17_3.2: i32 = int_literal 0 [template = constants.%.9]
 // CHECK:STDOUT:   %.loc17_3.3: ref i32 = array_index %ints.var, %.loc17_3.2
-// CHECK:STDOUT:   %.loc17_3.4: init i32 = initialize_from %.loc11 to %.loc17_3.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_3.5: i32 = int_literal 1 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc17_3.4: init i32 = initialize_from %.loc11 to %.loc17_3.3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_3.5: i32 = int_literal 1 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc17_3.6: ref i32 = array_index %ints.var, %.loc17_3.5
-// CHECK:STDOUT:   %.loc17_3.7: init i32 = initialize_from %.loc12 to %.loc17_3.6 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc17_3.8: i32 = int_literal 2 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc17_3.7: init i32 = initialize_from %.loc12 to %.loc17_3.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc17_3.8: i32 = int_literal 2 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc17_3.9: ref i32 = array_index %ints.var, %.loc17_3.8
-// CHECK:STDOUT:   %.loc17_3.10: init i32 = initialize_from %.loc13 to %.loc17_3.9 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_3.11: i32 = int_literal 3 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc17_3.10: init i32 = initialize_from %.loc13 to %.loc17_3.9 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_3.11: i32 = int_literal 3 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc17_3.12: ref i32 = array_index %ints.var, %.loc17_3.11
-// CHECK:STDOUT:   %.loc17_3.13: init i32 = initialize_from %.loc14 to %.loc17_3.12 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc17_3.14: i32 = int_literal 4 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc17_3.13: init i32 = initialize_from %.loc14 to %.loc17_3.12 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_3.14: i32 = int_literal 4 [template = constants.%.13]
 // CHECK:STDOUT:   %.loc17_3.15: ref i32 = array_index %ints.var, %.loc17_3.14
-// CHECK:STDOUT:   %.loc17_3.16: init i32 = initialize_from %.loc15 to %.loc17_3.15 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc17_3.17: i32 = int_literal 5 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc17_3.16: init i32 = initialize_from %.loc15 to %.loc17_3.15 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc17_3.17: i32 = int_literal 5 [template = constants.%.14]
 // CHECK:STDOUT:   %.loc17_3.18: ref i32 = array_index %ints.var, %.loc17_3.17
-// CHECK:STDOUT:   %.loc17_3.19: init i32 = initialize_from %.loc16 to %.loc17_3.18 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc17_3.19: init i32 = initialize_from %.loc16 to %.loc17_3.18 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc17_3.20: init [i32; 6] = array_init (%.loc17_3.4, %.loc17_3.7, %.loc17_3.10, %.loc17_3.13, %.loc17_3.16, %.loc17_3.19) to %ints.var [template = constants.%array.1]
 // CHECK:STDOUT:   %.loc17_4: init [i32; 6] = converted %.loc17_3.1, %.loc17_3.20 [template = constants.%array.1]
 // CHECK:STDOUT:   assign %ints.var, %.loc17_4
-// CHECK:STDOUT:   %.loc18_21: i32 = int_literal 6 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_22: type = array_type %.loc18_21, f64 [template = constants.%.14]
+// CHECK:STDOUT:   %.loc18_21: i32 = int_literal 6 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc18_22: type = array_type %.loc18_21, f64 [template = constants.%.15]
 // CHECK:STDOUT:   %floats.var: ref [f64; 6] = var floats
 // CHECK:STDOUT:   %floats: ref [f64; 6] = bind_name floats, %floats.var
-// CHECK:STDOUT:   %.loc19: f64 = float_literal 0.90000000000000002 [template = constants.%.16]
-// CHECK:STDOUT:   %.loc20: f64 = float_literal 8 [template = constants.%.17]
-// CHECK:STDOUT:   %.loc21: f64 = float_literal 80 [template = constants.%.18]
-// CHECK:STDOUT:   %.loc22: f64 = float_literal 1.0E+7 [template = constants.%.19]
-// CHECK:STDOUT:   %.loc23: f64 = float_literal 1.0E+8 [template = constants.%.20]
-// CHECK:STDOUT:   %.loc24: f64 = float_literal 1.0E-8 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc19: f64 = float_literal 0.90000000000000002 [template = constants.%.17]
+// CHECK:STDOUT:   %.loc20: f64 = float_literal 8 [template = constants.%.18]
+// CHECK:STDOUT:   %.loc21: f64 = float_literal 80 [template = constants.%.19]
+// CHECK:STDOUT:   %.loc22: f64 = float_literal 1.0E+7 [template = constants.%.20]
+// CHECK:STDOUT:   %.loc23: f64 = float_literal 1.0E+8 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc24: f64 = float_literal 1.0E-8 [template = constants.%.22]
 // CHECK:STDOUT:   %.loc25_3.1: (f64, f64, f64, f64, f64, f64) = tuple_literal (%.loc19, %.loc20, %.loc21, %.loc22, %.loc23, %.loc24)
-// CHECK:STDOUT:   %.loc25_3.2: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc25_3.2: i32 = int_literal 0 [template = constants.%.9]
 // CHECK:STDOUT:   %.loc25_3.3: ref f64 = array_index %floats.var, %.loc25_3.2
-// CHECK:STDOUT:   %.loc25_3.4: init f64 = initialize_from %.loc19 to %.loc25_3.3 [template = constants.%.16]
-// CHECK:STDOUT:   %.loc25_3.5: i32 = int_literal 1 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc25_3.4: init f64 = initialize_from %.loc19 to %.loc25_3.3 [template = constants.%.17]
+// CHECK:STDOUT:   %.loc25_3.5: i32 = int_literal 1 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc25_3.6: ref f64 = array_index %floats.var, %.loc25_3.5
-// CHECK:STDOUT:   %.loc25_3.7: init f64 = initialize_from %.loc20 to %.loc25_3.6 [template = constants.%.17]
-// CHECK:STDOUT:   %.loc25_3.8: i32 = int_literal 2 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc25_3.7: init f64 = initialize_from %.loc20 to %.loc25_3.6 [template = constants.%.18]
+// CHECK:STDOUT:   %.loc25_3.8: i32 = int_literal 2 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc25_3.9: ref f64 = array_index %floats.var, %.loc25_3.8
-// CHECK:STDOUT:   %.loc25_3.10: init f64 = initialize_from %.loc21 to %.loc25_3.9 [template = constants.%.18]
-// CHECK:STDOUT:   %.loc25_3.11: i32 = int_literal 3 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc25_3.10: init f64 = initialize_from %.loc21 to %.loc25_3.9 [template = constants.%.19]
+// CHECK:STDOUT:   %.loc25_3.11: i32 = int_literal 3 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc25_3.12: ref f64 = array_index %floats.var, %.loc25_3.11
-// CHECK:STDOUT:   %.loc25_3.13: init f64 = initialize_from %.loc22 to %.loc25_3.12 [template = constants.%.19]
-// CHECK:STDOUT:   %.loc25_3.14: i32 = int_literal 4 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc25_3.13: init f64 = initialize_from %.loc22 to %.loc25_3.12 [template = constants.%.20]
+// CHECK:STDOUT:   %.loc25_3.14: i32 = int_literal 4 [template = constants.%.13]
 // CHECK:STDOUT:   %.loc25_3.15: ref f64 = array_index %floats.var, %.loc25_3.14
-// CHECK:STDOUT:   %.loc25_3.16: init f64 = initialize_from %.loc23 to %.loc25_3.15 [template = constants.%.20]
-// CHECK:STDOUT:   %.loc25_3.17: i32 = int_literal 5 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc25_3.16: init f64 = initialize_from %.loc23 to %.loc25_3.15 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc25_3.17: i32 = int_literal 5 [template = constants.%.14]
 // CHECK:STDOUT:   %.loc25_3.18: ref f64 = array_index %floats.var, %.loc25_3.17
-// CHECK:STDOUT:   %.loc25_3.19: init f64 = initialize_from %.loc24 to %.loc25_3.18 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc25_3.19: init f64 = initialize_from %.loc24 to %.loc25_3.18 [template = constants.%.22]
 // CHECK:STDOUT:   %.loc25_3.20: init [f64; 6] = array_init (%.loc25_3.4, %.loc25_3.7, %.loc25_3.10, %.loc25_3.13, %.loc25_3.16, %.loc25_3.19) to %floats.var [template = constants.%array.2]
 // CHECK:STDOUT:   %.loc25_4: init [f64; 6] = converted %.loc25_3.1, %.loc25_3.20 [template = constants.%array.2]
 // CHECK:STDOUT:   assign %floats.var, %.loc25_4

+ 8 - 2
toolchain/check/testdata/basics/run.carbon

@@ -8,13 +8,19 @@ fn Run() {}
 
 // CHECK:STDOUT: --- run.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Run = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 7 - 4
toolchain/check/testdata/basics/run_i32.carbon

@@ -9,23 +9,26 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT: --- run_i32.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Run = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {
 // CHECK:STDOUT:     @Run.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template = constants.%.2]
 // CHECK:STDOUT:   return %.loc7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 15 - 6
toolchain/check/testdata/builtins/bool/make_type.carbon

@@ -20,13 +20,19 @@ var b: Bool() = false;
 
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Bool = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Bool = %Bool
+// CHECK:STDOUT:     .Bool = %Bool.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Bool: <function> = fn_decl @Bool [template] {
+// CHECK:STDOUT:   %Bool.decl: Bool = fn_decl @Bool [template = constants.%struct] {
 // CHECK:STDOUT:     @Bool.%return: ref type = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -36,7 +42,10 @@ var b: Bool() = false;
 // CHECK:STDOUT: --- use_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: bool = bool_literal false [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Bool = struct_value () [template]
+// CHECK:STDOUT:   %.2: bool = bool_literal false [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -45,9 +54,9 @@ var b: Bool() = false;
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+3, loc_11 [template = imports.%Bool]
+// CHECK:STDOUT:   %import_ref: Bool = import_ref ir1, inst+3, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Bool.ref: <function> = name_ref Bool, %import_ref [template = imports.%Bool]
+// CHECK:STDOUT:   %Bool.ref: Bool = name_ref Bool, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %bool.make_type: init type = call %Bool.ref() [template = bool]
 // CHECK:STDOUT:   %.loc6_13.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:   %.loc6_13.2: type = converted %bool.make_type, %.loc6_13.1 [template = bool]
@@ -59,7 +68,7 @@ var b: Bool() = false;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc6: bool = bool_literal false [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6: bool = bool_literal false [template = constants.%.2]
 // CHECK:STDOUT:   assign file.%b.var, %.loc6
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 52 - 29
toolchain/check/testdata/builtins/float/add.carbon

@@ -49,27 +49,32 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: f64 = float_literal 2.2000000000000002 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 2.3000000000000003 [template]
-// CHECK:STDOUT:   %.3: f64 = float_literal 4.5 [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Add = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.2: f64 = float_literal 2.2000000000000002 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 2.3000000000000003 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 4.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .Add = %Add.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Add.%a: f64 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Add.%b: f64 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Add.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
@@ -84,7 +89,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, file.%Add [template = file.%Add]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.add: init f64 = call %Add.ref(%a.ref, %b.ref)
@@ -95,34 +100,52 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, file.%Add [template = file.%Add]
-// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2.2000000000000002 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 2.3000000000000003 [template = constants.%.2]
-// CHECK:STDOUT:   %float.add: init f64 = call %Add.ref(%.loc8_18, %.loc8_23) [template = constants.%.3]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2.2000000000000002 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 2.3000000000000003 [template = constants.%.3]
+// CHECK:STDOUT:   %float.add: init f64 = call %Add.ref(%.loc8_18, %.loc8_23) [template = constants.%.4]
 // CHECK:STDOUT:   assign file.%x.var, %float.add
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
@@ -131,26 +154,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
@@ -159,7 +182,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
@@ -178,7 +201,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init f64 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc21_19.1: f64 = value_of_initializer %TooFew.call
@@ -188,7 +211,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: f64, %b: f64, %c: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: f64 = name_ref c, %c
@@ -200,7 +223,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)

+ 69 - 46
toolchain/check/testdata/builtins/float/div.carbon

@@ -51,33 +51,38 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: f64 = float_literal 10 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 2.5 [template]
-// CHECK:STDOUT:   %.3: f64 = float_literal 4 [template]
-// CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
-// CHECK:STDOUT:   %.5: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.6: f64 = float_literal +Inf [template]
-// CHECK:STDOUT:   %.7: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.2: f64 = float_literal 10 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 2.5 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 4 [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.7: f64 = float_literal +Inf [template]
 // CHECK:STDOUT:   %.8: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal NaN [template]
+// CHECK:STDOUT:   %.9: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.10: f64 = float_literal NaN [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .Div = %Div.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:     .a = %a.loc8
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Div.%a: f64 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Div.%b: f64 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Div.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
@@ -86,19 +91,19 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.var: ref f64 = var a
 // CHECK:STDOUT:   %a.loc8: ref f64 = bind_name a, %a.var
-// CHECK:STDOUT:   %Div.ref.loc9: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc9_18: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_23: f64 = float_literal 0 [template = constants.%.5]
-// CHECK:STDOUT:   %float.div.loc9: init f64 = call %Div.ref.loc9(%.loc9_18, %.loc9_23) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_27.1: f64 = value_of_initializer %float.div.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_27.2: f64 = converted %float.div.loc9, %.loc9_27.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc9_18: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_23: f64 = float_literal 0 [template = constants.%.6]
+// CHECK:STDOUT:   %float.div.loc9: init f64 = call %Div.ref.loc9(%.loc9_18, %.loc9_23) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_27.1: f64 = value_of_initializer %float.div.loc9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_27.2: f64 = converted %float.div.loc9, %.loc9_27.1 [template = constants.%.7]
 // CHECK:STDOUT:   %b.loc9: f64 = bind_name b, %.loc9_27.2
-// CHECK:STDOUT:   %Div.ref.loc10: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc10_18: f64 = float_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %float.div.loc10: init f64 = call %Div.ref.loc10(%.loc10_18, %.loc10_23) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc10_27.1: f64 = value_of_initializer %float.div.loc10 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc10_27.2: f64 = converted %float.div.loc10, %.loc10_27.1 [template = constants.%.9]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc10_18: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %float.div.loc10: init f64 = call %Div.ref.loc10(%.loc10_18, %.loc10_23) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc10_27.1: f64 = value_of_initializer %float.div.loc10 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc10_27.2: f64 = converted %float.div.loc10, %.loc10_27.1 [template = constants.%.10]
 // CHECK:STDOUT:   %c: f64 = bind_name c, %.loc10_27.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -106,7 +111,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, file.%Div [template = file.%Div]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.div: init f64 = call %Div.ref(%a.ref, %b.ref)
@@ -117,34 +122,52 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, file.%Div [template = file.%Div]
-// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 10 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_24: f64 = float_literal 2.5 [template = constants.%.2]
-// CHECK:STDOUT:   %float.div: init f64 = call %Div.ref(%.loc8_18, %.loc8_24) [template = constants.%.3]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 10 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_24: f64 = float_literal 2.5 [template = constants.%.3]
+// CHECK:STDOUT:   %float.div: init f64 = call %Div.ref(%.loc8_18, %.loc8_24) [template = constants.%.4]
 // CHECK:STDOUT:   assign file.%a.var, %float.div
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
@@ -153,26 +176,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
@@ -181,7 +204,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
@@ -200,7 +223,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init f64 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc21_19.1: f64 = value_of_initializer %TooFew.call
@@ -210,7 +233,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: f64, %b: f64, %c: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: f64 = name_ref c, %c
@@ -222,7 +245,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)

+ 25 - 13
toolchain/check/testdata/builtins/float/eq.carbon

@@ -32,10 +32,14 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT: --- float_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Eq: type = fn_type @Eq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Eq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
@@ -43,19 +47,21 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:   %.7: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.8: f64 = float_literal 2 [template]
 // CHECK:STDOUT:   %.9: bool = bool_literal false [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Eq = %Eq
+// CHECK:STDOUT:     .Eq = %Eq.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Eq: <function> = fn_decl @Eq [template] {
+// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_7.1: f64 = param a
 // CHECK:STDOUT:     @Eq.%a: f64 = bind_name a, %a.loc2_7.1
 // CHECK:STDOUT:     %b.loc2_15.1: f64 = param b
@@ -64,7 +70,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc7_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc7_6.1
@@ -72,7 +78,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:     %false_.loc7_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc7_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc12_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc12_16.1
 // CHECK:STDOUT:     %b.loc12_24.1: f64 = param b
@@ -96,7 +102,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Eq.ref.loc8: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref.loc8: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc8_19: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc8_24: f64 = float_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %float.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_24) [template = constants.%.6]
@@ -115,7 +121,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT: !if.expr.result.loc8:
 // CHECK:STDOUT:   %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Eq.ref.loc9: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref.loc9: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_20: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc9_25: f64 = float_literal 2 [template = constants.%.8]
 // CHECK:STDOUT:   %float.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_25) [template = constants.%.9]
@@ -138,7 +144,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Eq.ref: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.eq: init bool = call %Eq.ref(%a.ref, %b.ref)
@@ -149,13 +155,19 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .WrongResult = %WrongResult
+// CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult: <function> = fn_decl @WrongResult [template] {
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc7_16.1: f64 = param a
 // CHECK:STDOUT:     @WrongResult.%a: f64 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: f64 = param b

+ 26 - 18
toolchain/check/testdata/builtins/float/greater.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_greater.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Greater: type = fn_type @Greater [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Greater = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 2 [template]
@@ -46,34 +52,36 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   %.15: f64 = float_literal 0 [template]
 // CHECK:STDOUT:   %.16: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.17: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Greater = %Greater
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Greater = %Greater.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Greater: <function> = fn_decl @Greater [template] {
+// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_12.1: f64 = param a
 // CHECK:STDOUT:     @Greater.%a: f64 = bind_name a, %a.loc2_12.1
 // CHECK:STDOUT:     %b.loc2_20.1: f64 = param b
 // CHECK:STDOUT:     @Greater.%b: f64 = bind_name b, %b.loc2_20.1
 // CHECK:STDOUT:     @Greater.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -81,7 +89,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
@@ -107,7 +115,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc9: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc9: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_25: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_30: f64 = float_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %float.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_30) [template = constants.%.6]
@@ -126,7 +134,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc10: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc10: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc10: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_25: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc10_30: f64 = float_literal 1 [template = constants.%.8]
 // CHECK:STDOUT:   %float.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_30) [template = constants.%.6]
@@ -145,7 +153,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc11: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Greater.ref.loc11: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc11: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.9]
 // CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.10]
 // CHECK:STDOUT:   %float.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.11]
@@ -164,8 +172,8 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_13.3: type = block_arg !if.expr.result.loc11 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc12: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc12: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Greater.ref.loc12: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_32: f64 = float_literal 1 [template = constants.%.12]
 // CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.13]
 // CHECK:STDOUT:   %.loc12_38: f64 = float_literal 0 [template = constants.%.14]
@@ -187,9 +195,9 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Greater.ref.loc13: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc13: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.15]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_36: f64 = float_literal 1 [template = constants.%.16]
 // CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.17]
 // CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.17]
@@ -214,7 +222,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Greater.ref: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.greater: init bool = call %Greater.ref(%a.ref, %b.ref)

+ 26 - 18
toolchain/check/testdata/builtins/float/greater_eq.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_greater_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %GreaterEq: type = fn_type @GreaterEq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: GreaterEq = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 2 [template]
@@ -46,34 +52,36 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   %.15: f64 = float_literal 0 [template]
 // CHECK:STDOUT:   %.16: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.17: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .GreaterEq = %GreaterEq
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .GreaterEq = %GreaterEq.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %GreaterEq: <function> = fn_decl @GreaterEq [template] {
+// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_14.1: f64 = param a
 // CHECK:STDOUT:     @GreaterEq.%a: f64 = bind_name a, %a.loc2_14.1
 // CHECK:STDOUT:     %b.loc2_22.1: f64 = param b
 // CHECK:STDOUT:     @GreaterEq.%b: f64 = bind_name b, %b.loc2_22.1
 // CHECK:STDOUT:     @GreaterEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -81,7 +89,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
@@ -107,7 +115,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: False = name_ref false_, %false_
-// CHECK:STDOUT:   %GreaterEq.ref.loc9: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc9: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_27: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_32: f64 = float_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %float.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_32) [template = constants.%.6]
@@ -126,7 +134,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc10: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc10: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc10: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_26: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc10_31: f64 = float_literal 1 [template = constants.%.8]
 // CHECK:STDOUT:   %float.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_31) [template = constants.%.9]
@@ -145,7 +153,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc11: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc11: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc11: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_26: f64 = float_literal 1 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc11_31: f64 = float_literal 0 [template = constants.%.11]
 // CHECK:STDOUT:   %float.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_31) [template = constants.%.9]
@@ -164,8 +172,8 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_13.3: type = block_arg !if.expr.result.loc11 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc12: False = name_ref false_, %false_
-// CHECK:STDOUT:   %GreaterEq.ref.loc12: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %GreaterEq.ref.loc12: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_34: f64 = float_literal 1 [template = constants.%.12]
 // CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.13]
 // CHECK:STDOUT:   %.loc12_40: f64 = float_literal 0 [template = constants.%.14]
@@ -187,9 +195,9 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc13: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc13: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_26: f64 = float_literal 0 [template = constants.%.15]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_38: f64 = float_literal 1 [template = constants.%.16]
 // CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_38) [template = constants.%.17]
 // CHECK:STDOUT:   %.loc13_25.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.17]
@@ -214,7 +222,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %GreaterEq.ref: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.greater_eq: init bool = call %GreaterEq.ref(%a.ref, %b.ref)

+ 26 - 18
toolchain/check/testdata/builtins/float/less.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_less.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Less: type = fn_type @Less [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Less = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 2 [template]
@@ -46,34 +52,36 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   %.15: f64 = float_literal 0 [template]
 // CHECK:STDOUT:   %.16: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.17: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Less = %Less
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Less = %Less.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Less: <function> = fn_decl @Less [template] {
+// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_9.1: f64 = param a
 // CHECK:STDOUT:     @Less.%a: f64 = bind_name a, %a.loc2_9.1
 // CHECK:STDOUT:     %b.loc2_17.1: f64 = param b
 // CHECK:STDOUT:     @Less.%b: f64 = bind_name b, %b.loc2_17.1
 // CHECK:STDOUT:     @Less.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -81,7 +89,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
@@ -107,7 +115,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Less.ref.loc9: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc9: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_21: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_26: f64 = float_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %float.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.6]
@@ -126,7 +134,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc10: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc10: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc10: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_22: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc10_27: f64 = float_literal 1 [template = constants.%.8]
 // CHECK:STDOUT:   %float.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_27) [template = constants.%.9]
@@ -145,7 +153,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc11: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc11: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc11: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_22: f64 = float_literal 1 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc11_27: f64 = float_literal 0 [template = constants.%.11]
 // CHECK:STDOUT:   %float.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_27) [template = constants.%.9]
@@ -164,8 +172,8 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_14.3: type = block_arg !if.expr.result.loc11 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc12: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Less.ref.loc12: <function> = name_ref Less, file.%Less [template = file.%Less]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Less.ref.loc12: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_28: f64 = float_literal 1 [template = constants.%.12]
 // CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.13]
 // CHECK:STDOUT:   %.loc12_34: f64 = float_literal 0 [template = constants.%.14]
@@ -187,9 +195,9 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc13: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc13: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_22: f64 = float_literal 0 [template = constants.%.15]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_34: f64 = float_literal 1 [template = constants.%.16]
 // CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.17]
 // CHECK:STDOUT:   %.loc13_21.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.17]
@@ -214,7 +222,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Less.ref: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.less: init bool = call %Less.ref(%a.ref, %b.ref)

+ 26 - 18
toolchain/check/testdata/builtins/float/less_eq.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_less_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %LessEq: type = fn_type @LessEq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: LessEq = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 2 [template]
@@ -46,34 +52,36 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   %.15: f64 = float_literal 0 [template]
 // CHECK:STDOUT:   %.16: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.17: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .LessEq = %LessEq
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .LessEq = %LessEq.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LessEq: <function> = fn_decl @LessEq [template] {
+// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_11.1: f64 = param a
 // CHECK:STDOUT:     @LessEq.%a: f64 = bind_name a, %a.loc2_11.1
 // CHECK:STDOUT:     %b.loc2_19.1: f64 = param b
 // CHECK:STDOUT:     @LessEq.%b: f64 = bind_name b, %b.loc2_19.1
 // CHECK:STDOUT:     @LessEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -81,7 +89,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
@@ -107,7 +115,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc9: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc9: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_23: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_28: f64 = float_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %float.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_28) [template = constants.%.6]
@@ -126,7 +134,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc10: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc10: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc10: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_23: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc10_28: f64 = float_literal 1 [template = constants.%.8]
 // CHECK:STDOUT:   %float.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_28) [template = constants.%.6]
@@ -145,7 +153,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc11: False = name_ref false_, %false_
-// CHECK:STDOUT:   %LessEq.ref.loc11: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc11: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.9]
 // CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.10]
 // CHECK:STDOUT:   %float.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.11]
@@ -164,8 +172,8 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_14.3: type = block_arg !if.expr.result.loc11 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc12: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc12: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %LessEq.ref.loc12: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_30: f64 = float_literal 1 [template = constants.%.12]
 // CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.13]
 // CHECK:STDOUT:   %.loc12_36: f64 = float_literal 0 [template = constants.%.14]
@@ -187,9 +195,9 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: False = name_ref false_, %false_
-// CHECK:STDOUT:   %LessEq.ref.loc13: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc13: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.15]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_36: f64 = float_literal 1 [template = constants.%.16]
 // CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.17]
 // CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.17]
@@ -214,7 +222,7 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %LessEq.ref: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.less_eq: init bool = call %LessEq.ref(%a.ref, %b.ref)

+ 32 - 18
toolchain/check/testdata/builtins/float/make_type.carbon

@@ -42,13 +42,19 @@ var dyn: Float(dyn_size);
 
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Float = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Float = %Float
+// CHECK:STDOUT:     .Float = %Float.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float: <function> = fn_decl @Float [template] {
+// CHECK:STDOUT:   %Float.decl: Float = fn_decl @Float [template = constants.%struct] {
 // CHECK:STDOUT:     %size.loc4_10.1: i32 = param size
 // CHECK:STDOUT:     @Float.%size: i32 = bind_name size, %size.loc4_10.1
 // CHECK:STDOUT:     @Float.%return: ref type = var <return slot>
@@ -60,8 +66,13 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: --- use_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %GetFloat: type = fn_type @GetFloat [template]
+// CHECK:STDOUT:   %struct.2: GetFloat = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -69,18 +80,18 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:     .Float = %import_ref
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .f = %f
-// CHECK:STDOUT:     .GetFloat = %GetFloat
+// CHECK:STDOUT:     .GetFloat = %GetFloat.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%Float]
+// CHECK:STDOUT:   %import_ref: Float = import_ref ir1, inst+5, loc_11 [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float.ref: <function> = name_ref Float, %import_ref [template = imports.%Float]
-// CHECK:STDOUT:   %.loc6_14: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc6_14: i32 = int_literal 64 [template = constants.%.2]
 // CHECK:STDOUT:   %float.make_type: init type = call %Float.ref(%.loc6_14) [template = f64]
 // CHECK:STDOUT:   %.loc6_16.1: type = value_of_initializer %float.make_type [template = f64]
 // CHECK:STDOUT:   %.loc6_16.2: type = converted %float.make_type, %.loc6_16.1 [template = f64]
 // CHECK:STDOUT:   %f.var: ref f64 = var f
 // CHECK:STDOUT:   %f: ref f64 = bind_name f, %f.var
-// CHECK:STDOUT:   %GetFloat: <function> = fn_decl @GetFloat [template] {
+// CHECK:STDOUT:   %GetFloat.decl: GetFloat = fn_decl @GetFloat [template = constants.%struct.2] {
 // CHECK:STDOUT:     %dyn_size.loc8_13.1: i32 = param dyn_size
 // CHECK:STDOUT:     @GetFloat.%dyn_size: i32 = bind_name dyn_size, %dyn_size.loc8_13.1
 // CHECK:STDOUT:     @GetFloat.%return: ref type = var <return slot>
@@ -91,7 +102,7 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @GetFloat(%dyn_size: i32) -> type {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Float.ref: <function> = name_ref Float, file.%import_ref [template = imports.%Float]
+// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, file.%import_ref [template = constants.%struct.1]
 // CHECK:STDOUT:   %dyn_size.ref: i32 = name_ref dyn_size, %dyn_size
 // CHECK:STDOUT:   %float.make_type: init type = call %Float.ref(%dyn_size.ref)
 // CHECK:STDOUT:   %.loc9_25.1: type = value_of_initializer %float.make_type
@@ -101,7 +112,7 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc6: f64 = float_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6: f64 = float_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   assign file.%f.var, %.loc6
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -109,8 +120,11 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: --- fail_invalid_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 32 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Float = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 64 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -121,10 +135,10 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:     .dyn_size = %dyn_size
 // CHECK:STDOUT:     .dyn = %dyn
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%Float]
+// CHECK:STDOUT:   %import_ref: Float = import_ref ir1, inst+5, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float.ref.loc10: <function> = name_ref Float, %import_ref [template = imports.%Float]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 32 [template = constants.%.1]
+// CHECK:STDOUT:   %Float.ref.loc10: Float = name_ref Float, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 32 [template = constants.%.2]
 // CHECK:STDOUT:   %float.make_type.loc10: init type = call %Float.ref.loc10(%.loc10_26) [template = <error>]
 // CHECK:STDOUT:   %.loc10_28.1: type = value_of_initializer %float.make_type.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_28.2: type = converted %float.make_type.loc10, %.loc10_28.1 [template = <error>]
@@ -132,7 +146,7 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:   %invalid_float: ref <error> = bind_name invalid_float, %invalid_float.var
 // CHECK:STDOUT:   %dyn_size.var: ref i32 = var dyn_size
 // CHECK:STDOUT:   %dyn_size: ref i32 = bind_name dyn_size, %dyn_size.var
-// CHECK:STDOUT:   %Float.ref.loc16: <function> = name_ref Float, %import_ref [template = imports.%Float]
+// CHECK:STDOUT:   %Float.ref.loc16: Float = name_ref Float, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %dyn_size.ref: ref i32 = name_ref dyn_size, %dyn_size
 // CHECK:STDOUT:   %.loc16_16: i32 = bind_value %dyn_size.ref
 // CHECK:STDOUT:   %float.make_type.loc16: init type = call %Float.ref.loc16(%.loc16_16)
@@ -146,7 +160,7 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc12: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12: i32 = int_literal 64 [template = constants.%.3]
 // CHECK:STDOUT:   assign file.%dyn_size.var, %.loc12
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 52 - 29
toolchain/check/testdata/builtins/float/mul.carbon

@@ -49,27 +49,32 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- mul_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: f64 = float_literal 2 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 0.5 [template]
-// CHECK:STDOUT:   %.3: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mul = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.2: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 0.5 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mul = %Mul
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .Mul = %Mul.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul: <function> = fn_decl @Mul [template] {
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Mul.%a: f64 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Mul.%b: f64 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Mul.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
@@ -84,7 +89,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, file.%Mul [template = file.%Mul]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.mul: init f64 = call %Mul.ref(%a.ref, %b.ref)
@@ -95,34 +100,52 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, file.%Mul [template = file.%Mul]
-// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.2]
-// CHECK:STDOUT:   %float.mul: init f64 = call %Mul.ref(%.loc8_18, %.loc8_23) [template = constants.%.3]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.3]
+// CHECK:STDOUT:   %float.mul: init f64 = call %Mul.ref(%.loc8_18, %.loc8_23) [template = constants.%.4]
 // CHECK:STDOUT:   assign file.%x.var, %float.mul
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
@@ -131,26 +154,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
@@ -159,7 +182,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
@@ -178,7 +201,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init f64 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc21_19.1: f64 = value_of_initializer %TooFew.call
@@ -188,7 +211,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: f64, %b: f64, %c: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: f64 = name_ref c, %c
@@ -200,7 +223,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)

+ 52 - 29
toolchain/check/testdata/builtins/float/negate.carbon

@@ -70,34 +70,39 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: f64 = float_literal 1.5 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal -1.5 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.2: f64 = float_literal 1.5 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal -1.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .Negate = %Negate.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc2_11.1
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc8_21: f64 = float_literal 1.5 [template = constants.%.1]
-// CHECK:STDOUT:   %float.negate: init f64 = call %Negate.ref(%.loc8_21) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_25.1: f64 = value_of_initializer %float.negate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_25.2: f64 = converted %float.negate, %.loc8_25.1 [template = constants.%.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_21: f64 = float_literal 1.5 [template = constants.%.2]
+// CHECK:STDOUT:   %float.negate: init f64 = call %Negate.ref(%.loc8_21) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_25.1: f64 = value_of_initializer %float.negate [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_25.2: f64 = converted %float.negate, %.loc8_25.1 [template = constants.%.3]
 // CHECK:STDOUT:   %a.loc8: f64 = bind_name a, %.loc8_25.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -105,7 +110,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %float.negate: init f64 = call %Negate.ref(%a.ref)
 // CHECK:STDOUT:   %.loc5_19.1: f64 = value_of_initializer %float.negate
@@ -115,44 +120,62 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc18_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc18_18.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc19_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc19_14.1
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc21_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc21_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc32_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc32_23.1
 // CHECK:STDOUT:     %b.loc32_31.1: f64 = param b
@@ -161,7 +184,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc32_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc43_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc43_29.1
 // CHECK:STDOUT:     %b.loc43_37.1: f64 = param b
@@ -180,7 +203,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init f64 = call %TooFew.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc29_19.1: f64 = value_of_initializer %TooFew.call [template = <error>]
@@ -190,7 +213,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: f64, %b: f64, %c: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: f64 = name_ref c, %c
@@ -202,7 +225,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(<invalid>) [template = <error>]

+ 25 - 13
toolchain/check/testdata/builtins/float/neq.carbon

@@ -32,10 +32,14 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT: --- float_neq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Neq: type = fn_type @Neq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Neq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.5: f64 = float_literal 2 [template]
@@ -43,19 +47,21 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:   %.7: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.8: f64 = float_literal 1 [template]
 // CHECK:STDOUT:   %.9: bool = bool_literal false [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Neq = %Neq
+// CHECK:STDOUT:     .Neq = %Neq.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Neq: <function> = fn_decl @Neq [template] {
+// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Neq.%a: f64 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
@@ -64,7 +70,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc7_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc7_6.1
@@ -72,7 +78,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:     %false_.loc7_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc7_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc12_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc12_16.1
 // CHECK:STDOUT:     %b.loc12_24.1: f64 = param b
@@ -96,7 +102,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Neq.ref.loc8: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref.loc8: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc8_20: f64 = float_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc8_25: f64 = float_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %float.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_20, %.loc8_25) [template = constants.%.6]
@@ -115,7 +121,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT: !if.expr.result.loc8:
 // CHECK:STDOUT:   %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Neq.ref.loc9: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref.loc9: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_21: f64 = float_literal 1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc9_26: f64 = float_literal 1 [template = constants.%.8]
 // CHECK:STDOUT:   %float.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.9]
@@ -138,7 +144,7 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Neq.ref: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.neq: init bool = call %Neq.ref(%a.ref, %b.ref)
@@ -149,13 +155,19 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .WrongResult = %WrongResult
+// CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult: <function> = fn_decl @WrongResult [template] {
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc7_16.1: f64 = param a
 // CHECK:STDOUT:     @WrongResult.%a: f64 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: f64 = param b

+ 52 - 29
toolchain/check/testdata/builtins/float/sub.carbon

@@ -49,27 +49,32 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: f64 = float_literal 2 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 0.5 [template]
-// CHECK:STDOUT:   %.3: f64 = float_literal 1.5 [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Sub = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.2: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 0.5 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 1.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Sub = %Sub
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .Sub = %Sub.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Sub.%a: f64 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Sub.%b: f64 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Sub.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
@@ -84,7 +89,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, file.%Sub [template = file.%Sub]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %float.sub: init f64 = call %Sub.ref(%a.ref, %b.ref)
@@ -95,34 +100,52 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, file.%Sub [template = file.%Sub]
-// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.2]
-// CHECK:STDOUT:   %float.sub: init f64 = call %Sub.ref(%.loc8_18, %.loc8_23) [template = constants.%.3]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.3]
+// CHECK:STDOUT:   %float.sub: init f64 = call %Sub.ref(%.loc8_18, %.loc8_23) [template = constants.%.4]
 // CHECK:STDOUT:   assign file.%x.var, %float.sub
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
@@ -131,26 +154,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
@@ -159,7 +182,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
@@ -178,7 +201,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init f64 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc21_19.1: f64 = value_of_initializer %TooFew.call
@@ -188,7 +211,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: f64, %b: f64, %c: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: f64 = name_ref c, %c
@@ -200,7 +223,7 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: f64, %b: f64) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: f64 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: f64 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)

+ 23 - 18
toolchain/check/testdata/builtins/int/and.carbon

@@ -18,42 +18,47 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_and.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 8 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 8] [template]
+// CHECK:STDOUT:   %And: type = fn_type @And [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: And = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 12 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 10 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 8] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .And = %And
+// CHECK:STDOUT:     .And = %And.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %And: <function> = fn_decl @And [template] {
+// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @And.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @And.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @And.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %And.ref: <function> = name_ref And, %And [template = %And]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_24: i32 = int_literal 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc4_20, %.loc4_24) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_27: type = array_type %int.and, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, %And.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 12 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_24: i32 = int_literal 10 [template = constants.%.3]
+// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc4_20, %.loc4_24) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_27: type = array_type %int.and, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 8] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 8] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 8 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 8] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 8] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 8] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 8]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 8]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -66,7 +71,7 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %And.ref: <function> = name_ref And, file.%And [template = file.%And]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, file.%And.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%a.ref, %b.ref)

+ 32 - 25
toolchain/check/testdata/builtins/int/complement.carbon

@@ -19,53 +19,60 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT: --- int_complement.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1193046 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -1193047 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 16777215 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 15584169 [template]
-// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
-// CHECK:STDOUT:   %.6: type = ptr_type [i32; 15584169] [template]
+// CHECK:STDOUT:   %Complement: type = fn_type @Complement [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Complement = struct_value () [template]
+// CHECK:STDOUT:   %And: type = fn_type @And [template]
+// CHECK:STDOUT:   %struct.2: And = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1193046 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -1193047 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 16777215 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 15584169 [template]
+// CHECK:STDOUT:   %.6: type = array_type %.5, i32 [template]
+// CHECK:STDOUT:   %.7: type = ptr_type [i32; 15584169] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Complement = %Complement
-// CHECK:STDOUT:     .And = %And
+// CHECK:STDOUT:     .Complement = %Complement.decl
+// CHECK:STDOUT:     .And = %And.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Complement: <function> = fn_decl @Complement [template] {
+// CHECK:STDOUT:   %Complement.decl: Complement = fn_decl @Complement [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_15.1: i32 = param a
 // CHECK:STDOUT:     @Complement.%a: i32 = bind_name a, %a.loc2_15.1
 // CHECK:STDOUT:     @Complement.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %And: <function> = fn_decl @And [template] {
+// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_8.1: i32 = param a
 // CHECK:STDOUT:     @And.%a: i32 = bind_name a, %a.loc3_8.1
 // CHECK:STDOUT:     %b.loc3_16.1: i32 = param b
 // CHECK:STDOUT:     @And.%b: i32 = bind_name b, %b.loc3_16.1
 // CHECK:STDOUT:     @And.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %And.ref: <function> = name_ref And, %And [template = %And]
-// CHECK:STDOUT:   %Complement.ref: <function> = name_ref Complement, %Complement [template = %Complement]
-// CHECK:STDOUT:   %.loc5_31: i32 = int_literal 1193046 [template = constants.%.1]
-// CHECK:STDOUT:   %int.complement: init i32 = call %Complement.ref(%.loc5_31) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc5_42: i32 = int_literal 16777215 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19.1: i32 = value_of_initializer %int.complement [template = constants.%.2]
-// CHECK:STDOUT:   %.loc5_19.2: i32 = converted %int.complement, %.loc5_19.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc5_19.2, %.loc5_42) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_51: type = array_type %int.and, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, %And.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Complement.ref: Complement = name_ref Complement, %Complement.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc5_31: i32 = int_literal 1193046 [template = constants.%.2]
+// CHECK:STDOUT:   %int.complement: init i32 = call %Complement.ref(%.loc5_31) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_42: i32 = int_literal 16777215 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19.1: i32 = value_of_initializer %int.complement [template = constants.%.3]
+// CHECK:STDOUT:   %.loc5_19.2: i32 = converted %int.complement, %.loc5_19.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.and: init i32 = call %And.ref(%.loc5_19.2, %.loc5_42) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_51: type = array_type %int.and, i32 [template = constants.%.6]
 // CHECK:STDOUT:   %arr.var: ref [i32; 15584169] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 15584169] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 15584169 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc6_26: type = array_type %.loc6_18, i32 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc6_27: type = ptr_type [i32; 15584169] [template = constants.%.6]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 15584169 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc6_26: type = array_type %.loc6_18, i32 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc6_27: type = ptr_type [i32; 15584169] [template = constants.%.7]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 15584169] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc6_31: [i32; 15584169]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 15584169]* = bind_name arr_p, %.loc6_31
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc8_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc8_16.1
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
@@ -78,7 +85,7 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Complement.ref: <function> = name_ref Complement, file.%Complement [template = file.%Complement]
+// CHECK:STDOUT:   %Complement.ref: Complement = name_ref Complement, file.%Complement.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %int.complement: init i32 = call %Complement.ref(%a.ref)
 // CHECK:STDOUT:   %.loc9_23.1: i32 = value_of_initializer %int.complement

+ 25 - 13
toolchain/check/testdata/builtins/int/eq.carbon

@@ -32,28 +32,34 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT: --- int_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Eq: type = fn_type @Eq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Eq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: bool = bool_literal true [template]
 // CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Eq = %Eq
+// CHECK:STDOUT:     .Eq = %Eq.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Eq: <function> = fn_decl @Eq [template] {
+// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_7.1: i32 = param a
 // CHECK:STDOUT:     @Eq.%a: i32 = bind_name a, %a.loc2_7.1
 // CHECK:STDOUT:     %b.loc2_15.1: i32 = param b
@@ -62,7 +68,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc7_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc7_6.1
@@ -70,7 +76,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:     %false_.loc7_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc7_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc12_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc12_16.1
 // CHECK:STDOUT:     %b.loc12_24.1: i32 = param b
@@ -94,7 +100,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Eq.ref.loc8: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref.loc8: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc8_19: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc8_22: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_22) [template = constants.%.5]
@@ -113,7 +119,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT: !if.expr.result.loc8:
 // CHECK:STDOUT:   %.loc8_13.3: type = block_arg !if.expr.result.loc8 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Eq.ref.loc9: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref.loc9: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_20: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_23: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %int.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
@@ -136,7 +142,7 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Eq.ref: <function> = name_ref Eq, file.%Eq [template = file.%Eq]
+// CHECK:STDOUT:   %Eq.ref: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.eq: init bool = call %Eq.ref(%a.ref, %b.ref)
@@ -147,13 +153,19 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .WrongResult = %WrongResult
+// CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult: <function> = fn_decl @WrongResult [template] {
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @WrongResult.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b

+ 26 - 18
toolchain/check/testdata/builtins/int/greater.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: --- int_greater.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Greater: type = fn_type @Greater [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Greater = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
@@ -38,34 +44,36 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
 // CHECK:STDOUT:   %.8: bool = bool_literal true [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Greater = %Greater
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Greater = %Greater.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Greater: <function> = fn_decl @Greater [template] {
+// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_12.1: i32 = param a
 // CHECK:STDOUT:     @Greater.%a: i32 = bind_name a, %a.loc2_12.1
 // CHECK:STDOUT:     %b.loc2_20.1: i32 = param b
 // CHECK:STDOUT:     @Greater.%b: i32 = bind_name b, %b.loc2_20.1
 // CHECK:STDOUT:     @Greater.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -73,7 +81,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
@@ -99,7 +107,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc9: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc9: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_25: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_28: i32 = int_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %int.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_28) [template = constants.%.6]
@@ -118,7 +126,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc10: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc10: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc10: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_25: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_28: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_28) [template = constants.%.6]
@@ -137,7 +145,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc11: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Greater.ref.loc11: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc11: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_24: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc11_27: i32 = int_literal 0 [template = constants.%.7]
 // CHECK:STDOUT:   %int.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
@@ -156,8 +164,8 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_13.3: type = block_arg !if.expr.result.loc11 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc12: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Greater.ref.loc12: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Greater.ref.loc12: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_32: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc12_36: i32 = int_literal 0 [template = constants.%.7]
@@ -179,9 +187,9 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Greater.ref.loc13: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref.loc13: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_34: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
@@ -206,7 +214,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Greater.ref: <function> = name_ref Greater, file.%Greater [template = file.%Greater]
+// CHECK:STDOUT:   %Greater.ref: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.greater: init bool = call %Greater.ref(%a.ref, %b.ref)

+ 26 - 18
toolchain/check/testdata/builtins/int/greater_eq.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: --- int_greater_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %GreaterEq: type = fn_type @GreaterEq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: GreaterEq = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
@@ -38,34 +44,36 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.7: bool = bool_literal true [template]
 // CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .GreaterEq = %GreaterEq
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .GreaterEq = %GreaterEq.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %GreaterEq: <function> = fn_decl @GreaterEq [template] {
+// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_14.1: i32 = param a
 // CHECK:STDOUT:     @GreaterEq.%a: i32 = bind_name a, %a.loc2_14.1
 // CHECK:STDOUT:     %b.loc2_22.1: i32 = param b
 // CHECK:STDOUT:     @GreaterEq.%b: i32 = bind_name b, %b.loc2_22.1
 // CHECK:STDOUT:     @GreaterEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -73,7 +81,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
@@ -99,7 +107,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref.loc9: False = name_ref false_, %false_
-// CHECK:STDOUT:   %GreaterEq.ref.loc9: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc9: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_27: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_30: i32 = int_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %int.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_30) [template = constants.%.6]
@@ -118,7 +126,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_14.3: type = block_arg !if.expr.result.loc9 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc10: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc10: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc10: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_26: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_29: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_29) [template = constants.%.7]
@@ -137,7 +145,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc11: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc11: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc11: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_26: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc11_29: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %int.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_29) [template = constants.%.7]
@@ -156,8 +164,8 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_13.3: type = block_arg !if.expr.result.loc11 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc12: False = name_ref false_, %false_
-// CHECK:STDOUT:   %GreaterEq.ref.loc12: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %GreaterEq.ref.loc12: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_34: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc12_38: i32 = int_literal 0 [template = constants.%.8]
@@ -179,9 +187,9 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_14.3: type = block_arg !if.expr.result.loc12 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc13: True = name_ref true_, %true_
-// CHECK:STDOUT:   %GreaterEq.ref.loc13: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref.loc13: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_26: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_36: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc13_25.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
@@ -206,7 +214,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %GreaterEq.ref: <function> = name_ref GreaterEq, file.%GreaterEq [template = file.%GreaterEq]
+// CHECK:STDOUT:   %GreaterEq.ref: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.greater_eq: init bool = call %GreaterEq.ref(%a.ref, %b.ref)

+ 77 - 67
toolchain/check/testdata/builtins/int/left_shift.carbon

@@ -62,42 +62,47 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT: --- int_left_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 20 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 20] [template]
+// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: LeftShift = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 20 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 20] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .LeftShift = %LeftShift
+// CHECK:STDOUT:     .LeftShift = %LeftShift.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LeftShift: <function> = fn_decl @LeftShift [template] {
+// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_14.1: i32 = param a
 // CHECK:STDOUT:     @LeftShift.%a: i32 = bind_name a, %a.loc2_14.1
 // CHECK:STDOUT:     %b.loc2_22.1: i32 = param b
 // CHECK:STDOUT:     @LeftShift.%b: i32 = bind_name b, %b.loc2_22.1
 // CHECK:STDOUT:     @LeftShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %LeftShift.ref: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc4_26: i32 = int_literal 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_29: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift: init i32 = call %LeftShift.ref(%.loc4_26, %.loc4_29) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_31: type = array_type %int.left_shift, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_26: i32 = int_literal 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_29: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.left_shift: init i32 = call %LeftShift.ref(%.loc4_26, %.loc4_29) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_31: type = array_type %int.left_shift, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 20] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 20] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 20 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_21: type = ptr_type [i32; 20] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 20 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_21: type = ptr_type [i32; 20] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 20] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_25: [i32; 20]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 20]* = bind_name arr_p, %.loc5_25
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -110,7 +115,7 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %LeftShift.ref: <function> = name_ref LeftShift, file.%LeftShift [template = file.%LeftShift]
+// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, file.%LeftShift.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.left_shift: init i32 = call %LeftShift.ref(%a.ref, %b.ref)
@@ -122,91 +127,96 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT: --- fail_bad_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 31 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal -2147483648 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 32 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 33 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 1000 [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.8: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: LeftShift = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 31 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 33 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 1000 [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.9: i32 = int_literal -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .LeftShift = %LeftShift
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .LeftShift = %LeftShift.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LeftShift: <function> = fn_decl @LeftShift [template] {
+// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_14.1: i32 = param a
 // CHECK:STDOUT:     @LeftShift.%a: i32 = bind_name a, %a.loc4_14.1
 // CHECK:STDOUT:     %b.loc4_22.1: i32 = param b
 // CHECK:STDOUT:     @LeftShift.%b: i32 = bind_name b, %b.loc4_22.1
 // CHECK:STDOUT:     @LeftShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc5_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %LeftShift.ref.loc8: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc8_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_32: i32 = int_literal 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc8: init i32 = call %LeftShift.ref.loc8(%.loc8_29, %.loc8_32) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_35.1: i32 = value_of_initializer %int.left_shift.loc8 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_35.2: i32 = converted %int.left_shift.loc8, %.loc8_35.1 [template = constants.%.3]
+// CHECK:STDOUT:   %LeftShift.ref.loc8: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_32: i32 = int_literal 31 [template = constants.%.3]
+// CHECK:STDOUT:   %int.left_shift.loc8: init i32 = call %LeftShift.ref.loc8(%.loc8_29, %.loc8_32) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_35.1: i32 = value_of_initializer %int.left_shift.loc8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_35.2: i32 = converted %int.left_shift.loc8, %.loc8_35.1 [template = constants.%.4]
 // CHECK:STDOUT:   %size_1: i32 = bind_name size_1, %.loc8_35.2
-// CHECK:STDOUT:   %LeftShift.ref.loc13: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc13_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_32: i32 = int_literal 32 [template = constants.%.4]
+// CHECK:STDOUT:   %LeftShift.ref.loc13: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc13_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_32: i32 = int_literal 32 [template = constants.%.5]
 // CHECK:STDOUT:   %int.left_shift.loc13: init i32 = call %LeftShift.ref.loc13(%.loc13_29, %.loc13_32) [template = <error>]
 // CHECK:STDOUT:   %.loc13_35.1: i32 = value_of_initializer %int.left_shift.loc13 [template = <error>]
 // CHECK:STDOUT:   %.loc13_35.2: i32 = converted %int.left_shift.loc13, %.loc13_35.1 [template = <error>]
 // CHECK:STDOUT:   %size_2: i32 = bind_name size_2, %.loc13_35.2
-// CHECK:STDOUT:   %LeftShift.ref.loc18: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc18_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_32: i32 = int_literal 33 [template = constants.%.5]
+// CHECK:STDOUT:   %LeftShift.ref.loc18: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc18_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc18_32: i32 = int_literal 33 [template = constants.%.6]
 // CHECK:STDOUT:   %int.left_shift.loc18: init i32 = call %LeftShift.ref.loc18(%.loc18_29, %.loc18_32) [template = <error>]
 // CHECK:STDOUT:   %.loc18_35.1: i32 = value_of_initializer %int.left_shift.loc18 [template = <error>]
 // CHECK:STDOUT:   %.loc18_35.2: i32 = converted %int.left_shift.loc18, %.loc18_35.1 [template = <error>]
 // CHECK:STDOUT:   %size_3: i32 = bind_name size_3, %.loc18_35.2
-// CHECK:STDOUT:   %LeftShift.ref.loc21: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc21_33: i32 = int_literal 1000 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc21_39: i32 = int_literal 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc21: init i32 = call %LeftShift.ref.loc21(%.loc21_33, %.loc21_39) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc21_42.1: i32 = value_of_initializer %int.left_shift.loc21 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc21_42.2: i32 = converted %int.left_shift.loc21, %.loc21_42.1 [template = constants.%.7]
+// CHECK:STDOUT:   %LeftShift.ref.loc21: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc21_33: i32 = int_literal 1000 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc21_39: i32 = int_literal 31 [template = constants.%.3]
+// CHECK:STDOUT:   %int.left_shift.loc21: init i32 = call %LeftShift.ref.loc21(%.loc21_33, %.loc21_39) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc21_42.1: i32 = value_of_initializer %int.left_shift.loc21 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc21_42.2: i32 = converted %int.left_shift.loc21, %.loc21_42.1 [template = constants.%.8]
 // CHECK:STDOUT:   %overflow_1: i32 = bind_name overflow_1, %.loc21_42.2
-// CHECK:STDOUT:   %LeftShift.ref.loc26: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc26_33: i32 = int_literal 1000 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc26_39: i32 = int_literal 32 [template = constants.%.4]
+// CHECK:STDOUT:   %LeftShift.ref.loc26: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc26_33: i32 = int_literal 1000 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc26_39: i32 = int_literal 32 [template = constants.%.5]
 // CHECK:STDOUT:   %int.left_shift.loc26: init i32 = call %LeftShift.ref.loc26(%.loc26_33, %.loc26_39) [template = <error>]
 // CHECK:STDOUT:   %.loc26_42.1: i32 = value_of_initializer %int.left_shift.loc26 [template = <error>]
 // CHECK:STDOUT:   %.loc26_42.2: i32 = converted %int.left_shift.loc26, %.loc26_42.1 [template = <error>]
 // CHECK:STDOUT:   %overflow_2: i32 = bind_name overflow_2, %.loc26_42.2
-// CHECK:STDOUT:   %LeftShift.ref.loc29: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc29_36: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_39: i32 = int_literal 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.left_shift.loc29: init i32 = call %LeftShift.ref.loc29(%.loc29_36, %.loc29_39) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_42.1: i32 = value_of_initializer %int.left_shift.loc29 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc29_42.2: i32 = converted %int.left_shift.loc29, %.loc29_42.1 [template = constants.%.7]
+// CHECK:STDOUT:   %LeftShift.ref.loc29: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc29_36: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc29_39: i32 = int_literal 31 [template = constants.%.3]
+// CHECK:STDOUT:   %int.left_shift.loc29: init i32 = call %LeftShift.ref.loc29(%.loc29_36, %.loc29_39) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc29_42.1: i32 = value_of_initializer %int.left_shift.loc29 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc29_42.2: i32 = converted %int.left_shift.loc29, %.loc29_42.1 [template = constants.%.8]
 // CHECK:STDOUT:   %no_overflow_1: i32 = bind_name no_overflow_1, %.loc29_42.2
-// CHECK:STDOUT:   %LeftShift.ref.loc34: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc34_36: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc34_39: i32 = int_literal 32 [template = constants.%.4]
+// CHECK:STDOUT:   %LeftShift.ref.loc34: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc34_36: i32 = int_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc34_39: i32 = int_literal 32 [template = constants.%.5]
 // CHECK:STDOUT:   %int.left_shift.loc34: init i32 = call %LeftShift.ref.loc34(%.loc34_36, %.loc34_39) [template = <error>]
 // CHECK:STDOUT:   %.loc34_42.1: i32 = value_of_initializer %int.left_shift.loc34 [template = <error>]
 // CHECK:STDOUT:   %.loc34_42.2: i32 = converted %int.left_shift.loc34, %.loc34_42.1 [template = <error>]
 // CHECK:STDOUT:   %no_overflow_2: i32 = bind_name no_overflow_2, %.loc34_42.2
-// CHECK:STDOUT:   %LeftShift.ref.loc40: <function> = name_ref LeftShift, %LeftShift [template = %LeftShift]
-// CHECK:STDOUT:   %.loc40_31: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc40_41: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc40_41) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc40_30.1: i32 = value_of_initializer %int.snegate [template = constants.%.8]
-// CHECK:STDOUT:   %.loc40_30.2: i32 = converted %int.snegate, %.loc40_30.1 [template = constants.%.8]
+// CHECK:STDOUT:   %LeftShift.ref.loc40: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc40_31: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc40_41: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc40_41) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc40_30.1: i32 = value_of_initializer %int.snegate [template = constants.%.9]
+// CHECK:STDOUT:   %.loc40_30.2: i32 = converted %int.snegate, %.loc40_30.1 [template = constants.%.9]
 // CHECK:STDOUT:   %int.left_shift.loc40: init i32 = call %LeftShift.ref.loc40(%.loc40_31, %.loc40_30.2) [template = <error>]
 // CHECK:STDOUT:   %.loc40_44.1: i32 = value_of_initializer %int.left_shift.loc40 [template = <error>]
 // CHECK:STDOUT:   %.loc40_44.2: i32 = converted %int.left_shift.loc40, %.loc40_44.1 [template = <error>]

+ 26 - 18
toolchain/check/testdata/builtins/int/less.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: --- int_less.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Less: type = fn_type @Less [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Less = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
@@ -38,34 +44,36 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.7: bool = bool_literal false [template]
 // CHECK:STDOUT:   %.8: i32 = int_literal 0 [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Less = %Less
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Less = %Less.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Less: <function> = fn_decl @Less [template] {
+// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_9.1: i32 = param a
 // CHECK:STDOUT:     @Less.%a: i32 = bind_name a, %a.loc2_9.1
 // CHECK:STDOUT:     %b.loc2_17.1: i32 = param b
 // CHECK:STDOUT:     @Less.%b: i32 = bind_name b, %b.loc2_17.1
 // CHECK:STDOUT:     @Less.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -73,7 +81,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
@@ -99,7 +107,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Less.ref.loc9: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc9: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_21: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_24: i32 = int_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %int.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_24) [template = constants.%.6]
@@ -118,7 +126,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc10: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc10: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc10: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_22: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_25: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_25) [template = constants.%.7]
@@ -137,7 +145,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_14.3: type = block_arg !if.expr.result.loc10 [template = constants.%False]
 // CHECK:STDOUT:   %false_.ref.loc11: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc11: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc11: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_22: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc11_25: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %int.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_25) [template = constants.%.7]
@@ -156,8 +164,8 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_14.3: type = block_arg !if.expr.result.loc11 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc12: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Less.ref.loc12: <function> = name_ref Less, file.%Less [template = file.%Less]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Less.ref.loc12: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_28: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc12_32: i32 = int_literal 0 [template = constants.%.8]
@@ -179,9 +187,9 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Less.ref.loc13: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref.loc13: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_22: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_32: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_32) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc13_21.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
@@ -206,7 +214,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Less.ref: <function> = name_ref Less, file.%Less [template = file.%Less]
+// CHECK:STDOUT:   %Less.ref: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.less: init bool = call %Less.ref(%a.ref, %b.ref)

+ 26 - 18
toolchain/check/testdata/builtins/int/less_eq.carbon

@@ -27,10 +27,16 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: --- int_less_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %LessEq: type = fn_type @LessEq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: LessEq = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
@@ -38,34 +44,36 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
 // CHECK:STDOUT:   %.8: bool = bool_literal false [template]
 // CHECK:STDOUT:   %.9: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .LessEq = %LessEq
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .LessEq = %LessEq.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LessEq: <function> = fn_decl @LessEq [template] {
+// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @LessEq.%a: i32 = bind_name a, %a.loc2_11.1
 // CHECK:STDOUT:     %b.loc2_19.1: i32 = param b
 // CHECK:STDOUT:     @LessEq.%b: i32 = bind_name b, %b.loc2_19.1
 // CHECK:STDOUT:     @LessEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc8_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc8_6.1
@@ -73,7 +81,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     %false_.loc8_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc8_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
@@ -99,7 +107,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %true_.ref.loc9: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc9: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc9: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_23: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_26: i32 = int_literal 2 [template = constants.%.5]
 // CHECK:STDOUT:   %int.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_26) [template = constants.%.6]
@@ -118,7 +126,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc9:
 // CHECK:STDOUT:   %.loc9_13.3: type = block_arg !if.expr.result.loc9 [template = constants.%True]
 // CHECK:STDOUT:   %true_.ref.loc10: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc10: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc10: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc10_23: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc10_26: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_26) [template = constants.%.6]
@@ -137,7 +145,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc10:
 // CHECK:STDOUT:   %.loc10_13.3: type = block_arg !if.expr.result.loc10 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc11: False = name_ref false_, %false_
-// CHECK:STDOUT:   %LessEq.ref.loc11: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc11: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc11_24: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc11_27: i32 = int_literal 0 [template = constants.%.7]
 // CHECK:STDOUT:   %int.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_27) [template = constants.%.8]
@@ -156,8 +164,8 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc11:
 // CHECK:STDOUT:   %.loc11_14.3: type = block_arg !if.expr.result.loc11 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref.loc12: True = name_ref true_, %true_
-// CHECK:STDOUT:   %LessEq.ref.loc12: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %LessEq.ref.loc12: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc12_30: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc12_34: i32 = int_literal 0 [template = constants.%.7]
@@ -179,9 +187,9 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc12:
 // CHECK:STDOUT:   %.loc12_13.3: type = block_arg !if.expr.result.loc12 [template = constants.%True]
 // CHECK:STDOUT:   %false_.ref.loc13: False = name_ref false_, %false_
-// CHECK:STDOUT:   %LessEq.ref.loc13: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref.loc13: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %Negate.ref.loc13: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_34: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.snegate.loc13: init i32 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
 // CHECK:STDOUT:   %.loc13_23.1: i32 = value_of_initializer %int.snegate.loc13 [template = constants.%.9]
@@ -206,7 +214,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %LessEq.ref: <function> = name_ref LessEq, file.%LessEq [template = file.%LessEq]
+// CHECK:STDOUT:   %LessEq.ref: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.less_eq: init bool = call %LessEq.ref(%a.ref, %b.ref)

+ 15 - 6
toolchain/check/testdata/builtins/int/make_type_32.carbon

@@ -20,13 +20,19 @@ var i: Int() = 0;
 
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Int = %Int
+// CHECK:STDOUT:     .Int = %Int.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int: <function> = fn_decl @Int [template] {
+// CHECK:STDOUT:   %Int.decl: Int = fn_decl @Int [template = constants.%struct] {
 // CHECK:STDOUT:     @Int.%return: ref type = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -36,7 +42,10 @@ var i: Int() = 0;
 // CHECK:STDOUT: --- use_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -45,9 +54,9 @@ var i: Int() = 0;
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .i = %i
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+3, loc_11 [template = imports.%Int]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+3, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int.ref: <function> = name_ref Int, %import_ref [template = imports.%Int]
+// CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %int.make_type_32: init type = call %Int.ref() [template = i32]
 // CHECK:STDOUT:   %.loc6_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
 // CHECK:STDOUT:   %.loc6_12.2: type = converted %int.make_type_32, %.loc6_12.1 [template = i32]
@@ -59,7 +68,7 @@ var i: Int() = 0;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc6: i32 = int_literal 0 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc6: i32 = int_literal 0 [template = constants.%.2]
 // CHECK:STDOUT:   assign file.%i.var, %.loc6
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 87 - 61
toolchain/check/testdata/builtins/int/make_type_signed.carbon

@@ -67,13 +67,19 @@ var m: Int(1000000000);
 
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Int = %Int
+// CHECK:STDOUT:     .Int = %Int.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int: <function> = fn_decl @Int [template] {
+// CHECK:STDOUT:   %Int.decl: Int = fn_decl @Int [template = constants.%struct] {
 // CHECK:STDOUT:     %n.loc4_8.1: i32 = param n
 // CHECK:STDOUT:     @Int.%n: i32 = bind_name n, %n.loc4_8.1
 // CHECK:STDOUT:     @Int.%return: ref type = var <return slot>
@@ -85,69 +91,78 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- use_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
-// CHECK:STDOUT:   %.2: type = int_type signed, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 13 [template]
-// CHECK:STDOUT:   %.4: type = int_type signed, %.3 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %.3: type = int_type signed, %.2 [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 13 [template]
+// CHECK:STDOUT:   %.5: type = int_type signed, %.4 [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.3: G = struct_value () [template]
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [symbolic]
-// CHECK:STDOUT:   %.5: type = int_type signed, %N [symbolic]
+// CHECK:STDOUT:   %.6: type = int_type signed, %N [symbolic]
+// CHECK:STDOUT:   %Symbolic: type = fn_type @Symbolic [template]
+// CHECK:STDOUT:   %struct.4: Symbolic = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Int = %import_ref
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .G = %G
-// CHECK:STDOUT:     .Symbolic = %Symbolic
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
+// CHECK:STDOUT:     .Symbolic = %Symbolic.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_13 [template = imports.%Int]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loc_13 [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
-// CHECK:STDOUT:     %Int.ref.loc6_9: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:     %.loc6_13: i32 = int_literal 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc6_12: init type = call %Int.ref.loc6_9(%.loc6_13) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_15.1: type = value_of_initializer %int.make_type_signed.loc6_12 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_15.2: type = converted %int.make_type_signed.loc6_12, %.loc6_15.1 [template = constants.%.2]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %Int.ref.loc6_9: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc6_13: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:     %int.make_type_signed.loc6_12: init type = call %Int.ref.loc6_9(%.loc6_13) [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_15.1: type = value_of_initializer %int.make_type_signed.loc6_12 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_15.2: type = converted %int.make_type_signed.loc6_12, %.loc6_15.1 [template = constants.%.3]
 // CHECK:STDOUT:     %n.loc6_6.1: i64 = param n
 // CHECK:STDOUT:     @F.%n: i64 = bind_name n, %n.loc6_6.1
-// CHECK:STDOUT:     %Int.ref.loc6_21: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:     %.loc6_25: i32 = int_literal 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_signed.loc6_24: init type = call %Int.ref.loc6_21(%.loc6_25) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_27.1: type = value_of_initializer %int.make_type_signed.loc6_24 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_27.2: type = converted %int.make_type_signed.loc6_24, %.loc6_27.1 [template = constants.%.2]
+// CHECK:STDOUT:     %Int.ref.loc6_21: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc6_25: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:     %int.make_type_signed.loc6_24: init type = call %Int.ref.loc6_21(%.loc6_25) [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_27.1: type = value_of_initializer %int.make_type_signed.loc6_24 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_27.2: type = converted %int.make_type_signed.loc6_24, %.loc6_27.1 [template = constants.%.3]
 // CHECK:STDOUT:     @F.%return: ref i64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
-// CHECK:STDOUT:     %Int.ref.loc10_9: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:     %.loc10_13: i32 = int_literal 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc10_12: init type = call %Int.ref.loc10_9(%.loc10_13) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_15.1: type = value_of_initializer %int.make_type_signed.loc10_12 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_15.2: type = converted %int.make_type_signed.loc10_12, %.loc10_15.1 [template = constants.%.4]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %Int.ref.loc10_9: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc10_13: i32 = int_literal 13 [template = constants.%.4]
+// CHECK:STDOUT:     %int.make_type_signed.loc10_12: init type = call %Int.ref.loc10_9(%.loc10_13) [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_15.1: type = value_of_initializer %int.make_type_signed.loc10_12 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_15.2: type = converted %int.make_type_signed.loc10_12, %.loc10_15.1 [template = constants.%.5]
 // CHECK:STDOUT:     %n.loc10_6.1: i13 = param n
 // CHECK:STDOUT:     @G.%n: i13 = bind_name n, %n.loc10_6.1
-// CHECK:STDOUT:     %Int.ref.loc10_21: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:     %.loc10_25: i32 = int_literal 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_signed.loc10_24: init type = call %Int.ref.loc10_21(%.loc10_25) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_27.1: type = value_of_initializer %int.make_type_signed.loc10_24 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_27.2: type = converted %int.make_type_signed.loc10_24, %.loc10_27.1 [template = constants.%.4]
+// CHECK:STDOUT:     %Int.ref.loc10_21: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc10_25: i32 = int_literal 13 [template = constants.%.4]
+// CHECK:STDOUT:     %int.make_type_signed.loc10_24: init type = call %Int.ref.loc10_21(%.loc10_25) [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_27.1: type = value_of_initializer %int.make_type_signed.loc10_24 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_27.2: type = converted %int.make_type_signed.loc10_24, %.loc10_27.1 [template = constants.%.5]
 // CHECK:STDOUT:     @G.%return: ref i13 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Symbolic: <function> = fn_decl @Symbolic [template] {
+// CHECK:STDOUT:   %Symbolic.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.4] {
 // CHECK:STDOUT:     %N.loc14_13.1: i32 = param N
 // CHECK:STDOUT:     @Symbolic.%N: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = constants.%N]
-// CHECK:STDOUT:     %Int.ref.loc14_25: <function> = name_ref Int, %import_ref [template = imports.%Int]
+// CHECK:STDOUT:     %Int.ref.loc14_25: Int = name_ref Int, %import_ref [template = constants.%struct.1]
 // CHECK:STDOUT:     %N.ref.loc14_29: i32 = name_ref N, @Symbolic.%N [symbolic = constants.%N]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = constants.%.5]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_28: init type = call %Int.ref.loc14_25(%N.ref.loc14_29) [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_30.1: type = value_of_initializer %int.make_type_signed.loc14_28 [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_30.2: type = converted %int.make_type_signed.loc14_28, %.loc14_30.1 [symbolic = constants.%.6]
 // CHECK:STDOUT:     %x.loc14_22.1: Core.Int(N) = param x
 // CHECK:STDOUT:     @Symbolic.%x: Core.Int(N) = bind_name x, %x.loc14_22.1
-// CHECK:STDOUT:     %Int.ref.loc14_36: <function> = name_ref Int, %import_ref [template = imports.%Int]
+// CHECK:STDOUT:     %Int.ref.loc14_36: Int = name_ref Int, %import_ref [template = constants.%struct.1]
 // CHECK:STDOUT:     %N.ref.loc14_40: i32 = name_ref N, @Symbolic.%N [symbolic = constants.%N]
-// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = constants.%.5]
+// CHECK:STDOUT:     %int.make_type_signed.loc14_39: init type = call %Int.ref.loc14_36(%N.ref.loc14_40) [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_41.2: type = converted %int.make_type_signed.loc14_39, %.loc14_41.1 [symbolic = constants.%.6]
 // CHECK:STDOUT:     @Symbolic.%return: ref Core.Int(N) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -175,7 +190,10 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- fail_zero_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -184,10 +202,10 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%Int]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int.ref: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 0 [template = constants.%.1]
+// CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 0 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc10_12) [template = <error>]
 // CHECK:STDOUT:   %.loc10_13.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc10_13.2: type = converted %int.make_type_signed, %.loc10_13.1 [template = <error>]
@@ -200,30 +218,35 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- fail_negative_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %struct.2: Int = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Int = %import_ref
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .n = %n.loc12
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_23 [template = imports.%Int]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loc_23 [template = constants.%struct.2]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %n.loc6_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Int.ref: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_19) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_11.1: i32 = value_of_initializer %int.snegate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_11.2: i32 = converted %int.snegate, %.loc12_11.1 [template = constants.%.2]
+// CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_19) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_11.1: i32 = value_of_initializer %int.snegate [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_11.2: i32 = converted %int.snegate, %.loc12_11.1 [template = constants.%.3]
 // CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc12_11.2) [template = <error>]
 // CHECK:STDOUT:   %.loc12_21.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc12_21.2: type = converted %int.make_type_signed, %.loc12_21.1 [template = <error>]
@@ -238,7 +261,10 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- fail_oversized.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1000000000 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -247,10 +273,10 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%Int]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int.ref: <function> = name_ref Int, %import_ref [template = imports.%Int]
-// CHECK:STDOUT:   %.loc9_12: i32 = int_literal 1000000000 [template = constants.%.1]
+// CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_12: i32 = int_literal 1000000000 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_signed: init type = call %Int.ref(%.loc9_12) [template = <error>]
 // CHECK:STDOUT:   %.loc9_22.1: type = value_of_initializer %int.make_type_signed [template = <error>]
 // CHECK:STDOUT:   %.loc9_22.2: type = converted %int.make_type_signed, %.loc9_22.1 [template = <error>]

+ 87 - 61
toolchain/check/testdata/builtins/int/make_type_unsigned.carbon

@@ -67,13 +67,19 @@ var m: UInt(1000000000);
 
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .UInt = %UInt
+// CHECK:STDOUT:     .UInt = %UInt.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %UInt: <function> = fn_decl @UInt [template] {
+// CHECK:STDOUT:   %UInt.decl: UInt = fn_decl @UInt [template = constants.%struct] {
 // CHECK:STDOUT:     %n.loc4_9.1: i32 = param n
 // CHECK:STDOUT:     @UInt.%n: i32 = bind_name n, %n.loc4_9.1
 // CHECK:STDOUT:     @UInt.%return: ref type = var <return slot>
@@ -85,69 +91,78 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- use_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
-// CHECK:STDOUT:   %.2: type = int_type unsigned, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 13 [template]
-// CHECK:STDOUT:   %.4: type = int_type unsigned, %.3 [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %.3: type = int_type unsigned, %.2 [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 13 [template]
+// CHECK:STDOUT:   %.5: type = int_type unsigned, %.4 [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.3: G = struct_value () [template]
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [symbolic]
-// CHECK:STDOUT:   %.5: type = int_type unsigned, %N [symbolic]
+// CHECK:STDOUT:   %.6: type = int_type unsigned, %N [symbolic]
+// CHECK:STDOUT:   %Symbolic: type = fn_type @Symbolic [template]
+// CHECK:STDOUT:   %struct.4: Symbolic = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .UInt = %import_ref
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .G = %G
-// CHECK:STDOUT:     .Symbolic = %Symbolic
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .G = %G.decl
+// CHECK:STDOUT:     .Symbolic = %Symbolic.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_13 [template = imports.%UInt]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loc_13 [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
-// CHECK:STDOUT:     %UInt.ref.loc6_9: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:     %.loc6_14: i32 = int_literal 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc6_13: init type = call %UInt.ref.loc6_9(%.loc6_14) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_16.1: type = value_of_initializer %int.make_type_unsigned.loc6_13 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_16.2: type = converted %int.make_type_unsigned.loc6_13, %.loc6_16.1 [template = constants.%.2]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %UInt.ref.loc6_9: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc6_14: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc6_13: init type = call %UInt.ref.loc6_9(%.loc6_14) [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_16.1: type = value_of_initializer %int.make_type_unsigned.loc6_13 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_16.2: type = converted %int.make_type_unsigned.loc6_13, %.loc6_16.1 [template = constants.%.3]
 // CHECK:STDOUT:     %n.loc6_6.1: u64 = param n
 // CHECK:STDOUT:     @F.%n: u64 = bind_name n, %n.loc6_6.1
-// CHECK:STDOUT:     %UInt.ref.loc6_22: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:     %.loc6_27: i32 = int_literal 64 [template = constants.%.1]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc6_26: init type = call %UInt.ref.loc6_22(%.loc6_27) [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_29.1: type = value_of_initializer %int.make_type_unsigned.loc6_26 [template = constants.%.2]
-// CHECK:STDOUT:     %.loc6_29.2: type = converted %int.make_type_unsigned.loc6_26, %.loc6_29.1 [template = constants.%.2]
+// CHECK:STDOUT:     %UInt.ref.loc6_22: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc6_27: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc6_26: init type = call %UInt.ref.loc6_22(%.loc6_27) [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_29.1: type = value_of_initializer %int.make_type_unsigned.loc6_26 [template = constants.%.3]
+// CHECK:STDOUT:     %.loc6_29.2: type = converted %int.make_type_unsigned.loc6_26, %.loc6_29.1 [template = constants.%.3]
 // CHECK:STDOUT:     @F.%return: ref u64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
-// CHECK:STDOUT:     %UInt.ref.loc10_9: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:     %.loc10_14: i32 = int_literal 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc10_13: init type = call %UInt.ref.loc10_9(%.loc10_14) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_16.1: type = value_of_initializer %int.make_type_unsigned.loc10_13 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_16.2: type = converted %int.make_type_unsigned.loc10_13, %.loc10_16.1 [template = constants.%.4]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %UInt.ref.loc10_9: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc10_14: i32 = int_literal 13 [template = constants.%.4]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc10_13: init type = call %UInt.ref.loc10_9(%.loc10_14) [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_16.1: type = value_of_initializer %int.make_type_unsigned.loc10_13 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_16.2: type = converted %int.make_type_unsigned.loc10_13, %.loc10_16.1 [template = constants.%.5]
 // CHECK:STDOUT:     %n.loc10_6.1: u13 = param n
 // CHECK:STDOUT:     @G.%n: u13 = bind_name n, %n.loc10_6.1
-// CHECK:STDOUT:     %UInt.ref.loc10_22: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:     %.loc10_27: i32 = int_literal 13 [template = constants.%.3]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc10_26: init type = call %UInt.ref.loc10_22(%.loc10_27) [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_29.1: type = value_of_initializer %int.make_type_unsigned.loc10_26 [template = constants.%.4]
-// CHECK:STDOUT:     %.loc10_29.2: type = converted %int.make_type_unsigned.loc10_26, %.loc10_29.1 [template = constants.%.4]
+// CHECK:STDOUT:     %UInt.ref.loc10_22: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %.loc10_27: i32 = int_literal 13 [template = constants.%.4]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc10_26: init type = call %UInt.ref.loc10_22(%.loc10_27) [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_29.1: type = value_of_initializer %int.make_type_unsigned.loc10_26 [template = constants.%.5]
+// CHECK:STDOUT:     %.loc10_29.2: type = converted %int.make_type_unsigned.loc10_26, %.loc10_29.1 [template = constants.%.5]
 // CHECK:STDOUT:     @G.%return: ref u13 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Symbolic: <function> = fn_decl @Symbolic [template] {
+// CHECK:STDOUT:   %Symbolic.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.4] {
 // CHECK:STDOUT:     %N.loc14_13.1: i32 = param N
 // CHECK:STDOUT:     @Symbolic.%N: i32 = bind_symbolic_name N 0, %N.loc14_13.1 [symbolic = constants.%N]
-// CHECK:STDOUT:     %UInt.ref.loc14_25: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
+// CHECK:STDOUT:     %UInt.ref.loc14_25: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
 // CHECK:STDOUT:     %N.ref.loc14_30: i32 = name_ref N, @Symbolic.%N [symbolic = constants.%N]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = constants.%.5]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_29: init type = call %UInt.ref.loc14_25(%N.ref.loc14_30) [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_31.1: type = value_of_initializer %int.make_type_unsigned.loc14_29 [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_31.2: type = converted %int.make_type_unsigned.loc14_29, %.loc14_31.1 [symbolic = constants.%.6]
 // CHECK:STDOUT:     %x.loc14_22.1: Core.UInt(N) = param x
 // CHECK:STDOUT:     @Symbolic.%x: Core.UInt(N) = bind_name x, %x.loc14_22.1
-// CHECK:STDOUT:     %UInt.ref.loc14_37: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
+// CHECK:STDOUT:     %UInt.ref.loc14_37: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
 // CHECK:STDOUT:     %N.ref.loc14_42: i32 = name_ref N, @Symbolic.%N [symbolic = constants.%N]
-// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = constants.%.5]
-// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = constants.%.5]
+// CHECK:STDOUT:     %int.make_type_unsigned.loc14_41: init type = call %UInt.ref.loc14_37(%N.ref.loc14_42) [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = constants.%.6]
+// CHECK:STDOUT:     %.loc14_43.2: type = converted %int.make_type_unsigned.loc14_41, %.loc14_43.1 [symbolic = constants.%.6]
 // CHECK:STDOUT:     @Symbolic.%return: ref Core.UInt(N) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -175,7 +190,10 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- fail_zero_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -184,10 +202,10 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%UInt]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %UInt.ref: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:   %.loc10_13: i32 = int_literal 0 [template = constants.%.1]
+// CHECK:STDOUT:   %UInt.ref: UInt = name_ref UInt, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_13: i32 = int_literal 0 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc10_13) [template = <error>]
 // CHECK:STDOUT:   %.loc10_14.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc10_14.2: type = converted %int.make_type_unsigned, %.loc10_14.1 [template = <error>]
@@ -200,30 +218,35 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- fail_negative_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %struct.2: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .UInt = %import_ref
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .n = %n.loc12
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_23 [template = imports.%UInt]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loc_23 [template = constants.%struct.2]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %n.loc6_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %UInt.ref: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_20: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_20) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_12.1: i32 = value_of_initializer %int.snegate [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_12.2: i32 = converted %int.snegate, %.loc12_12.1 [template = constants.%.2]
+// CHECK:STDOUT:   %UInt.ref: UInt = name_ref UInt, %import_ref [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc12_20: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc12_20) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_12.1: i32 = value_of_initializer %int.snegate [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_12.2: i32 = converted %int.snegate, %.loc12_12.1 [template = constants.%.3]
 // CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc12_12.2) [template = <error>]
 // CHECK:STDOUT:   %.loc12_22.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc12_22.2: type = converted %int.make_type_unsigned, %.loc12_22.1 [template = <error>]
@@ -238,7 +261,10 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- fail_oversized.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1000000000 [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -247,10 +273,10 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+5, loc_11 [template = imports.%UInt]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loc_11 [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %UInt.ref: <function> = name_ref UInt, %import_ref [template = imports.%UInt]
-// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 1000000000 [template = constants.%.1]
+// CHECK:STDOUT:   %UInt.ref: UInt = name_ref UInt, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 1000000000 [template = constants.%.2]
 // CHECK:STDOUT:   %int.make_type_unsigned: init type = call %UInt.ref(%.loc9_13) [template = <error>]
 // CHECK:STDOUT:   %.loc9_23.1: type = value_of_initializer %int.make_type_unsigned [template = <error>]
 // CHECK:STDOUT:   %.loc9_23.2: type = converted %int.make_type_unsigned, %.loc9_23.1 [template = <error>]

+ 17 - 11
toolchain/check/testdata/builtins/int/neq.carbon

@@ -23,28 +23,34 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: --- int_neq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Neq: type = fn_type @Neq [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Neq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: bool = bool_literal false [template]
 // CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
 // CHECK:STDOUT:   %.7: bool = bool_literal true [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Neq = %Neq
+// CHECK:STDOUT:     .Neq = %Neq.decl
 // CHECK:STDOUT:     .True = %True.decl
 // CHECK:STDOUT:     .False = %False.decl
-// CHECK:STDOUT:     .F = %F
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .F = %F.decl
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Neq: <function> = fn_decl @Neq [template] {
+// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Neq.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
@@ -53,7 +59,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %True.decl: type = class_decl @True [template = constants.%True] {}
 // CHECK:STDOUT:   %False.decl: type = class_decl @False [template = constants.%False] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // CHECK:STDOUT:     %True.ref: type = name_ref True, %True.decl [template = constants.%True]
 // CHECK:STDOUT:     %true_.loc7_6.1: True = param true_
 // CHECK:STDOUT:     @F.%true_: True = bind_name true_, %true_.loc7_6.1
@@ -61,7 +67,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     %false_.loc7_19.1: False = param false_
 // CHECK:STDOUT:     @F.%false_: False = bind_name false_, %false_.loc7_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc12_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc12_16.1
 // CHECK:STDOUT:     %b.loc12_24.1: i32 = param b
@@ -85,7 +91,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: fn @F(%true_: True, %false_: False) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %false_.ref: False = name_ref false_, %false_
-// CHECK:STDOUT:   %Neq.ref.loc8: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref.loc8: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc8_21: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc8_24: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %int.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_21, %.loc8_24) [template = constants.%.5]
@@ -104,7 +110,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT: !if.expr.result.loc8:
 // CHECK:STDOUT:   %.loc8_14.3: type = block_arg !if.expr.result.loc8 [template = constants.%False]
 // CHECK:STDOUT:   %true_.ref: True = name_ref true_, %true_
-// CHECK:STDOUT:   %Neq.ref.loc9: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref.loc9: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc9_20: i32 = int_literal 1 [template = constants.%.4]
 // CHECK:STDOUT:   %.loc9_23: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %int.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_20, %.loc9_23) [template = constants.%.7]
@@ -127,7 +133,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Neq.ref: <function> = name_ref Neq, file.%Neq [template = file.%Neq]
+// CHECK:STDOUT:   %Neq.ref: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.neq: init bool = call %Neq.ref(%a.ref, %b.ref)

+ 23 - 18
toolchain/check/testdata/builtins/int/or.carbon

@@ -18,42 +18,47 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_or.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 14 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 14] [template]
+// CHECK:STDOUT:   %Or: type = fn_type @Or [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Or = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 12 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 10 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 14 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 14] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Or = %Or
+// CHECK:STDOUT:     .Or = %Or.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Or: <function> = fn_decl @Or [template] {
+// CHECK:STDOUT:   %Or.decl: Or = fn_decl @Or [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_7.1: i32 = param a
 // CHECK:STDOUT:     @Or.%a: i32 = bind_name a, %a.loc2_7.1
 // CHECK:STDOUT:     %b.loc2_15.1: i32 = param b
 // CHECK:STDOUT:     @Or.%b: i32 = bind_name b, %b.loc2_15.1
 // CHECK:STDOUT:     @Or.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Or.ref: <function> = name_ref Or, %Or [template = %Or]
-// CHECK:STDOUT:   %.loc4_19: i32 = int_literal 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.or: init i32 = call %Or.ref(%.loc4_19, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_26: type = array_type %int.or, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, %Or.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_19: i32 = int_literal 12 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 10 [template = constants.%.3]
+// CHECK:STDOUT:   %int.or: init i32 = call %Or.ref(%.loc4_19, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_26: type = array_type %int.or, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 14] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 14] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 14 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_21: type = ptr_type [i32; 14] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 14 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_20: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_21: type = ptr_type [i32; 14] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 14] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_25: [i32; 14]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 14]* = bind_name arr_p, %.loc5_25
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -66,7 +71,7 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Or.ref: <function> = name_ref Or, file.%Or [template = file.%Or]
+// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, file.%Or.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.or: init i32 = call %Or.ref(%a.ref, %b.ref)

+ 109 - 94
toolchain/check/testdata/builtins/int/right_shift.carbon

@@ -63,42 +63,47 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- int_right_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 22 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 5] [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 22 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 5] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .RightShift = %RightShift
+// CHECK:STDOUT:     .RightShift = %RightShift.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift: <function> = fn_decl @RightShift [template] {
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc2_15.1
 // CHECK:STDOUT:     %b.loc2_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc2_23.1
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RightShift.ref: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %.loc4_27: i32 = int_literal 22 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_31: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift: init i32 = call %RightShift.ref(%.loc4_27, %.loc4_31) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_33: type = array_type %int.right_shift, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_27: i32 = int_literal 22 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_31: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.right_shift: init i32 = call %RightShift.ref(%.loc4_27, %.loc4_31) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_33: type = array_type %int.right_shift, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 5] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 5] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 5 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 5] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 5 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 5] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 5] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 5]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 5]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -111,7 +116,7 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %RightShift.ref: <function> = name_ref RightShift, file.%RightShift [template = file.%RightShift]
+// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, file.%RightShift.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.right_shift: init i32 = call %RightShift.ref(%a.ref, %b.ref)
@@ -123,79 +128,84 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- arith_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -1 [template]
-// CHECK:STDOUT:   %.3: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.4: type = ptr_type [i32; 1] [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 10 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -10 [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.8: i32 = int_literal -3 [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.10: type = array_type %.9, i32 [template]
-// CHECK:STDOUT:   %.11: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %.4: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.5: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 10 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -10 [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.9: i32 = int_literal -3 [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.11: type = array_type %.10, i32 [template]
+// CHECK:STDOUT:   %.12: type = ptr_type [i32; 3] [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .RightShift = %RightShift
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .RightShift = %RightShift.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .arr1 = %arr1
 // CHECK:STDOUT:     .arr2 = %arr2
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift: <function> = fn_decl @RightShift [template] {
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc6_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc6_15.1
 // CHECK:STDOUT:     %b.loc6_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc6_23.1
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc7_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref.loc10_17: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %RightShift.ref.loc10: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %Negate.ref.loc10_35: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc10_42: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc10_41: init i32 = call %Negate.ref.loc10_35(%.loc10_42) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_46: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.snegate.loc10_41 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.snegate.loc10_41, %.loc10_34.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift.loc10: init i32 = call %RightShift.ref.loc10(%.loc10_34.2, %.loc10_46) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.right_shift.loc10 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.right_shift.loc10, %.loc10_23.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc10_23: init i32 = call %Negate.ref.loc10_17(%.loc10_23.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_49: type = array_type %int.snegate.loc10_23, i32 [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc10_17: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %RightShift.ref.loc10: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc10_35: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc10_42: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc10_41: init i32 = call %Negate.ref.loc10_35(%.loc10_42) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_46: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.snegate.loc10_41 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.snegate.loc10_41, %.loc10_34.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.right_shift.loc10: init i32 = call %RightShift.ref.loc10(%.loc10_34.2, %.loc10_46) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.right_shift.loc10 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.right_shift.loc10, %.loc10_23.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.snegate.loc10_23: init i32 = call %Negate.ref.loc10_17(%.loc10_23.2) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_49: type = array_type %int.snegate.loc10_23, i32 [template = constants.%.4]
 // CHECK:STDOUT:   %arr1.var: ref [i32; 1] = var arr1
 // CHECK:STDOUT:   %arr1: ref [i32; 1] = bind_name arr1, %arr1.var
-// CHECK:STDOUT:   %.loc11_19: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_20: type = array_type %.loc11_19, i32 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_21: type = ptr_type [i32; 1] [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_19: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_20: type = array_type %.loc11_19, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_21: type = ptr_type [i32; 1] [template = constants.%.5]
 // CHECK:STDOUT:   %arr1.ref: ref [i32; 1] = name_ref arr1, %arr1
 // CHECK:STDOUT:   %.loc11_25: [i32; 1]* = addr_of %arr1.ref
 // CHECK:STDOUT:   %arr1_p: [i32; 1]* = bind_name arr1_p, %.loc11_25
-// CHECK:STDOUT:   %Negate.ref.loc14_17: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %RightShift.ref.loc14: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %Negate.ref.loc14_35: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc14_42: i32 = int_literal 10 [template = constants.%.5]
-// CHECK:STDOUT:   %int.snegate.loc14_41: init i32 = call %Negate.ref.loc14_35(%.loc14_42) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc14_47: i32 = int_literal 2 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc14_34.1: i32 = value_of_initializer %int.snegate.loc14_41 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc14_34.2: i32 = converted %int.snegate.loc14_41, %.loc14_34.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.right_shift.loc14: init i32 = call %RightShift.ref.loc14(%.loc14_34.2, %.loc14_47) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc14_23.1: i32 = value_of_initializer %int.right_shift.loc14 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc14_23.2: i32 = converted %int.right_shift.loc14, %.loc14_23.1 [template = constants.%.8]
-// CHECK:STDOUT:   %int.snegate.loc14_23: init i32 = call %Negate.ref.loc14_17(%.loc14_23.2) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc14_50: type = array_type %int.snegate.loc14_23, i32 [template = constants.%.10]
+// CHECK:STDOUT:   %Negate.ref.loc14_17: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %RightShift.ref.loc14: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc14_35: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc14_42: i32 = int_literal 10 [template = constants.%.6]
+// CHECK:STDOUT:   %int.snegate.loc14_41: init i32 = call %Negate.ref.loc14_35(%.loc14_42) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc14_47: i32 = int_literal 2 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc14_34.1: i32 = value_of_initializer %int.snegate.loc14_41 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc14_34.2: i32 = converted %int.snegate.loc14_41, %.loc14_34.1 [template = constants.%.7]
+// CHECK:STDOUT:   %int.right_shift.loc14: init i32 = call %RightShift.ref.loc14(%.loc14_34.2, %.loc14_47) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc14_23.1: i32 = value_of_initializer %int.right_shift.loc14 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc14_23.2: i32 = converted %int.right_shift.loc14, %.loc14_23.1 [template = constants.%.9]
+// CHECK:STDOUT:   %int.snegate.loc14_23: init i32 = call %Negate.ref.loc14_17(%.loc14_23.2) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc14_50: type = array_type %int.snegate.loc14_23, i32 [template = constants.%.11]
 // CHECK:STDOUT:   %arr2.var: ref [i32; 3] = var arr2
 // CHECK:STDOUT:   %arr2: ref [i32; 3] = bind_name arr2, %arr2.var
-// CHECK:STDOUT:   %.loc15_19: i32 = int_literal 3 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc15_20: type = array_type %.loc15_19, i32 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc15_21: type = ptr_type [i32; 3] [template = constants.%.11]
+// CHECK:STDOUT:   %.loc15_19: i32 = int_literal 3 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc15_20: type = array_type %.loc15_19, i32 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc15_21: type = ptr_type [i32; 3] [template = constants.%.12]
 // CHECK:STDOUT:   %arr2.ref: ref [i32; 3] = name_ref arr2, %arr2
 // CHECK:STDOUT:   %.loc15_25: [i32; 3]* = addr_of %arr2.ref
 // CHECK:STDOUT:   %arr2_p: [i32; 3]* = bind_name arr2_p, %.loc15_25
@@ -208,61 +218,66 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- fail_bad_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 31 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 32 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 33 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 31 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 33 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .RightShift = %RightShift
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .RightShift = %RightShift.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift: <function> = fn_decl @RightShift [template] {
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc4_15.1
 // CHECK:STDOUT:     %b.loc4_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc4_23.1
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc5_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RightShift.ref.loc8: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %.loc8_30: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_33: i32 = int_literal 31 [template = constants.%.2]
-// CHECK:STDOUT:   %int.right_shift.loc8: init i32 = call %RightShift.ref.loc8(%.loc8_30, %.loc8_33) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_36.1: i32 = value_of_initializer %int.right_shift.loc8 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_36.2: i32 = converted %int.right_shift.loc8, %.loc8_36.1 [template = constants.%.3]
+// CHECK:STDOUT:   %RightShift.ref.loc8: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_30: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_33: i32 = int_literal 31 [template = constants.%.3]
+// CHECK:STDOUT:   %int.right_shift.loc8: init i32 = call %RightShift.ref.loc8(%.loc8_30, %.loc8_33) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_36.1: i32 = value_of_initializer %int.right_shift.loc8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_36.2: i32 = converted %int.right_shift.loc8, %.loc8_36.1 [template = constants.%.4]
 // CHECK:STDOUT:   %size_1: i32 = bind_name size_1, %.loc8_36.2
-// CHECK:STDOUT:   %RightShift.ref.loc13: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %.loc13_30: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc13_33: i32 = int_literal 32 [template = constants.%.4]
+// CHECK:STDOUT:   %RightShift.ref.loc13: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc13_30: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc13_33: i32 = int_literal 32 [template = constants.%.5]
 // CHECK:STDOUT:   %int.right_shift.loc13: init i32 = call %RightShift.ref.loc13(%.loc13_30, %.loc13_33) [template = <error>]
 // CHECK:STDOUT:   %.loc13_36.1: i32 = value_of_initializer %int.right_shift.loc13 [template = <error>]
 // CHECK:STDOUT:   %.loc13_36.2: i32 = converted %int.right_shift.loc13, %.loc13_36.1 [template = <error>]
 // CHECK:STDOUT:   %size_2: i32 = bind_name size_2, %.loc13_36.2
-// CHECK:STDOUT:   %RightShift.ref.loc18: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %.loc18_30: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_33: i32 = int_literal 33 [template = constants.%.5]
+// CHECK:STDOUT:   %RightShift.ref.loc18: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc18_30: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc18_33: i32 = int_literal 33 [template = constants.%.6]
 // CHECK:STDOUT:   %int.right_shift.loc18: init i32 = call %RightShift.ref.loc18(%.loc18_30, %.loc18_33) [template = <error>]
 // CHECK:STDOUT:   %.loc18_36.1: i32 = value_of_initializer %int.right_shift.loc18 [template = <error>]
 // CHECK:STDOUT:   %.loc18_36.2: i32 = converted %int.right_shift.loc18, %.loc18_36.1 [template = <error>]
 // CHECK:STDOUT:   %size_3: i32 = bind_name size_3, %.loc18_36.2
-// CHECK:STDOUT:   %RightShift.ref.loc24: <function> = name_ref RightShift, %RightShift [template = %RightShift]
-// CHECK:STDOUT:   %.loc24_32: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc24_42: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc24_42) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_31.1: i32 = value_of_initializer %int.snegate [template = constants.%.6]
-// CHECK:STDOUT:   %.loc24_31.2: i32 = converted %int.snegate, %.loc24_31.1 [template = constants.%.6]
+// CHECK:STDOUT:   %RightShift.ref.loc24: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc24_32: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc24_42: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%.loc24_42) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc24_31.1: i32 = value_of_initializer %int.snegate [template = constants.%.7]
+// CHECK:STDOUT:   %.loc24_31.2: i32 = converted %int.snegate, %.loc24_31.1 [template = constants.%.7]
 // CHECK:STDOUT:   %int.right_shift.loc24: init i32 = call %RightShift.ref.loc24(%.loc24_32, %.loc24_31.2) [template = <error>]
 // CHECK:STDOUT:   %.loc24_45.1: i32 = value_of_initializer %int.right_shift.loc24 [template = <error>]
 // CHECK:STDOUT:   %.loc24_45.2: i32 = converted %int.right_shift.loc24, %.loc24_45.1 [template = <error>]

+ 92 - 69
toolchain/check/testdata/builtins/int/sadd.carbon

@@ -88,42 +88,47 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- int_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Add = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
+// CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.sadd, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.sadd, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 3] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 3] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 3] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 3] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 3] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 3]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 3]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -136,7 +141,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, file.%Add [template = file.%Add]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.sadd: init i32 = call %Add.ref(%a.ref, %b.ref)
@@ -148,33 +153,48 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
 // CHECK:STDOUT:     .too_few = %too_few
 // CHECK:STDOUT:     .too_many = %too_many
 // CHECK:STDOUT:     .bad_return_type = %bad_return_type
 // CHECK:STDOUT:     .bad_call = %bad_call
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: i32 = param a
 // CHECK:STDOUT:     @TooFew.%a: i32 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
@@ -183,52 +203,52 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     @TooMany.%c: i32 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
 // CHECK:STDOUT:     %b.loc18_26.1: i32 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: i32 = bind_name b, %b.loc18_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
 // CHECK:STDOUT:     %b.loc19_22.1: i32 = param b
 // CHECK:STDOUT:     @JustRight.%b: i32 = bind_name b, %b.loc19_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, %TooFew [template = %TooFew]
-// CHECK:STDOUT:   %.loc25: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc25: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25)
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, %TooMany [template = %TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc30_35: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc30_35: i32 = int_literal 3 [template = constants.%.4]
 // CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32, %.loc30_35)
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, %BadReturnType [template = %BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc35_45: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc35_42: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc35_45: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42, %.loc35_45)
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
-// CHECK:STDOUT:   %JustRight.ref: <function> = name_ref JustRight, %JustRight [template = %JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc44_37: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc44_37: i32 = int_literal 3 [template = constants.%.4]
 // CHECK:STDOUT:   %int.sadd: init i32 = call %JustRight.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc44_39: type = array_type %int.sadd, i32 [template = <error>]
 // CHECK:STDOUT:   %bad_call.var: ref <error> = var bad_call
 // CHECK:STDOUT:   %bad_call: ref <error> = bind_name bad_call, %bad_call.var
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc50_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc50_23.1
 // CHECK:STDOUT:     %b.loc50_31.1: i32 = param b
@@ -237,7 +257,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc50_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc54_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc54_29.1
 // CHECK:STDOUT:     %b.loc54_37.1: i32 = param b
@@ -256,7 +276,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc47_19.1: i32 = value_of_initializer %TooFew.call
@@ -266,7 +286,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: i32, %b: i32, %c: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: i32 = name_ref c, %c
@@ -278,7 +298,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)
@@ -290,38 +310,41 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
+// CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref.loc6: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_30: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sadd.loc6: init i32 = call %Add.ref.loc6(%.loc6_18, %.loc6_30) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.sadd.loc6 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.sadd.loc6, %.loc6_32.1 [template = constants.%.1]
+// CHECK:STDOUT:   %Add.ref.loc6: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_30: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %int.sadd.loc6: init i32 = call %Add.ref.loc6(%.loc6_18, %.loc6_30) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.sadd.loc6 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.sadd.loc6, %.loc6_32.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a.loc6: i32 = bind_name a, %.loc6_32.2
-// CHECK:STDOUT:   %Add.ref.loc10: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_30: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.sadd.loc10: init i32 = call %Add.ref.loc10(%.loc10_18, %.loc10_30) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_32.1: i32 = value_of_initializer %int.sadd.loc10 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_32.2: i32 = converted %int.sadd.loc10, %.loc10_32.1 [template = constants.%.4]
+// CHECK:STDOUT:   %Add.ref.loc10: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_30: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.sadd.loc10: init i32 = call %Add.ref.loc10(%.loc10_18, %.loc10_30) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_32.1: i32 = value_of_initializer %int.sadd.loc10 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_32.2: i32 = converted %int.sadd.loc10, %.loc10_32.1 [template = constants.%.5]
 // CHECK:STDOUT:   %b.loc10: i32 = bind_name b, %.loc10_32.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 102 - 87
toolchain/check/testdata/builtins/int/sdiv.carbon

@@ -56,42 +56,47 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
+// CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.sdiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.sdiv, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.sdiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.sdiv, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 1] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 1] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 1] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 1]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 1]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -104,7 +109,7 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, file.%Div [template = file.%Div]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.sdiv: init i32 = call %Div.ref(%a.ref, %b.ref)
@@ -116,90 +121,97 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
-// CHECK:STDOUT:     .Sub = %Sub
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Div = %Div.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc9: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Negate.ref.loc9_18: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
-// CHECK:STDOUT:   %Negate.ref.loc9_39: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.snegate.loc9_24, %.loc9_17.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.snegate.loc9_45, %.loc9_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.sdiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.sdiv.loc9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.sdiv.loc9, %.loc9_49.1 [template = constants.%.1]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.snegate.loc9_24, %.loc9_17.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.snegate.loc9_45, %.loc9_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.sdiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.sdiv.loc9 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.sdiv.loc9, %.loc9_49.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a.loc9: i32 = bind_name a, %.loc9_49.2
-// CHECK:STDOUT:   %Div.ref.loc12: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Sub.ref.loc12: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.snegate.loc12, %.loc12_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.ssub.loc12, %.loc12_17.1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.sdiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.sdiv.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.sdiv.loc12, %.loc12_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Div.ref.loc12: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.snegate.loc12, %.loc12_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.ssub.loc12, %.loc12_17.1 [template = constants.%.6]
+// CHECK:STDOUT:   %int.sdiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.sdiv.loc12 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.sdiv.loc12, %.loc12_49.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc12: i32 = bind_name b, %.loc12_49.2
-// CHECK:STDOUT:   %Div.ref.loc19: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Sub.ref.loc19: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc19_22: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc19_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc19_28: init i32 = call %Negate.ref.loc19_22(%.loc19_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc19_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc19_21.1: i32 = value_of_initializer %int.snegate.loc19_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc19_21.2: i32 = converted %int.snegate.loc19_28, %.loc19_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc19: init i32 = call %Sub.ref.loc19(%.loc19_21.2, %.loc19_43) [template = constants.%.5]
-// CHECK:STDOUT:   %Negate.ref.loc19_47: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc19_54: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc19_53: init i32 = call %Negate.ref.loc19_47(%.loc19_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc19_17.1: i32 = value_of_initializer %int.ssub.loc19 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_17.2: i32 = converted %int.ssub.loc19, %.loc19_17.1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_17.3: i32 = value_of_initializer %int.snegate.loc19_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc19_17.4: i32 = converted %int.snegate.loc19_53, %.loc19_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.sdiv.loc19: init i32 = call %Div.ref.loc19(%.loc19_17.2, %.loc19_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_57.1: i32 = value_of_initializer %int.sdiv.loc19 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc19_57.2: i32 = converted %int.sdiv.loc19, %.loc19_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Div.ref.loc19: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc19: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc19_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc19_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc19_28: init i32 = call %Negate.ref.loc19_22(%.loc19_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc19_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc19_21.1: i32 = value_of_initializer %int.snegate.loc19_28 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc19_21.2: i32 = converted %int.snegate.loc19_28, %.loc19_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc19: init i32 = call %Sub.ref.loc19(%.loc19_21.2, %.loc19_43) [template = constants.%.6]
+// CHECK:STDOUT:   %Negate.ref.loc19_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc19_54: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.snegate.loc19_53: init i32 = call %Negate.ref.loc19_47(%.loc19_54) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc19_17.1: i32 = value_of_initializer %int.ssub.loc19 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc19_17.2: i32 = converted %int.ssub.loc19, %.loc19_17.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc19_17.3: i32 = value_of_initializer %int.snegate.loc19_53 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc19_17.4: i32 = converted %int.snegate.loc19_53, %.loc19_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.sdiv.loc19: init i32 = call %Div.ref.loc19(%.loc19_17.2, %.loc19_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc19_57.1: i32 = value_of_initializer %int.sdiv.loc19 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc19_57.2: i32 = converted %int.sdiv.loc19, %.loc19_57.1 [template = constants.%.6]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc19_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -212,33 +224,36 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Div = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
+// CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc10: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.sdiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18, %.loc10_21) [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.sdiv.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.sdiv.loc10, %.loc10_23.1 [template = <error>]
 // CHECK:STDOUT:   %a.loc10: i32 = bind_name a, %.loc10_23.2
-// CHECK:STDOUT:   %Div.ref.loc15: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc15_18: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc15_18: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.sdiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18, %.loc15_21) [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.1: i32 = value_of_initializer %int.sdiv.loc15 [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.2: i32 = converted %int.sdiv.loc15, %.loc15_23.1 [template = <error>]

+ 103 - 88
toolchain/check/testdata/builtins/int/smod.carbon

@@ -59,42 +59,47 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 2] [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 2] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
+// CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 3 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.smod, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %int.smod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.smod, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 2] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 2] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 2] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 2] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 2] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 2]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 2]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -107,7 +112,7 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mod.ref: <function> = name_ref Mod, file.%Mod [template = file.%Mod]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.smod: init i32 = call %Mod.ref(%a.ref, %b.ref)
@@ -119,91 +124,98 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
-// CHECK:STDOUT:     .Sub = %Sub
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Mod = %Mod.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc9: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Negate.ref.loc9_18: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
-// CHECK:STDOUT:   %Negate.ref.loc9_39: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.snegate.loc9_24, %.loc9_17.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.snegate.loc9_45, %.loc9_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.smod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.smod.loc9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.smod.loc9, %.loc9_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mod.ref.loc9: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.snegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.snegate.loc9_24 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.snegate.loc9_24, %.loc9_17.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.snegate.loc9_45 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.snegate.loc9_45, %.loc9_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.smod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.smod.loc9 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.smod.loc9, %.loc9_49.1 [template = constants.%.6]
 // CHECK:STDOUT:   %a.loc9: i32 = bind_name a, %.loc9_49.2
-// CHECK:STDOUT:   %Mod.ref.loc12: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Sub.ref.loc12: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.snegate.loc12, %.loc12_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.ssub.loc12, %.loc12_17.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.smod.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.smod.loc12, %.loc12_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.snegate.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.snegate.loc12, %.loc12_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.ssub.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.ssub.loc12, %.loc12_17.1 [template = constants.%.7]
+// CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.smod.loc12 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.smod.loc12, %.loc12_49.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc12: i32 = bind_name b, %.loc12_49.2
-// CHECK:STDOUT:   %Mod.ref.loc20: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Sub.ref.loc20: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc20_22: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc20_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc20_28: init i32 = call %Negate.ref.loc20_22(%.loc20_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc20_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc20_21.1: i32 = value_of_initializer %int.snegate.loc20_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc20_21.2: i32 = converted %int.snegate.loc20_28, %.loc20_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc20: init i32 = call %Sub.ref.loc20(%.loc20_21.2, %.loc20_43) [template = constants.%.6]
-// CHECK:STDOUT:   %Negate.ref.loc20_47: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc20_54: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.snegate.loc20_53: init i32 = call %Negate.ref.loc20_47(%.loc20_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc20_17.1: i32 = value_of_initializer %int.ssub.loc20 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc20_17.2: i32 = converted %int.ssub.loc20, %.loc20_17.1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc20_17.3: i32 = value_of_initializer %int.snegate.loc20_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc20_17.4: i32 = converted %int.snegate.loc20_53, %.loc20_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.smod.loc20: init i32 = call %Mod.ref.loc20(%.loc20_17.2, %.loc20_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc20_57.1: i32 = value_of_initializer %int.smod.loc20 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc20_57.2: i32 = converted %int.smod.loc20, %.loc20_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mod.ref.loc20: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc20: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc20_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc20_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc20_28: init i32 = call %Negate.ref.loc20_22(%.loc20_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc20_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc20_21.1: i32 = value_of_initializer %int.snegate.loc20_28 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc20_21.2: i32 = converted %int.snegate.loc20_28, %.loc20_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc20: init i32 = call %Sub.ref.loc20(%.loc20_21.2, %.loc20_43) [template = constants.%.7]
+// CHECK:STDOUT:   %Negate.ref.loc20_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc20_54: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.snegate.loc20_53: init i32 = call %Negate.ref.loc20_47(%.loc20_54) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc20_17.1: i32 = value_of_initializer %int.ssub.loc20 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc20_17.2: i32 = converted %int.ssub.loc20, %.loc20_17.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc20_17.3: i32 = value_of_initializer %int.snegate.loc20_53 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc20_17.4: i32 = converted %int.snegate.loc20_53, %.loc20_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.smod.loc20: init i32 = call %Mod.ref.loc20(%.loc20_17.2, %.loc20_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc20_57.1: i32 = value_of_initializer %int.smod.loc20 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc20_57.2: i32 = converted %int.smod.loc20, %.loc20_57.1 [template = constants.%.6]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc20_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -216,33 +228,36 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Mod = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
+// CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc12: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc12_18: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_18: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.smod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18, %.loc12_21) [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.1: i32 = value_of_initializer %int.smod.loc12 [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.2: i32 = converted %int.smod.loc12, %.loc12_23.1 [template = <error>]
 // CHECK:STDOUT:   %a.loc12: i32 = bind_name a, %.loc12_23.2
-// CHECK:STDOUT:   %Mod.ref.loc17: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc17_18: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Mod.ref.loc17: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_18: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.smod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18, %.loc17_21) [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.1: i32 = value_of_initializer %int.smod.loc17 [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.2: i32 = converted %int.smod.loc17, %.loc17_23.1 [template = <error>]

+ 45 - 37
toolchain/check/testdata/builtins/int/smul.carbon

@@ -30,42 +30,47 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- int_mul.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 6 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mul = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mul = %Mul
+// CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul: <function> = fn_decl @Mul [template] {
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.smul, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.smul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.smul, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 6] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 6] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 6] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 6]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 6]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -78,7 +83,7 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, file.%Mul [template = file.%Mul]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.smul: init i32 = call %Mul.ref(%a.ref, %b.ref)
@@ -90,39 +95,42 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 32767 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 65536 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 2147418112 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 32768 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Mul = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 32767 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 65536 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 2147418112 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 32768 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mul = %Mul
+// CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul: <function> = fn_decl @Mul [template] {
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref.loc6: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 32767 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_26: i32 = int_literal 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.smul.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.smul.loc6, %.loc6_34.1 [template = constants.%.3]
+// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 32767 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_26: i32 = int_literal 65536 [template = constants.%.3]
+// CHECK:STDOUT:   %int.smul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.smul.loc6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.smul.loc6, %.loc6_34.1 [template = constants.%.4]
 // CHECK:STDOUT:   %a.loc6: i32 = bind_name a, %.loc6_34.2
-// CHECK:STDOUT:   %Mul.ref.loc10: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 32768 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.smul.loc10: init i32 = call %Mul.ref.loc10(%.loc10_18, %.loc10_26) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.smul.loc10 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.smul.loc10, %.loc10_34.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mul.ref.loc10: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 32768 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 65536 [template = constants.%.3]
+// CHECK:STDOUT:   %int.smul.loc10: init i32 = call %Mul.ref.loc10(%.loc10_18, %.loc10_26) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_34.1: i32 = value_of_initializer %int.smul.loc10 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc10_34.2: i32 = converted %int.smul.loc10, %.loc10_34.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc10: i32 = bind_name b, %.loc10_34.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 111 - 86
toolchain/check/testdata/builtins/int/snegate.carbon

@@ -115,50 +115,55 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 123 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -123 [template]
-// CHECK:STDOUT:   %.3: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.4: type = ptr_type [i32; 123] [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 123 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -123 [template]
+// CHECK:STDOUT:   %.4: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.5: type = ptr_type [i32; 123] [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc2_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref.loc4_16: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Negate.ref.loc4_23: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc4_30: i32 = int_literal 123 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_22.1: i32 = value_of_initializer %int.snegate.loc4_29 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_22.2: i32 = converted %int.snegate.loc4_29, %.loc4_22.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_22.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_35: type = array_type %int.snegate.loc4_22, i32 [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc4_16: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc4_23: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_30: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_22.1: i32 = value_of_initializer %int.snegate.loc4_29 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_22.2: i32 = converted %int.snegate.loc4_29, %.loc4_22.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.snegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_22.2) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_35: type = array_type %int.snegate.loc4_22, i32 [template = constants.%.4]
 // CHECK:STDOUT:   %arr.var: ref [i32; 123] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 123] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_22: type = ptr_type [i32; 123] [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_22: type = ptr_type [i32; 123] [template = constants.%.5]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 123] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_26: [i32; 123]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 123]* = bind_name arr_p, %.loc5_26
-// CHECK:STDOUT:   %Negate.ref.loc7: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc7_21: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.snegate.loc7: init i32 = call %Negate.ref.loc7(%.loc7_21) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.snegate.loc7 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.snegate.loc7, %.loc7_23.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Negate.ref.loc7: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc7_21: i32 = int_literal 1 [template = constants.%.6]
+// CHECK:STDOUT:   %int.snegate.loc7: init i32 = call %Negate.ref.loc7(%.loc7_21) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.snegate.loc7 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.snegate.loc7, %.loc7_23.1 [template = constants.%.7]
 // CHECK:STDOUT:   %n: i32 = bind_name n, %.loc7_23.2
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc9_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc9_16.1
 // CHECK:STDOUT:     %b.loc9_24.1: i32 = param b
@@ -171,7 +176,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %int.snegate: init i32 = call %Negate.ref(%a.ref)
 // CHECK:STDOUT:   %.loc10_19.1: i32 = value_of_initializer %int.snegate
@@ -182,74 +187,89 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
 // CHECK:STDOUT:     .too_few = %too_few
 // CHECK:STDOUT:     .too_many = %too_many
 // CHECK:STDOUT:     .bad_return_type = %bad_return_type
 // CHECK:STDOUT:     .bad_call = %bad_call
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, %TooFew [template = %TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref()
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, %TooMany [template = %TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32)
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, %BadReturnType [template = %BadReturnType]
-// CHECK:STDOUT:   %.loc35: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc35: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35)
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
-// CHECK:STDOUT:   %JustRight.ref: <function> = name_ref JustRight, %JustRight [template = %JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %int.snegate: init i32 = call %JustRight.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc44_36: type = array_type %int.snegate, i32 [template = <error>]
 // CHECK:STDOUT:   %bad_call.var: ref <error> = var bad_call
 // CHECK:STDOUT:   %bad_call: ref <error> = bind_name bad_call, %bad_call.var
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc57_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc57_23.1
 // CHECK:STDOUT:     %b.loc57_31.1: i32 = param b
@@ -258,7 +278,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc57_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc68_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc68_29.1
 // CHECK:STDOUT:     %b.loc68_37.1: i32 = param b
@@ -277,7 +297,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc54_19.1: i32 = value_of_initializer %TooFew.call [template = <error>]
@@ -287,7 +307,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: i32, %b: i32, %c: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: i32 = name_ref c, %c
@@ -299,7 +319,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(<invalid>) [template = <error>]
@@ -311,55 +331,60 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Negate = %Negate.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc4_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref.loc8_14: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Negate.ref.loc8_21: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc8_28: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_20.1: i32 = value_of_initializer %int.snegate.loc8_27 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_20.2: i32 = converted %int.snegate.loc8_27, %.loc8_20.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.snegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_20.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.snegate.loc8_20 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.snegate.loc8_20, %.loc8_40.1 [template = constants.%.1]
+// CHECK:STDOUT:   %Negate.ref.loc8_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc8_21: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_28: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_20.1: i32 = value_of_initializer %int.snegate.loc8_27 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_20.2: i32 = converted %int.snegate.loc8_27, %.loc8_20.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.snegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_20.2) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.snegate.loc8_20 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.snegate.loc8_20, %.loc8_40.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a.loc8: i32 = bind_name a, %.loc8_40.2
-// CHECK:STDOUT:   %Negate.ref.loc14_14: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc14_25: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc14_32: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.snegate.loc14_31: init i32 = call %Negate.ref.loc14_25(%.loc14_32) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc14_45: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc14_24.1: i32 = value_of_initializer %int.snegate.loc14_31 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc14_24.2: i32 = converted %int.snegate.loc14_31, %.loc14_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc14_24.2, %.loc14_45) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_20.1: i32 = value_of_initializer %int.ssub [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_20.2: i32 = converted %int.ssub, %.loc14_20.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.snegate.loc14_20: init i32 = call %Negate.ref.loc14_14(%.loc14_20.2) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_48.1: i32 = value_of_initializer %int.snegate.loc14_20 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc14_48.2: i32 = converted %int.snegate.loc14_20, %.loc14_48.1 [template = constants.%.4]
+// CHECK:STDOUT:   %Negate.ref.loc14_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc14_25: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc14_32: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.snegate.loc14_31: init i32 = call %Negate.ref.loc14_25(%.loc14_32) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc14_45: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc14_24.1: i32 = value_of_initializer %int.snegate.loc14_31 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc14_24.2: i32 = converted %int.snegate.loc14_31, %.loc14_24.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc14_24.2, %.loc14_45) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_20.1: i32 = value_of_initializer %int.ssub [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_20.2: i32 = converted %int.ssub, %.loc14_20.1 [template = constants.%.5]
+// CHECK:STDOUT:   %int.snegate.loc14_20: init i32 = call %Negate.ref.loc14_14(%.loc14_20.2) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_48.1: i32 = value_of_initializer %int.snegate.loc14_20 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_48.2: i32 = converted %int.snegate.loc14_20, %.loc14_48.1 [template = constants.%.5]
 // CHECK:STDOUT:   %b.loc14: i32 = bind_name b, %.loc14_48.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 62 - 54
toolchain/check/testdata/builtins/int/ssub.carbon

@@ -31,42 +31,47 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- int_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.ssub, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.ssub, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 1] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 1] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 1] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 1]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 1]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -79,7 +84,7 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, file.%Sub [template = file.%Sub]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.ssub: init i32 = call %Sub.ref(%a.ref, %b.ref)
@@ -91,57 +96,60 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref.loc6: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_21: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.ssub.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.ssub.loc6, %.loc6_32.1 [template = constants.%.3]
+// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_21: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.ssub.loc6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.ssub.loc6, %.loc6_32.1 [template = constants.%.4]
 // CHECK:STDOUT:   %a.loc6: i32 = bind_name a, %.loc6_32.2
-// CHECK:STDOUT:   %Sub.ref.loc7_14: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Sub.ref.loc7_18: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc7_22: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_25: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_17.1: i32 = value_of_initializer %int.ssub.loc7_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_17.2: i32 = converted %int.ssub.loc7_21, %.loc7_17.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.ssub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_17.2, %.loc7_38) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.ssub.loc7_17 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.ssub.loc7_17, %.loc7_40.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Sub.ref.loc7_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %Sub.ref.loc7_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc7_22: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_25: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_17.1: i32 = value_of_initializer %int.ssub.loc7_21 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_17.2: i32 = converted %int.ssub.loc7_21, %.loc7_17.1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.ssub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_17.2, %.loc7_38) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.ssub.loc7_17 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.ssub.loc7_17, %.loc7_40.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc7: i32 = bind_name b, %.loc7_40.2
-// CHECK:STDOUT:   %Sub.ref.loc11_14: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Sub.ref.loc11_18: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc11_22: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_25: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.ssub.loc11_21: init i32 = call %Sub.ref.loc11_18(%.loc11_22, %.loc11_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_38: i32 = int_literal 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc11_17.1: i32 = value_of_initializer %int.ssub.loc11_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_17.2: i32 = converted %int.ssub.loc11_21, %.loc11_17.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.ssub.loc11_17: init i32 = call %Sub.ref.loc11_14(%.loc11_17.2, %.loc11_38) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_40.1: i32 = value_of_initializer %int.ssub.loc11_17 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_40.2: i32 = converted %int.ssub.loc11_17, %.loc11_40.1 [template = constants.%.2]
+// CHECK:STDOUT:   %Sub.ref.loc11_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %Sub.ref.loc11_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc11_22: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_25: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.ssub.loc11_21: init i32 = call %Sub.ref.loc11_18(%.loc11_22, %.loc11_25) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_38: i32 = int_literal 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_17.1: i32 = value_of_initializer %int.ssub.loc11_21 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_17.2: i32 = converted %int.ssub.loc11_21, %.loc11_17.1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.ssub.loc11_17: init i32 = call %Sub.ref.loc11_14(%.loc11_17.2, %.loc11_38) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_40.1: i32 = value_of_initializer %int.ssub.loc11_17 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_40.2: i32 = converted %int.ssub.loc11_17, %.loc11_40.1 [template = constants.%.3]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc11_40.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 92 - 69
toolchain/check/testdata/builtins/int/uadd.carbon

@@ -85,42 +85,47 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- int_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Add = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
+// CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.uadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.uadd, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.uadd: init i32 = call %Add.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.uadd, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 3] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 3] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 3] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 3] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 3] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 3]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 3]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -133,7 +138,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, file.%Add [template = file.%Add]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.uadd: init i32 = call %Add.ref(%a.ref, %b.ref)
@@ -145,33 +150,48 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
 // CHECK:STDOUT:     .too_few = %too_few
 // CHECK:STDOUT:     .too_many = %too_many
 // CHECK:STDOUT:     .bad_return_type = %bad_return_type
 // CHECK:STDOUT:     .bad_call = %bad_call
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc8_11.1: i32 = param a
 // CHECK:STDOUT:     @TooFew.%a: i32 = bind_name a, %a.loc8_11.1
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
@@ -180,52 +200,52 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     @TooMany.%c: i32 = bind_name c, %c.loc13_28.1
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
 // CHECK:STDOUT:     %b.loc18_26.1: i32 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: i32 = bind_name b, %b.loc18_26.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
 // CHECK:STDOUT:     %b.loc19_22.1: i32 = param b
 // CHECK:STDOUT:     @JustRight.%b: i32 = bind_name b, %b.loc19_22.1
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, %TooFew [template = %TooFew]
-// CHECK:STDOUT:   %.loc25: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc25: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%.loc25)
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, %TooMany [template = %TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc30_35: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc30_35: i32 = int_literal 3 [template = constants.%.4]
 // CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32, %.loc30_35)
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, %BadReturnType [template = %BadReturnType]
-// CHECK:STDOUT:   %.loc35_42: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc35_45: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc35_42: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc35_45: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35_42, %.loc35_45)
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
-// CHECK:STDOUT:   %JustRight.ref: <function> = name_ref JustRight, %JustRight [template = %JustRight]
-// CHECK:STDOUT:   %.loc43_31: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc43_34: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc43_37: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc43_31: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc43_34: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc43_37: i32 = int_literal 3 [template = constants.%.4]
 // CHECK:STDOUT:   %int.uadd: init i32 = call %JustRight.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc43_39: type = array_type %int.uadd, i32 [template = <error>]
 // CHECK:STDOUT:   %bad_call.var: ref <error> = var bad_call
 // CHECK:STDOUT:   %bad_call: ref <error> = bind_name bad_call, %bad_call.var
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc45_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc45_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc49_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc49_23.1
 // CHECK:STDOUT:     %b.loc49_31.1: i32 = param b
@@ -234,7 +254,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc49_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc53_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc53_29.1
 // CHECK:STDOUT:     %b.loc53_37.1: i32 = param b
@@ -253,7 +273,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(%a.ref)
 // CHECK:STDOUT:   %.loc46_19.1: i32 = value_of_initializer %TooFew.call
@@ -263,7 +283,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: i32, %b: i32, %c: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: i32 = name_ref c, %c
@@ -275,7 +295,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%a.ref, %b.ref)
@@ -287,38 +307,41 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Add = %Add
+// CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add: <function> = fn_decl @Add [template] {
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref.loc7: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc7_18: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %int.uadd.loc7: init i32 = call %Add.ref.loc7(%.loc7_18, %.loc7_30) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_32.1: i32 = value_of_initializer %int.uadd.loc7 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_32.2: i32 = converted %int.uadd.loc7, %.loc7_32.1 [template = constants.%.1]
+// CHECK:STDOUT:   %Add.ref.loc7: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc7_18: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %int.uadd.loc7: init i32 = call %Add.ref.loc7(%.loc7_18, %.loc7_30) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_32.1: i32 = value_of_initializer %int.uadd.loc7 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_32.2: i32 = converted %int.uadd.loc7, %.loc7_32.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a.loc7: i32 = bind_name a, %.loc7_32.2
-// CHECK:STDOUT:   %Add.ref.loc8: <function> = name_ref Add, %Add [template = %Add]
-// CHECK:STDOUT:   %.loc8_18: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_30: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.uadd.loc8: init i32 = call %Add.ref.loc8(%.loc8_18, %.loc8_30) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_32.1: i32 = value_of_initializer %int.uadd.loc8 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc8_32.2: i32 = converted %int.uadd.loc8, %.loc8_32.1 [template = constants.%.4]
+// CHECK:STDOUT:   %Add.ref.loc8: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc8_18: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_30: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.uadd.loc8: init i32 = call %Add.ref.loc8(%.loc8_18, %.loc8_30) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_32.1: i32 = value_of_initializer %int.uadd.loc8 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_32.2: i32 = converted %int.uadd.loc8, %.loc8_32.1 [template = constants.%.5]
 // CHECK:STDOUT:   %b.loc8: i32 = bind_name b, %.loc8_32.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 103 - 88
toolchain/check/testdata/builtins/int/udiv.carbon

@@ -52,42 +52,47 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
+// CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.udiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.udiv, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.udiv: init i32 = call %Div.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.udiv, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 1] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 1] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 1] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 1]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 1]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -100,7 +105,7 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: <function> = name_ref Div, file.%Div [template = file.%Div]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.udiv: init i32 = call %Div.ref(%a.ref, %b.ref)
@@ -112,91 +117,98 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
-// CHECK:STDOUT:     .Sub = %Sub
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Div = %Div.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc9: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Negate.ref.loc9_18: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
-// CHECK:STDOUT:   %Negate.ref.loc9_39: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.unegate.loc9_24, %.loc9_17.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.unegate.loc9_45, %.loc9_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.udiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.udiv.loc9 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.udiv.loc9, %.loc9_49.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.unegate.loc9_24, %.loc9_17.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.unegate.loc9_45, %.loc9_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.udiv.loc9: init i32 = call %Div.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.udiv.loc9 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.udiv.loc9, %.loc9_49.1 [template = constants.%.6]
 // CHECK:STDOUT:   %a.loc9: i32 = bind_name a, %.loc9_49.2
-// CHECK:STDOUT:   %Div.ref.loc12: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Sub.ref.loc12: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.unegate.loc12, %.loc12_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.usub.loc12, %.loc12_17.1 [template = constants.%.6]
-// CHECK:STDOUT:   %int.udiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.udiv.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.udiv.loc12, %.loc12_49.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Div.ref.loc12: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.unegate.loc12, %.loc12_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.usub.loc12, %.loc12_17.1 [template = constants.%.7]
+// CHECK:STDOUT:   %int.udiv.loc12: init i32 = call %Div.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.udiv.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.udiv.loc12, %.loc12_49.1 [template = constants.%.7]
 // CHECK:STDOUT:   %b.loc12: i32 = bind_name b, %.loc12_49.2
-// CHECK:STDOUT:   %Div.ref.loc15: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %Sub.ref.loc15: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc15_22: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc15_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.unegate.loc15_28, %.loc15_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_21.2, %.loc15_43) [template = constants.%.6]
-// CHECK:STDOUT:   %Negate.ref.loc15_47: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc15_54: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_17.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc15_17.2: i32 = converted %int.usub.loc15, %.loc15_17.1 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc15_17.3: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_17.4: i32 = converted %int.unegate.loc15_53, %.loc15_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_17.2, %.loc15_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.udiv.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.udiv.loc15, %.loc15_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc15: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc15_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc15_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.unegate.loc15_28, %.loc15_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_21.2, %.loc15_43) [template = constants.%.7]
+// CHECK:STDOUT:   %Negate.ref.loc15_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc15_54: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_17.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc15_17.2: i32 = converted %int.usub.loc15, %.loc15_17.1 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc15_17.3: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_17.4: i32 = converted %int.unegate.loc15_53, %.loc15_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_17.2, %.loc15_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.udiv.loc15 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.udiv.loc15, %.loc15_57.1 [template = constants.%.6]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -209,33 +221,36 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Div = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Div = %Div
+// CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div: <function> = fn_decl @Div [template] {
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc10: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc10_18: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.udiv.loc10: init i32 = call %Div.ref.loc10(%.loc10_18, %.loc10_21) [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.1: i32 = value_of_initializer %int.udiv.loc10 [template = <error>]
 // CHECK:STDOUT:   %.loc10_23.2: i32 = converted %int.udiv.loc10, %.loc10_23.1 [template = <error>]
 // CHECK:STDOUT:   %a.loc10: i32 = bind_name a, %.loc10_23.2
-// CHECK:STDOUT:   %Div.ref.loc15: <function> = name_ref Div, %Div [template = %Div]
-// CHECK:STDOUT:   %.loc15_18: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc15_18: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.udiv.loc15: init i32 = call %Div.ref.loc15(%.loc15_18, %.loc15_21) [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.1: i32 = value_of_initializer %int.udiv.loc15 [template = <error>]
 // CHECK:STDOUT:   %.loc15_23.2: i32 = converted %int.udiv.loc15, %.loc15_23.1 [template = <error>]

+ 103 - 88
toolchain/check/testdata/builtins/int/umod.carbon

@@ -54,42 +54,47 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 2] [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 2] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
+// CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 5 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 3 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.umod, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 5 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 3 [template = constants.%.3]
+// CHECK:STDOUT:   %int.umod: init i32 = call %Mod.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.umod, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 2] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 2] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 2] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 2] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 2] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 2]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 2]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -102,7 +107,7 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mod.ref: <function> = name_ref Mod, file.%Mod [template = file.%Mod]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.umod: init i32 = call %Mod.ref(%a.ref, %b.ref)
@@ -114,91 +119,98 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
-// CHECK:STDOUT:     .Sub = %Sub
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Mod = %Mod.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc9: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Negate.ref.loc9_18: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.2]
-// CHECK:STDOUT:   %Negate.ref.loc9_39: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.unegate.loc9_24, %.loc9_17.1 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.unegate.loc9_45, %.loc9_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.umod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.umod.loc9 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.umod.loc9, %.loc9_49.1 [template = constants.%.2]
+// CHECK:STDOUT:   %Mod.ref.loc9: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_25: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc9_24: init i32 = call %Negate.ref.loc9_18(%.loc9_25) [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_46: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.unegate.loc9_45: init i32 = call %Negate.ref.loc9_39(%.loc9_46) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.1: i32 = value_of_initializer %int.unegate.loc9_24 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.2: i32 = converted %int.unegate.loc9_24, %.loc9_17.1 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_17.3: i32 = value_of_initializer %int.unegate.loc9_45 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_17.4: i32 = converted %int.unegate.loc9_45, %.loc9_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.umod.loc9: init i32 = call %Mod.ref.loc9(%.loc9_17.2, %.loc9_17.4) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_49.1: i32 = value_of_initializer %int.umod.loc9 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc9_49.2: i32 = converted %int.umod.loc9, %.loc9_49.1 [template = constants.%.3]
 // CHECK:STDOUT:   %a.loc9: i32 = bind_name a, %.loc9_49.2
-// CHECK:STDOUT:   %Mod.ref.loc12: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Sub.ref.loc12: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc12: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.unegate.loc12, %.loc12_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.usub.loc12, %.loc12_17.1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.umod.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.umod.loc12, %.loc12_49.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc12_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc12: init i32 = call %Negate.ref.loc12(%.loc12_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_21.1: i32 = value_of_initializer %int.unegate.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_21.2: i32 = converted %int.unegate.loc12, %.loc12_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc12: init i32 = call %Sub.ref.loc12(%.loc12_21.2, %.loc12_43) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_47: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc12_17.1: i32 = value_of_initializer %int.usub.loc12 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc12_17.2: i32 = converted %int.usub.loc12, %.loc12_17.1 [template = constants.%.6]
+// CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_17.2, %.loc12_47) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_49.1: i32 = value_of_initializer %int.umod.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_49.2: i32 = converted %int.umod.loc12, %.loc12_49.1 [template = constants.%.7]
 // CHECK:STDOUT:   %b.loc12: i32 = bind_name b, %.loc12_49.2
-// CHECK:STDOUT:   %Mod.ref.loc15: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %Sub.ref.loc15: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc15_22: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc15_29: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_43: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.unegate.loc15_28, %.loc15_21.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_21.2, %.loc15_43) [template = constants.%.5]
-// CHECK:STDOUT:   %Negate.ref.loc15_47: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc15_54: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_17.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_17.2: i32 = converted %int.usub.loc15, %.loc15_17.1 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_17.3: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc15_17.4: i32 = converted %int.unegate.loc15_53, %.loc15_17.3 [template = constants.%.4]
-// CHECK:STDOUT:   %int.umod.loc15: init i32 = call %Mod.ref.loc15(%.loc15_17.2, %.loc15_17.4) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.umod.loc15 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.umod.loc15, %.loc15_57.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mod.ref.loc15: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref.loc15: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc15_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc15_29: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc15_28: init i32 = call %Negate.ref.loc15_22(%.loc15_29) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_43: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc15_21.1: i32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc15_21.2: i32 = converted %int.unegate.loc15_28, %.loc15_21.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc15: init i32 = call %Sub.ref.loc15(%.loc15_21.2, %.loc15_43) [template = constants.%.6]
+// CHECK:STDOUT:   %Negate.ref.loc15_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc15_54: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.unegate.loc15_53: init i32 = call %Negate.ref.loc15_47(%.loc15_54) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_17.1: i32 = value_of_initializer %int.usub.loc15 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_17.2: i32 = converted %int.usub.loc15, %.loc15_17.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_17.3: i32 = value_of_initializer %int.unegate.loc15_53 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc15_17.4: i32 = converted %int.unegate.loc15_53, %.loc15_17.3 [template = constants.%.5]
+// CHECK:STDOUT:   %int.umod.loc15: init i32 = call %Mod.ref.loc15(%.loc15_17.2, %.loc15_17.4) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_57.1: i32 = value_of_initializer %int.umod.loc15 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc15_57.2: i32 = converted %int.umod.loc15, %.loc15_57.1 [template = constants.%.6]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -211,33 +223,36 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Mod = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mod = %Mod
+// CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod: <function> = fn_decl @Mod [template] {
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc12: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc12_18: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc12_18: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc12_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.umod.loc12: init i32 = call %Mod.ref.loc12(%.loc12_18, %.loc12_21) [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.1: i32 = value_of_initializer %int.umod.loc12 [template = <error>]
 // CHECK:STDOUT:   %.loc12_23.2: i32 = converted %int.umod.loc12, %.loc12_23.1 [template = <error>]
 // CHECK:STDOUT:   %a.loc12: i32 = bind_name a, %.loc12_23.2
-// CHECK:STDOUT:   %Mod.ref.loc17: <function> = name_ref Mod, %Mod [template = %Mod]
-// CHECK:STDOUT:   %.loc17_18: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %Mod.ref.loc17: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc17_18: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 0 [template = constants.%.3]
 // CHECK:STDOUT:   %int.umod.loc17: init i32 = call %Mod.ref.loc17(%.loc17_18, %.loc17_21) [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.1: i32 = value_of_initializer %int.umod.loc17 [template = <error>]
 // CHECK:STDOUT:   %.loc17_23.2: i32 = converted %int.umod.loc17, %.loc17_23.1 [template = <error>]

+ 45 - 37
toolchain/check/testdata/builtins/int/umul.carbon

@@ -27,42 +27,47 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- int_mul.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 6 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Mul = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mul = %Mul
+// CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul: <function> = fn_decl @Mul [template] {
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.umul, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.umul: init i32 = call %Mul.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.umul, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 6] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 6] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 6] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 6]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 6]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -75,7 +80,7 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: <function> = name_ref Mul, file.%Mul [template = file.%Mul]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.umul: init i32 = call %Mul.ref(%a.ref, %b.ref)
@@ -87,39 +92,42 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 32767 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 65536 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 2147418112 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 32768 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Mul = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 32767 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 65536 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 2147418112 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 32768 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Mul = %Mul
+// CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul: <function> = fn_decl @Mul [template] {
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref.loc6: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 32767 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_26: i32 = int_literal 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.umul.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.umul.loc6, %.loc6_34.1 [template = constants.%.3]
+// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 32767 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_26: i32 = int_literal 65536 [template = constants.%.3]
+// CHECK:STDOUT:   %int.umul.loc6: init i32 = call %Mul.ref.loc6(%.loc6_18, %.loc6_26) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_34.1: i32 = value_of_initializer %int.umul.loc6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_34.2: i32 = converted %int.umul.loc6, %.loc6_34.1 [template = constants.%.4]
 // CHECK:STDOUT:   %a.loc6: i32 = bind_name a, %.loc6_34.2
-// CHECK:STDOUT:   %Mul.ref.loc7: <function> = name_ref Mul, %Mul [template = %Mul]
-// CHECK:STDOUT:   %.loc7_18: i32 = int_literal 32768 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 65536 [template = constants.%.2]
-// CHECK:STDOUT:   %int.umul.loc7: init i32 = call %Mul.ref.loc7(%.loc7_18, %.loc7_26) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_34.1: i32 = value_of_initializer %int.umul.loc7 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_34.2: i32 = converted %int.umul.loc7, %.loc7_34.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Mul.ref.loc7: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc7_18: i32 = int_literal 32768 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 65536 [template = constants.%.3]
+// CHECK:STDOUT:   %int.umul.loc7: init i32 = call %Mul.ref.loc7(%.loc7_18, %.loc7_26) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_34.1: i32 = value_of_initializer %int.umul.loc7 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_34.2: i32 = converted %int.umul.loc7, %.loc7_34.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc7: i32 = bind_name b, %.loc7_34.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 111 - 86
toolchain/check/testdata/builtins/int/unegate.carbon

@@ -111,50 +111,55 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 123 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -123 [template]
-// CHECK:STDOUT:   %.3: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.4: type = ptr_type [i32; 123] [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 123 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -123 [template]
+// CHECK:STDOUT:   %.4: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.5: type = ptr_type [i32; 123] [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal -1 [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
+// CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc2_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref.loc4_16: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Negate.ref.loc4_23: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc4_30: i32 = int_literal 123 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_22.1: i32 = value_of_initializer %int.unegate.loc4_29 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc4_22.2: i32 = converted %int.unegate.loc4_29, %.loc4_22.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.unegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_22.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_35: type = array_type %int.unegate.loc4_22, i32 [template = constants.%.3]
+// CHECK:STDOUT:   %Negate.ref.loc4_16: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc4_23: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_30: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc4_29: init i32 = call %Negate.ref.loc4_23(%.loc4_30) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_22.1: i32 = value_of_initializer %int.unegate.loc4_29 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc4_22.2: i32 = converted %int.unegate.loc4_29, %.loc4_22.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.unegate.loc4_22: init i32 = call %Negate.ref.loc4_16(%.loc4_22.2) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_35: type = array_type %int.unegate.loc4_22, i32 [template = constants.%.4]
 // CHECK:STDOUT:   %arr.var: ref [i32; 123] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 123] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_22: type = ptr_type [i32; 123] [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc5_21: type = array_type %.loc5_18, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_22: type = ptr_type [i32; 123] [template = constants.%.5]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 123] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_26: [i32; 123]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 123]* = bind_name arr_p, %.loc5_26
-// CHECK:STDOUT:   %Negate.ref.loc7: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc7_21: i32 = int_literal 1 [template = constants.%.5]
-// CHECK:STDOUT:   %int.unegate.loc7: init i32 = call %Negate.ref.loc7(%.loc7_21) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.unegate.loc7 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.unegate.loc7, %.loc7_23.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Negate.ref.loc7: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc7_21: i32 = int_literal 1 [template = constants.%.6]
+// CHECK:STDOUT:   %int.unegate.loc7: init i32 = call %Negate.ref.loc7(%.loc7_21) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_23.1: i32 = value_of_initializer %int.unegate.loc7 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_23.2: i32 = converted %int.unegate.loc7, %.loc7_23.1 [template = constants.%.7]
 // CHECK:STDOUT:   %n: i32 = bind_name n, %.loc7_23.2
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc9_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc9_16.1
 // CHECK:STDOUT:     %b.loc9_24.1: i32 = param b
@@ -167,7 +172,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: <function> = name_ref Negate, file.%Negate [template = file.%Negate]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %int.unegate: init i32 = call %Negate.ref(%a.ref)
 // CHECK:STDOUT:   %.loc10_19.1: i32 = value_of_initializer %int.unegate
@@ -178,74 +183,89 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
+// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
+// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
+// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .TooFew = %TooFew
-// CHECK:STDOUT:     .TooMany = %TooMany
-// CHECK:STDOUT:     .BadReturnType = %BadReturnType
-// CHECK:STDOUT:     .JustRight = %JustRight
+// CHECK:STDOUT:     .TooFew = %TooFew.decl
+// CHECK:STDOUT:     .TooMany = %TooMany.decl
+// CHECK:STDOUT:     .BadReturnType = %BadReturnType.decl
+// CHECK:STDOUT:     .JustRight = %JustRight.decl
 // CHECK:STDOUT:     .too_few = %too_few
 // CHECK:STDOUT:     .too_many = %too_many
 // CHECK:STDOUT:     .bad_return_type = %bad_return_type
 // CHECK:STDOUT:     .bad_call = %bad_call
-// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew
-// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany
-// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType
+// CHECK:STDOUT:     .RuntimeCallTooFew = %RuntimeCallTooFew.decl
+// CHECK:STDOUT:     .RuntimeCallTooMany = %RuntimeCallTooMany.decl
+// CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew: <function> = fn_decl @TooFew [template] {
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany: <function> = fn_decl @TooMany [template] {
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType: <function> = fn_decl @BadReturnType [template] {
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight: <function> = fn_decl @JustRight [template] {
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, %TooFew [template = %TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref()
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // CHECK:STDOUT:   %too_few: ref <error> = bind_name too_few, %too_few.var
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, %TooMany [template = %TooMany]
-// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc30_29: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_32: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %TooMany.call: init i32 = call %TooMany.ref(%.loc30_29, %.loc30_32)
 // CHECK:STDOUT:   %too_many.var: ref <error> = var too_many
 // CHECK:STDOUT:   %too_many: ref <error> = bind_name too_many, %too_many.var
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, %BadReturnType [template = %BadReturnType]
-// CHECK:STDOUT:   %.loc35: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc35: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(%.loc35)
 // CHECK:STDOUT:   %bad_return_type.var: ref <error> = var bad_return_type
 // CHECK:STDOUT:   %bad_return_type: ref <error> = bind_name bad_return_type, %bad_return_type.var
-// CHECK:STDOUT:   %JustRight.ref: <function> = name_ref JustRight, %JustRight [template = %JustRight]
-// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc44_31: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc44_34: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %int.unegate: init i32 = call %JustRight.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc44_36: type = array_type %int.unegate, i32 [template = <error>]
 // CHECK:STDOUT:   %bad_call.var: ref <error> = var bad_call
 // CHECK:STDOUT:   %bad_call: ref <error> = bind_name bad_call, %bad_call.var
-// CHECK:STDOUT:   %RuntimeCallTooFew: <function> = fn_decl @RuntimeCallTooFew [template] {
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany: <function> = fn_decl @RuntimeCallTooMany [template] {
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
 // CHECK:STDOUT:     %a.loc57_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc57_23.1
 // CHECK:STDOUT:     %b.loc57_31.1: i32 = param b
@@ -254,7 +274,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc57_39.1
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType: <function> = fn_decl @RuntimeCallBadReturnType [template] {
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
 // CHECK:STDOUT:     %a.loc68_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc68_29.1
 // CHECK:STDOUT:     %b.loc68_37.1: i32 = param b
@@ -273,7 +293,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: <function> = name_ref TooFew, file.%TooFew [template = file.%TooFew]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %TooFew.call: init i32 = call %TooFew.ref(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %.loc54_19.1: i32 = value_of_initializer %TooFew.call [template = <error>]
@@ -283,7 +303,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooMany(%a: i32, %b: i32, %c: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooMany.ref: <function> = name_ref TooMany, file.%TooMany [template = file.%TooMany]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %c.ref: i32 = name_ref c, %c
@@ -295,7 +315,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a: i32, %b: i32) -> bool {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %BadReturnType.ref: <function> = name_ref BadReturnType, file.%BadReturnType [template = file.%BadReturnType]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %BadReturnType.call: init bool = call %BadReturnType.ref(<invalid>) [template = <error>]
@@ -307,55 +327,60 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Negate = %Negate
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Negate = %Negate.decl
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate: <function> = fn_decl @Negate [template] {
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc4_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc4_11.1
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref.loc8_14: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Negate.ref.loc8_21: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc8_28: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_20.1: i32 = value_of_initializer %int.unegate.loc8_27 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_20.2: i32 = converted %int.unegate.loc8_27, %.loc8_20.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.unegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_20.2) [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.unegate.loc8_20 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.unegate.loc8_20, %.loc8_40.1 [template = constants.%.1]
+// CHECK:STDOUT:   %Negate.ref.loc8_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref.loc8_21: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc8_28: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc8_27: init i32 = call %Negate.ref.loc8_21(%.loc8_28) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_20.1: i32 = value_of_initializer %int.unegate.loc8_27 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_20.2: i32 = converted %int.unegate.loc8_27, %.loc8_20.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.unegate.loc8_20: init i32 = call %Negate.ref.loc8_14(%.loc8_20.2) [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.unegate.loc8_20 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.unegate.loc8_20, %.loc8_40.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a.loc8: i32 = bind_name a, %.loc8_40.2
-// CHECK:STDOUT:   %Negate.ref.loc11_14: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Negate.ref.loc11_25: <function> = name_ref Negate, %Negate [template = %Negate]
-// CHECK:STDOUT:   %.loc11_32: i32 = int_literal 2147483647 [template = constants.%.1]
-// CHECK:STDOUT:   %int.unegate.loc11_31: init i32 = call %Negate.ref.loc11_25(%.loc11_32) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_45: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc11_24.1: i32 = value_of_initializer %int.unegate.loc11_31 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc11_24.2: i32 = converted %int.unegate.loc11_31, %.loc11_24.1 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc11_24.2, %.loc11_45) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_20.1: i32 = value_of_initializer %int.usub [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_20.2: i32 = converted %int.usub, %.loc11_20.1 [template = constants.%.4]
-// CHECK:STDOUT:   %int.unegate.loc11_20: init i32 = call %Negate.ref.loc11_14(%.loc11_20.2) [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_48.1: i32 = value_of_initializer %int.unegate.loc11_20 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_48.2: i32 = converted %int.unegate.loc11_20, %.loc11_48.1 [template = constants.%.4]
+// CHECK:STDOUT:   %Negate.ref.loc11_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc11_25: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc11_32: i32 = int_literal 2147483647 [template = constants.%.2]
+// CHECK:STDOUT:   %int.unegate.loc11_31: init i32 = call %Negate.ref.loc11_25(%.loc11_32) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_45: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_24.1: i32 = value_of_initializer %int.unegate.loc11_31 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc11_24.2: i32 = converted %int.unegate.loc11_31, %.loc11_24.1 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc11_24.2, %.loc11_45) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_20.1: i32 = value_of_initializer %int.usub [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_20.2: i32 = converted %int.usub, %.loc11_20.1 [template = constants.%.5]
+// CHECK:STDOUT:   %int.unegate.loc11_20: init i32 = call %Negate.ref.loc11_14(%.loc11_20.2) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_48.1: i32 = value_of_initializer %int.unegate.loc11_20 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_48.2: i32 = converted %int.unegate.loc11_20, %.loc11_48.1 [template = constants.%.5]
 // CHECK:STDOUT:   %b.loc11: i32 = bind_name b, %.loc11_48.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 62 - 54
toolchain/check/testdata/builtins/int/usub.carbon

@@ -28,42 +28,47 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- int_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_25: type = array_type %int.usub, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_23: i32 = int_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%.loc4_20, %.loc4_23) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_25: type = array_type %int.usub, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 1] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 1] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 1] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 1] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 1]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 1]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -76,7 +81,7 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: <function> = name_ref Sub, file.%Sub [template = file.%Sub]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.usub: init i32 = call %Sub.ref(%a.ref, %b.ref)
@@ -88,57 +93,60 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2147483647 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal -2147483647 [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal -2147483648 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Sub = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2147483647 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal -2147483647 [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal -2147483648 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Sub = %Sub
+// CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub: <function> = fn_decl @Sub [template] {
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct] {
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc4_8.1
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc4_16.1
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref.loc6: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc6_21: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.usub.loc6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.usub.loc6, %.loc6_32.1 [template = constants.%.3]
+// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc6_18: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc6_21: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc6: init i32 = call %Sub.ref.loc6(%.loc6_18, %.loc6_21) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_32.1: i32 = value_of_initializer %int.usub.loc6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc6_32.2: i32 = converted %int.usub.loc6, %.loc6_32.1 [template = constants.%.4]
 // CHECK:STDOUT:   %a.loc6: i32 = bind_name a, %.loc6_32.2
-// CHECK:STDOUT:   %Sub.ref.loc7_14: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Sub.ref.loc7_18: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc7_22: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_25: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_17.1: i32 = value_of_initializer %int.usub.loc7_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc7_17.2: i32 = converted %int.usub.loc7_21, %.loc7_17.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.usub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_17.2, %.loc7_38) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.usub.loc7_17 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.usub.loc7_17, %.loc7_40.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Sub.ref.loc7_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %Sub.ref.loc7_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc7_22: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_25: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc7_21: init i32 = call %Sub.ref.loc7_18(%.loc7_22, %.loc7_25) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_17.1: i32 = value_of_initializer %int.usub.loc7_21 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_17.2: i32 = converted %int.usub.loc7_21, %.loc7_17.1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.usub.loc7_17: init i32 = call %Sub.ref.loc7_14(%.loc7_17.2, %.loc7_38) [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_40.1: i32 = value_of_initializer %int.usub.loc7_17 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_40.2: i32 = converted %int.usub.loc7_17, %.loc7_40.1 [template = constants.%.6]
 // CHECK:STDOUT:   %b.loc7: i32 = bind_name b, %.loc7_40.2
-// CHECK:STDOUT:   %Sub.ref.loc8_14: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %Sub.ref.loc8_18: <function> = name_ref Sub, %Sub [template = %Sub]
-// CHECK:STDOUT:   %.loc8_22: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_25: i32 = int_literal 2147483647 [template = constants.%.2]
-// CHECK:STDOUT:   %int.usub.loc8_21: init i32 = call %Sub.ref.loc8_18(%.loc8_22, %.loc8_25) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_38: i32 = int_literal 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc8_17.1: i32 = value_of_initializer %int.usub.loc8_21 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc8_17.2: i32 = converted %int.usub.loc8_21, %.loc8_17.1 [template = constants.%.3]
-// CHECK:STDOUT:   %int.usub.loc8_17: init i32 = call %Sub.ref.loc8_14(%.loc8_17.2, %.loc8_38) [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.usub.loc8_17 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.usub.loc8_17, %.loc8_40.1 [template = constants.%.2]
+// CHECK:STDOUT:   %Sub.ref.loc8_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %Sub.ref.loc8_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %.loc8_22: i32 = int_literal 0 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_25: i32 = int_literal 2147483647 [template = constants.%.3]
+// CHECK:STDOUT:   %int.usub.loc8_21: init i32 = call %Sub.ref.loc8_18(%.loc8_22, %.loc8_25) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_38: i32 = int_literal 2 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc8_17.1: i32 = value_of_initializer %int.usub.loc8_21 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_17.2: i32 = converted %int.usub.loc8_21, %.loc8_17.1 [template = constants.%.4]
+// CHECK:STDOUT:   %int.usub.loc8_17: init i32 = call %Sub.ref.loc8_14(%.loc8_17.2, %.loc8_38) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_40.1: i32 = value_of_initializer %int.usub.loc8_17 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_40.2: i32 = converted %int.usub.loc8_17, %.loc8_40.1 [template = constants.%.3]
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc8_40.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 23 - 18
toolchain/check/testdata/builtins/int/xor.carbon

@@ -18,42 +18,47 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_xor.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 12 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 10 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 6 [template]
-// CHECK:STDOUT:   %.4: type = array_type %.3, i32 [template]
-// CHECK:STDOUT:   %.5: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %Xor: type = fn_type @Xor [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Xor = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 12 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 10 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.5: type = array_type %.4, i32 [template]
+// CHECK:STDOUT:   %.6: type = ptr_type [i32; 6] [template]
+// CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
+// CHECK:STDOUT:   %struct.2: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .Xor = %Xor
+// CHECK:STDOUT:     .Xor = %Xor.decl
 // CHECK:STDOUT:     .arr = %arr
-// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall
+// CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Xor: <function> = fn_decl @Xor [template] {
+// CHECK:STDOUT:   %Xor.decl: Xor = fn_decl @Xor [template = constants.%struct.1] {
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Xor.%a: i32 = bind_name a, %a.loc2_8.1
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Xor.%b: i32 = bind_name b, %b.loc2_16.1
 // CHECK:STDOUT:     @Xor.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Xor.ref: <function> = name_ref Xor, %Xor [template = %Xor]
-// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 12 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc4_24: i32 = int_literal 10 [template = constants.%.2]
-// CHECK:STDOUT:   %int.xor: init i32 = call %Xor.ref(%.loc4_20, %.loc4_24) [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_27: type = array_type %int.xor, i32 [template = constants.%.4]
+// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, %Xor.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc4_20: i32 = int_literal 12 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc4_24: i32 = int_literal 10 [template = constants.%.3]
+// CHECK:STDOUT:   %int.xor: init i32 = call %Xor.ref(%.loc4_20, %.loc4_24) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_27: type = array_type %int.xor, i32 [template = constants.%.5]
 // CHECK:STDOUT:   %arr.var: ref [i32; 6] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 6] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_19: type = array_type %.loc5_18, i32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc5_20: type = ptr_type [i32; 6] [template = constants.%.6]
 // CHECK:STDOUT:   %arr.ref: ref [i32; 6] = name_ref arr, %arr
 // CHECK:STDOUT:   %.loc5_24: [i32; 6]* = addr_of %arr.ref
 // CHECK:STDOUT:   %arr_p: [i32; 6]* = bind_name arr_p, %.loc5_24
-// CHECK:STDOUT:   %RuntimeCall: <function> = fn_decl @RuntimeCall [template] {
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
@@ -66,7 +71,7 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Xor.ref: <function> = name_ref Xor, file.%Xor [template = file.%Xor]
+// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, file.%Xor.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %a.ref: i32 = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: i32 = name_ref b, %b
 // CHECK:STDOUT:   %int.xor: init i32 = call %Xor.ref(%a.ref, %b.ref)

+ 10 - 6
toolchain/check/testdata/class/adapt.carbon

@@ -95,10 +95,14 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Adapted: type = class_type @Adapted [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %AdaptNotExtend: type = class_type @AdaptNotExtend [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -106,12 +110,12 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Adapted = %Adapted.decl
 // CHECK:STDOUT:     .AdaptNotExtend = %AdaptNotExtend.decl
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Adapted.decl: type = class_decl @Adapted [template = constants.%Adapted] {}
 // CHECK:STDOUT:   %AdaptNotExtend.decl: type = class_decl @AdaptNotExtend [template = constants.%AdaptNotExtend] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.2] {
 // CHECK:STDOUT:     %AdaptNotExtend.ref: type = name_ref AdaptNotExtend, %AdaptNotExtend.decl [template = constants.%AdaptNotExtend]
 // CHECK:STDOUT:     %a.loc12_6.1: AdaptNotExtend = param a
 // CHECK:STDOUT:     @F.2.%a: AdaptNotExtend = bind_name a, %a.loc12_6.1
@@ -119,11 +123,11 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Adapted {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Adapted
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @AdaptNotExtend {

+ 29 - 24
toolchain/check/testdata/class/base.carbon

@@ -33,17 +33,22 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.4: type = unbound_element_type Derived, Base [template]
 // CHECK:STDOUT:   %.5: type = unbound_element_type Derived, i32 [template]
 // CHECK:STDOUT:   %.6: type = struct_type {.base: Base, .d: i32} [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: {.b: i32}*, .d: i32} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type {.base: {.b: i32}*, .d: i32} [template]
-// CHECK:STDOUT:   %.9: type = ptr_type {.base: Base, .d: i32} [template]
-// CHECK:STDOUT:   %.10: i32 = int_literal 4 [template]
-// CHECK:STDOUT:   %.11: i32 = int_literal 7 [template]
-// CHECK:STDOUT:   %.12: type = struct_type {.base: {.b: i32}, .d: i32} [template]
-// CHECK:STDOUT:   %struct.1: Base = struct_value (%.10) [template]
-// CHECK:STDOUT:   %struct.2: Derived = struct_value (%struct.1, %.11) [template]
-// CHECK:STDOUT:   %.13: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.14: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.15: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %Make: type = fn_type @Make [template]
+// CHECK:STDOUT:   %.7: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Make = struct_value () [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.base: {.b: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type {.base: {.b: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.10: type = ptr_type {.base: Base, .d: i32} [template]
+// CHECK:STDOUT:   %.11: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.12: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.13: type = struct_type {.base: {.b: i32}, .d: i32} [template]
+// CHECK:STDOUT:   %struct.2: Base = struct_value (%.11) [template]
+// CHECK:STDOUT:   %struct.3: Derived = struct_value (%struct.2, %.12) [template]
+// CHECK:STDOUT:   %.14: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.15: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %Access: type = fn_type @Access [template]
+// CHECK:STDOUT:   %struct.4: Access = struct_value () [template]
+// CHECK:STDOUT:   %.16: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -51,22 +56,22 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Base = %Base.decl
 // CHECK:STDOUT:     .Derived = %Derived.decl
-// CHECK:STDOUT:     .Make = %Make
-// CHECK:STDOUT:     .Access = %Access
+// CHECK:STDOUT:     .Make = %Make.decl
+// CHECK:STDOUT:     .Access = %Access.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template] {
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Derived.ref.loc17: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     @Make.%return: ref Derived = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template] {
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct.4] {
 // CHECK:STDOUT:     %Derived.ref.loc21: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %d.loc21_11.1: Derived = param d
 // CHECK:STDOUT:     @Access.%d: Derived = bind_name d, %d.loc21_11.1
 // CHECK:STDOUT:     %.loc21_35.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:     %.loc21_35.2: type = converted %.loc21_35.1, constants.%.14 [template = constants.%.14]
+// CHECK:STDOUT:     %.loc21_35.2: type = converted %.loc21_35.1, constants.%.15 [template = constants.%.15]
 // CHECK:STDOUT:     @Access.%return: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -93,19 +98,19 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc18_26.1: {.b: i32} = struct_literal (%.loc18_25)
-// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc18_35.1: {.base: {.b: i32}, .d: i32} = struct_literal (%.loc18_26.1, %.loc18_34)
 // CHECK:STDOUT:   %.loc18_35.2: ref Base = class_element_access %return, element0
 // CHECK:STDOUT:   %.loc18_26.2: ref i32 = class_element_access %.loc18_35.2, element0
-// CHECK:STDOUT:   %.loc18_26.3: init i32 = initialize_from %.loc18_25 to %.loc18_26.2 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc18_26.4: init Base = class_init (%.loc18_26.3), %.loc18_35.2 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc18_35.3: init Base = converted %.loc18_26.1, %.loc18_26.4 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc18_26.3: init i32 = initialize_from %.loc18_25 to %.loc18_26.2 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc18_26.4: init Base = class_init (%.loc18_26.3), %.loc18_35.2 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc18_35.3: init Base = converted %.loc18_26.1, %.loc18_26.4 [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc18_35.4: ref i32 = class_element_access %return, element1
-// CHECK:STDOUT:   %.loc18_35.5: init i32 = initialize_from %.loc18_34 to %.loc18_35.4 [template = constants.%.11]
-// CHECK:STDOUT:   %.loc18_35.6: init Derived = class_init (%.loc18_35.3, %.loc18_35.5), %return [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc18_36: init Derived = converted %.loc18_35.1, %.loc18_35.6 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc18_35.5: init i32 = initialize_from %.loc18_34 to %.loc18_35.4 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc18_35.6: init Derived = class_init (%.loc18_35.3, %.loc18_35.5), %return [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc18_36: init Derived = converted %.loc18_35.1, %.loc18_35.6 [template = constants.%struct.3]
 // CHECK:STDOUT:   return %.loc18_36 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 5
toolchain/check/testdata/class/base_field.carbon

@@ -34,9 +34,12 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:   %.6: type = struct_type {.base: Base, .d: i32, .e: i32} [template]
 // CHECK:STDOUT:   %.7: type = ptr_type Derived [template]
 // CHECK:STDOUT:   %.8: type = ptr_type i32 [template]
-// CHECK:STDOUT:   %.9: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.10: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.11: type = ptr_type {.base: Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %Access: type = fn_type @Access [template]
+// CHECK:STDOUT:   %.9: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Access = struct_value () [template]
+// CHECK:STDOUT:   %.10: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.11: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.12: type = ptr_type {.base: Base, .d: i32, .e: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -44,12 +47,12 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Base = %Base.decl
 // CHECK:STDOUT:     .Derived = %Derived.decl
-// CHECK:STDOUT:     .Access = %Access
+// CHECK:STDOUT:     .Access = %Access.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template] {
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct] {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %.loc20_21: type = ptr_type Derived [template = constants.%.7]
 // CHECK:STDOUT:     %p.loc20_11.1: Derived* = param p

+ 17 - 11
toolchain/check/testdata/class/base_function_unqualified.carbon

@@ -23,11 +23,17 @@ fn Derived.H() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %H: type = fn_type @H [template]
+// CHECK:STDOUT:   %struct.3: H = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = struct_type {.base: Base} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -40,28 +46,28 @@ fn Derived.H() {
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %H: <function> = fn_decl @H [template] {}
+// CHECK:STDOUT:   %H.decl: H = fn_decl @H [template = constants.%struct.3] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc12: <unbound element of class Derived> = base_decl Base, element0 [template]
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {}
-// CHECK:STDOUT:   %H: <function> = fn_decl @H [template] {}
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %H.decl: H = fn_decl @H [template = constants.%struct.3] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
-// CHECK:STDOUT:   .G = %G
-// CHECK:STDOUT:   .H = %H
+// CHECK:STDOUT:   .G = %G.decl
+// CHECK:STDOUT:   .H = %H.decl
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -69,14 +75,14 @@ fn Derived.H() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %F.call: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @H() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %F.call: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 22 - 18
toolchain/check/testdata/class/base_method.carbon

@@ -28,16 +28,20 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %.1: type = unbound_element_type Base, i32 [template]
 // CHECK:STDOUT:   %.2: type = ptr_type Base [template]
-// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32} [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.5: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.6: type = unbound_element_type Derived, Base [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: Base} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type Derived [template]
-// CHECK:STDOUT:   %.9: type = struct_type {.base: {.a: i32}*} [template]
-// CHECK:STDOUT:   %.10: type = ptr_type {.base: Base} [template]
-// CHECK:STDOUT:   %.11: type = tuple_type () [template]
+// CHECK:STDOUT:   %.7: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.base: Base} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type Derived [template]
+// CHECK:STDOUT:   %Call: type = fn_type @Call [template]
+// CHECK:STDOUT:   %struct.2: Call = struct_value () [template]
+// CHECK:STDOUT:   %.10: type = struct_type {.base: {.a: i32}*} [template]
+// CHECK:STDOUT:   %.11: type = ptr_type {.base: Base} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -45,11 +49,11 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Base = %Base.decl
 // CHECK:STDOUT:     .Derived = %Derived.decl
-// CHECK:STDOUT:     .Call = %Call
+// CHECK:STDOUT:     .Call = %Call.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Base.ref: type = name_ref Base, %Base.decl [template = constants.%Base]
 // CHECK:STDOUT:     %.loc13_26: type = ptr_type Base [template = constants.%.2]
 // CHECK:STDOUT:     %self.loc13_16.1: Base* = param self
@@ -57,9 +61,9 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:     @F.%.loc13: Base* = addr_pattern @F.%self
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template] {
+// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:     %.loc21: type = ptr_type Derived [template = constants.%.8]
+// CHECK:STDOUT:     %.loc21: type = ptr_type Derived [template = constants.%.9]
 // CHECK:STDOUT:     %p.loc21_9.1: Derived* = param p
 // CHECK:STDOUT:     @Call.%p: Derived* = bind_name p, %p.loc21_9.1
 // CHECK:STDOUT:   }
@@ -67,7 +71,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Base [template = constants.%Base]
 // CHECK:STDOUT:     %.loc10_23: type = ptr_type Base [template = constants.%.2]
 // CHECK:STDOUT:     %self.loc10_13.1: Base* = param self
@@ -78,7 +82,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .a = %.loc8
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
@@ -97,7 +101,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %.loc14_4: ref Base = deref %self.ref
 // CHECK:STDOUT:   %a.ref: <unbound element of class Base> = name_ref a, @Base.%.loc8 [template = @Base.%.loc8]
 // CHECK:STDOUT:   %.loc14_10: ref i32 = class_element_access %.loc14_4, element0
-// CHECK:STDOUT:   %.loc14_15: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc14_15: i32 = int_literal 1 [template = constants.%.6]
 // CHECK:STDOUT:   assign %.loc14_10, %.loc14_15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -106,14 +110,14 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Derived* = name_ref p, %p
 // CHECK:STDOUT:   %.loc22_4.1: ref Derived = deref %p.ref
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc22_7: <bound method> = bound_method %.loc22_4.1, %F.ref
 // CHECK:STDOUT:   %.loc22_4.2: Derived* = addr_of %.loc22_4.1
 // CHECK:STDOUT:   %.loc22_9.1: ref Derived = deref %.loc22_4.2
 // CHECK:STDOUT:   %.loc22_9.2: ref Base = class_element_access %.loc22_9.1, element0
 // CHECK:STDOUT:   %.loc22_9.3: Base* = addr_of %.loc22_9.2
 // CHECK:STDOUT:   %.loc22_9.4: Base* = converted %.loc22_4.2, %.loc22_9.3
-// CHECK:STDOUT:   %.loc22_9.5: init () = call %.loc22_7(%.loc22_9.4)
+// CHECK:STDOUT:   %F.call: init () = call %.loc22_7(%.loc22_9.4)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 50 - 34
toolchain/check/testdata/class/base_method_qualified.carbon

@@ -39,14 +39,30 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %G.1: type = fn_type @G.1 [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %G.2: type = fn_type @G.2 [template]
+// CHECK:STDOUT:   %struct.4: G = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = struct_type {.base: Base} [template]
+// CHECK:STDOUT:   %Call: type = fn_type @Call [template]
+// CHECK:STDOUT:   %struct.5: Call = struct_value () [template]
 // CHECK:STDOUT:   %.6: type = struct_type {.base: {}*} [template]
 // CHECK:STDOUT:   %.7: type = ptr_type {.base: Base} [template]
 // CHECK:STDOUT:   %.8: type = ptr_type Derived [template]
+// CHECK:STDOUT:   %CallIndirect: type = fn_type @CallIndirect [template]
+// CHECK:STDOUT:   %struct.6: CallIndirect = struct_value () [template]
+// CHECK:STDOUT:   %PassDerivedToBase: type = fn_type @PassDerivedToBase [template]
+// CHECK:STDOUT:   %struct.7: PassDerivedToBase = struct_value () [template]
+// CHECK:STDOUT:   %PassDerivedToBaseIndirect: type = fn_type @PassDerivedToBaseIndirect [template]
+// CHECK:STDOUT:   %struct.8: PassDerivedToBaseIndirect = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -54,35 +70,35 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Derived = %Derived.decl.loc7
 // CHECK:STDOUT:     .Base = %Base.decl
-// CHECK:STDOUT:     .Call = %Call
-// CHECK:STDOUT:     .CallIndirect = %CallIndirect
-// CHECK:STDOUT:     .PassDerivedToBase = %PassDerivedToBase
-// CHECK:STDOUT:     .PassDerivedToBaseIndirect = %PassDerivedToBaseIndirect
+// CHECK:STDOUT:     .Call = %Call.decl
+// CHECK:STDOUT:     .CallIndirect = %CallIndirect.decl
+// CHECK:STDOUT:     .PassDerivedToBase = %PassDerivedToBase.decl
+// CHECK:STDOUT:     .PassDerivedToBaseIndirect = %PassDerivedToBaseIndirect.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Derived.decl.loc7: type = class_decl @Derived [template = constants.%Derived] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Derived.decl.loc14: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template] {
+// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.5] {
 // CHECK:STDOUT:     %Derived.ref.loc21: type = name_ref Derived, %Derived.decl.loc7 [template = constants.%Derived]
 // CHECK:STDOUT:     %a.loc21_9.1: Derived = param a
 // CHECK:STDOUT:     @Call.%a: Derived = bind_name a, %a.loc21_9.1
 // CHECK:STDOUT:     @Call.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %CallIndirect: <function> = fn_decl @CallIndirect [template] {
+// CHECK:STDOUT:   %CallIndirect.decl: CallIndirect = fn_decl @CallIndirect [template = constants.%struct.6] {
 // CHECK:STDOUT:     %Derived.ref.loc25: type = name_ref Derived, %Derived.decl.loc7 [template = constants.%Derived]
 // CHECK:STDOUT:     %.loc25: type = ptr_type Derived [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc25_17.1: Derived* = param p
 // CHECK:STDOUT:     @CallIndirect.%p: Derived* = bind_name p, %p.loc25_17.1
 // CHECK:STDOUT:     @CallIndirect.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %PassDerivedToBase: <function> = fn_decl @PassDerivedToBase [template] {
+// CHECK:STDOUT:   %PassDerivedToBase.decl: PassDerivedToBase = fn_decl @PassDerivedToBase [template = constants.%struct.7] {
 // CHECK:STDOUT:     %Derived.ref.loc29: type = name_ref Derived, %Derived.decl.loc7 [template = constants.%Derived]
 // CHECK:STDOUT:     %a.loc29_22.1: Derived = param a
 // CHECK:STDOUT:     @PassDerivedToBase.%a: Derived = bind_name a, %a.loc29_22.1
 // CHECK:STDOUT:     @PassDerivedToBase.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %PassDerivedToBaseIndirect: <function> = fn_decl @PassDerivedToBaseIndirect [template] {
+// CHECK:STDOUT:   %PassDerivedToBaseIndirect.decl: PassDerivedToBaseIndirect = fn_decl @PassDerivedToBaseIndirect [template = constants.%struct.8] {
 // CHECK:STDOUT:     %Derived.ref.loc33: type = name_ref Derived, %Derived.decl.loc7 [template = constants.%Derived]
 // CHECK:STDOUT:     %.loc33: type = ptr_type Derived [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc33_30.1: Derived* = param p
@@ -94,12 +110,12 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc15: <unbound element of class Derived> = base_decl Base, element0 [template]
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Self.ref.loc17: type = name_ref Self, constants.%Derived [template = constants.%Derived]
 // CHECK:STDOUT:     %self.loc17_8.1: Derived = param self
 // CHECK:STDOUT:     %self.loc17_8.2: Derived = bind_name self, %self.loc17_8.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G.2 [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G.2 [template = constants.%struct.4] {
 // CHECK:STDOUT:     %Self.ref.loc18: type = name_ref Self, constants.%Derived [template = constants.%Derived]
 // CHECK:STDOUT:     %self.loc18_8.1: Derived = param self
 // CHECK:STDOUT:     %self.loc18_8.2: Derived = bind_name self, %self.loc18_8.1
@@ -108,19 +124,19 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc15
-// CHECK:STDOUT:   .F = %F
-// CHECK:STDOUT:   .G = %G
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Base [template = constants.%Base]
 // CHECK:STDOUT:     %self.loc10_8.1: Base = param self
 // CHECK:STDOUT:     %self.loc10_8.2: Base = bind_name self, %self.loc10_8.1
 // CHECK:STDOUT:     %return.var.loc10: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G.1 [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G.1 [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, file.%Derived.decl.loc7 [template = constants.%Derived]
 // CHECK:STDOUT:     %self.loc11_8.1: Derived = param self
 // CHECK:STDOUT:     %self.loc11_8.2: Derived = bind_name self, %self.loc11_8.1
@@ -129,8 +145,8 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .F = %F
-// CHECK:STDOUT:   .G = %G
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1[@Base.%self.loc10_8.2: Base]() -> i32;
@@ -145,14 +161,14 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: Derived = name_ref a, %a
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc22_11: <bound method> = bound_method %a.ref, %F.ref
 // CHECK:STDOUT:   %.loc22_20.1: ref Base = class_element_access %a.ref, element0
 // CHECK:STDOUT:   %.loc22_20.2: ref Base = converted %a.ref, %.loc22_20.1
 // CHECK:STDOUT:   %.loc22_20.3: Base = bind_value %.loc22_20.2
-// CHECK:STDOUT:   %.loc22_20.4: init i32 = call %.loc22_11(%.loc22_20.3)
-// CHECK:STDOUT:   %.loc22_22.1: i32 = value_of_initializer %.loc22_20.4
-// CHECK:STDOUT:   %.loc22_22.2: i32 = converted %.loc22_20.4, %.loc22_22.1
+// CHECK:STDOUT:   %F.call: init i32 = call %.loc22_11(%.loc22_20.3)
+// CHECK:STDOUT:   %.loc22_22.1: i32 = value_of_initializer %F.call
+// CHECK:STDOUT:   %.loc22_22.2: i32 = converted %F.call, %.loc22_22.1
 // CHECK:STDOUT:   return %.loc22_22.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -160,15 +176,15 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Derived* = name_ref p, %p
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc26_11.1: ref Derived = deref %p.ref
 // CHECK:STDOUT:   %.loc26_11.2: <bound method> = bound_method %.loc26_11.1, %F.ref
 // CHECK:STDOUT:   %.loc26_21.1: ref Base = class_element_access %.loc26_11.1, element0
 // CHECK:STDOUT:   %.loc26_21.2: ref Base = converted %.loc26_11.1, %.loc26_21.1
 // CHECK:STDOUT:   %.loc26_21.3: Base = bind_value %.loc26_21.2
-// CHECK:STDOUT:   %.loc26_21.4: init i32 = call %.loc26_11.2(%.loc26_21.3)
-// CHECK:STDOUT:   %.loc26_23.1: i32 = value_of_initializer %.loc26_21.4
-// CHECK:STDOUT:   %.loc26_23.2: i32 = converted %.loc26_21.4, %.loc26_23.1
+// CHECK:STDOUT:   %F.call: init i32 = call %.loc26_11.2(%.loc26_21.3)
+// CHECK:STDOUT:   %.loc26_23.1: i32 = value_of_initializer %F.call
+// CHECK:STDOUT:   %.loc26_23.2: i32 = converted %F.call, %.loc26_23.1
 // CHECK:STDOUT:   return %.loc26_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -176,11 +192,11 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: Derived = name_ref a, %a
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @Base.%G [template = @Base.%G]
+// CHECK:STDOUT:   %G.ref: G = name_ref G, @Base.%G.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc30_11: <bound method> = bound_method %a.ref, %G.ref
-// CHECK:STDOUT:   %.loc30_20: init i32 = call %.loc30_11(%a.ref)
-// CHECK:STDOUT:   %.loc30_22.1: i32 = value_of_initializer %.loc30_20
-// CHECK:STDOUT:   %.loc30_22.2: i32 = converted %.loc30_20, %.loc30_22.1
+// CHECK:STDOUT:   %G.call: init i32 = call %.loc30_11(%a.ref)
+// CHECK:STDOUT:   %.loc30_22.1: i32 = value_of_initializer %G.call
+// CHECK:STDOUT:   %.loc30_22.2: i32 = converted %G.call, %.loc30_22.1
 // CHECK:STDOUT:   return %.loc30_22.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -188,13 +204,13 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Derived* = name_ref p, %p
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @Base.%G [template = @Base.%G]
+// CHECK:STDOUT:   %G.ref: G = name_ref G, @Base.%G.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc34_11.1: ref Derived = deref %p.ref
 // CHECK:STDOUT:   %.loc34_11.2: <bound method> = bound_method %.loc34_11.1, %G.ref
 // CHECK:STDOUT:   %.loc34_11.3: Derived = bind_value %.loc34_11.1
-// CHECK:STDOUT:   %.loc34_21: init i32 = call %.loc34_11.2(%.loc34_11.3)
-// CHECK:STDOUT:   %.loc34_23.1: i32 = value_of_initializer %.loc34_21
-// CHECK:STDOUT:   %.loc34_23.2: i32 = converted %.loc34_21, %.loc34_23.1
+// CHECK:STDOUT:   %G.call: init i32 = call %.loc34_11.2(%.loc34_11.3)
+// CHECK:STDOUT:   %.loc34_23.1: i32 = value_of_initializer %G.call
+// CHECK:STDOUT:   %.loc34_23.2: i32 = converted %G.call, %.loc34_23.1
 // CHECK:STDOUT:   return %.loc34_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 26 - 18
toolchain/check/testdata/class/base_method_shadow.carbon

@@ -34,22 +34,30 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %.1: type = ptr_type A [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.3: type = tuple_type () [template]
 // CHECK:STDOUT:   %.4: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.5: type = unbound_element_type B, A [template]
 // CHECK:STDOUT:   %.6: type = ptr_type B [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.7: type = struct_type {.base: A} [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %.8: type = struct_type {.base: {}*} [template]
 // CHECK:STDOUT:   %.9: type = ptr_type {.base: A} [template]
 // CHECK:STDOUT:   %.10: type = unbound_element_type C, B [template]
 // CHECK:STDOUT:   %.11: type = ptr_type C [template]
+// CHECK:STDOUT:   %F.3: type = fn_type @F.3 [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.12: type = struct_type {.base: B} [template]
 // CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT:   %.13: type = unbound_element_type D, B [template]
 // CHECK:STDOUT:   %.14: type = ptr_type D [template]
+// CHECK:STDOUT:   %Call: type = fn_type @Call [template]
+// CHECK:STDOUT:   %struct.4: Call = struct_value () [template]
 // CHECK:STDOUT:   %.15: type = struct_type {.base: {.base: A}*} [template]
 // CHECK:STDOUT:   %.16: type = ptr_type {.base: B} [template]
 // CHECK:STDOUT: }
@@ -61,14 +69,14 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:     .C = %C.decl
 // CHECK:STDOUT:     .D = %D.decl
-// CHECK:STDOUT:     .Call = %Call
+// CHECK:STDOUT:     .Call = %Call.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %D.decl: type = class_decl @D [template = constants.%D] {}
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template] {
+// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.4] {
 // CHECK:STDOUT:     %A.ref: type = name_ref A, %A.decl [template = constants.%A]
 // CHECK:STDOUT:     %.loc25_13: type = ptr_type A [template = constants.%.1]
 // CHECK:STDOUT:     %a.loc25_9.1: A* = param a
@@ -89,7 +97,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%A [template = constants.%A]
 // CHECK:STDOUT:     %.loc8_23: type = ptr_type A [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc8_13.1: A* = param self
@@ -99,13 +107,13 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:   %.loc12: <unbound element of class B> = base_decl A, element0 [template]
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%B [template = constants.%B]
 // CHECK:STDOUT:     %.loc13_23: type = ptr_type B [template = constants.%.6]
 // CHECK:STDOUT:     %self.loc13_13.1: B* = param self
@@ -116,14 +124,14 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .base = %.loc12
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc17: <unbound element of class C> = base_decl B, element0 [template]
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.3 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.3 [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%C [template = constants.%C]
 // CHECK:STDOUT:     %.loc18_23: type = ptr_type C [template = constants.%.11]
 // CHECK:STDOUT:     %self.loc18_13.1: C* = param self
@@ -134,7 +142,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc17
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   extend name_scope3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -158,32 +166,32 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: A* = name_ref a, %a
 // CHECK:STDOUT:   %.loc26_4.1: ref A = deref %a.ref
-// CHECK:STDOUT:   %F.ref.loc26: <function> = name_ref F, @A.%F [template = @A.%F]
+// CHECK:STDOUT:   %F.ref.loc26: F = name_ref F, @A.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc26_7: <bound method> = bound_method %.loc26_4.1, %F.ref.loc26
 // CHECK:STDOUT:   %.loc26_4.2: A* = addr_of %.loc26_4.1
-// CHECK:STDOUT:   %.loc26_9: init () = call %.loc26_7(%.loc26_4.2)
+// CHECK:STDOUT:   %F.call.loc26: init () = call %.loc26_7(%.loc26_4.2)
 // CHECK:STDOUT:   %b.ref: B* = name_ref b, %b
 // CHECK:STDOUT:   %.loc27_4.1: ref B = deref %b.ref
-// CHECK:STDOUT:   %F.ref.loc27: <function> = name_ref F, @B.%F [template = @B.%F]
+// CHECK:STDOUT:   %F.ref.loc27: F = name_ref F, @B.%F.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc27_7: <bound method> = bound_method %.loc27_4.1, %F.ref.loc27
 // CHECK:STDOUT:   %.loc27_4.2: B* = addr_of %.loc27_4.1
-// CHECK:STDOUT:   %.loc27_9: init () = call %.loc27_7(%.loc27_4.2)
+// CHECK:STDOUT:   %F.call.loc27: init () = call %.loc27_7(%.loc27_4.2)
 // CHECK:STDOUT:   %c.ref: C* = name_ref c, %c
 // CHECK:STDOUT:   %.loc28_4.1: ref C = deref %c.ref
-// CHECK:STDOUT:   %F.ref.loc28: <function> = name_ref F, @C.%F [template = @C.%F]
+// CHECK:STDOUT:   %F.ref.loc28: F = name_ref F, @C.%F.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc28_7: <bound method> = bound_method %.loc28_4.1, %F.ref.loc28
 // CHECK:STDOUT:   %.loc28_4.2: C* = addr_of %.loc28_4.1
-// CHECK:STDOUT:   %.loc28_9: init () = call %.loc28_7(%.loc28_4.2)
+// CHECK:STDOUT:   %F.call.loc28: init () = call %.loc28_7(%.loc28_4.2)
 // CHECK:STDOUT:   %d.ref: D* = name_ref d, %d
 // CHECK:STDOUT:   %.loc29_4.1: ref D = deref %d.ref
-// CHECK:STDOUT:   %F.ref.loc29: <function> = name_ref F, @B.%F [template = @B.%F]
+// CHECK:STDOUT:   %F.ref.loc29: F = name_ref F, @B.%F.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc29_7: <bound method> = bound_method %.loc29_4.1, %F.ref.loc29
 // CHECK:STDOUT:   %.loc29_4.2: D* = addr_of %.loc29_4.1
 // CHECK:STDOUT:   %.loc29_9.1: ref D = deref %.loc29_4.2
 // CHECK:STDOUT:   %.loc29_9.2: ref B = class_element_access %.loc29_9.1, element0
 // CHECK:STDOUT:   %.loc29_9.3: B* = addr_of %.loc29_9.2
 // CHECK:STDOUT:   %.loc29_9.4: B* = converted %.loc29_4.2, %.loc29_9.3
-// CHECK:STDOUT:   %.loc29_9.5: init () = call %.loc29_7(%.loc29_9.4)
+// CHECK:STDOUT:   %F.call.loc29: init () = call %.loc29_7(%.loc29_9.4)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 19 - 12
toolchain/check/testdata/class/basic.carbon

@@ -26,36 +26,43 @@ fn Run() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Class, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.k: i32} [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.k: i32} [template]
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %struct.3: Run = struct_value () [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 4 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Class = %Class.decl
-// CHECK:STDOUT:     .Run = %Run
+// CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     %n.loc17_12.1: i32 = param n
 // CHECK:STDOUT:     @G.%n: i32 = bind_name n, %n.loc17_12.1
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.3] {
 // CHECK:STDOUT:     @Run.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %n.loc8_8.1: i32 = param n
 // CHECK:STDOUT:     %n.loc8_8.2: i32 = bind_name n, %n.loc8_8.1
 // CHECK:STDOUT:     %return.var.loc8: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     %n.loc12_8.1: i32 = param n
 // CHECK:STDOUT:     %n.loc12_8.2: i32 = bind_name n, %n.loc12_8.1
 // CHECK:STDOUT:     %return.var.loc12: ref i32 = var <return slot>
@@ -64,8 +71,8 @@ fn Run() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .F = %F
-// CHECK:STDOUT:   .G = %G
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT:   .k = %.loc14
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -84,8 +91,8 @@ fn Run() -> i32 {
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F [template = @Class.%F]
-// CHECK:STDOUT:   %.loc22_18: i32 = int_literal 4 [template = constants.%.3]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Class.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc22_18: i32 = int_literal 4 [template = constants.%.4]
 // CHECK:STDOUT:   %F.call: init i32 = call %F.ref(%.loc22_18)
 // CHECK:STDOUT:   %.loc22_20.1: i32 = value_of_initializer %F.call
 // CHECK:STDOUT:   %.loc22_20.2: i32 = converted %F.call, %.loc22_20.1

+ 8 - 5
toolchain/check/testdata/class/complete_in_member_fn.carbon

@@ -14,9 +14,12 @@ class C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type C, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32} [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type C, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -29,7 +32,7 @@ class C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
 // CHECK:STDOUT:     %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
 // CHECK:STDOUT:     %c.loc8_8.1: C = param c
 // CHECK:STDOUT:     %c.loc8_8.2: C = bind_name c, %c.loc8_8.1
@@ -39,7 +42,7 @@ class C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%C
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   .a = %.loc10
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 26 - 17
toolchain/check/testdata/class/compound_field.carbon

@@ -44,11 +44,20 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT:   %.4: type = unbound_element_type Derived, Base [template]
 // CHECK:STDOUT:   %.5: type = unbound_element_type Derived, i32 [template]
 // CHECK:STDOUT:   %.6: type = struct_type {.base: Base, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.9: type = ptr_type {.base: Base, .d: i32, .e: i32} [template]
-// CHECK:STDOUT:   %.10: type = ptr_type Derived [template]
-// CHECK:STDOUT:   %.11: type = ptr_type i32 [template]
+// CHECK:STDOUT:   %AccessDerived: type = fn_type @AccessDerived [template]
+// CHECK:STDOUT:   %.7: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: AccessDerived = struct_value () [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.10: type = ptr_type {.base: Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %AccessBase: type = fn_type @AccessBase [template]
+// CHECK:STDOUT:   %struct.2: AccessBase = struct_value () [template]
+// CHECK:STDOUT:   %.11: type = ptr_type Derived [template]
+// CHECK:STDOUT:   %.12: type = ptr_type i32 [template]
+// CHECK:STDOUT:   %AccessDerivedIndirect: type = fn_type @AccessDerivedIndirect [template]
+// CHECK:STDOUT:   %struct.3: AccessDerivedIndirect = struct_value () [template]
+// CHECK:STDOUT:   %AccessBaseIndirect: type = fn_type @AccessBaseIndirect [template]
+// CHECK:STDOUT:   %struct.4: AccessBaseIndirect = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -56,40 +65,40 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Base = %Base.decl
 // CHECK:STDOUT:     .Derived = %Derived.decl
-// CHECK:STDOUT:     .AccessDerived = %AccessDerived
-// CHECK:STDOUT:     .AccessBase = %AccessBase
-// CHECK:STDOUT:     .AccessDerivedIndirect = %AccessDerivedIndirect
-// CHECK:STDOUT:     .AccessBaseIndirect = %AccessBaseIndirect
+// CHECK:STDOUT:     .AccessDerived = %AccessDerived.decl
+// CHECK:STDOUT:     .AccessBase = %AccessBase.decl
+// CHECK:STDOUT:     .AccessDerivedIndirect = %AccessDerivedIndirect.decl
+// CHECK:STDOUT:     .AccessBaseIndirect = %AccessBaseIndirect.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %AccessDerived: <function> = fn_decl @AccessDerived [template] {
+// CHECK:STDOUT:   %AccessDerived.decl: AccessDerived = fn_decl @AccessDerived [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Derived.ref.loc20: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %d.loc20_18.1: Derived = param d
 // CHECK:STDOUT:     @AccessDerived.%d: Derived = bind_name d, %d.loc20_18.1
 // CHECK:STDOUT:     @AccessDerived.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessBase: <function> = fn_decl @AccessBase [template] {
+// CHECK:STDOUT:   %AccessBase.decl: AccessBase = fn_decl @AccessBase [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Derived.ref.loc24: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %d.loc24_15.1: Derived = param d
 // CHECK:STDOUT:     @AccessBase.%d: Derived = bind_name d, %d.loc24_15.1
 // CHECK:STDOUT:     @AccessBase.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessDerivedIndirect: <function> = fn_decl @AccessDerivedIndirect [template] {
+// CHECK:STDOUT:   %AccessDerivedIndirect.decl: AccessDerivedIndirect = fn_decl @AccessDerivedIndirect [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Derived.ref.loc28: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:     %.loc28_36: type = ptr_type Derived [template = constants.%.10]
+// CHECK:STDOUT:     %.loc28_36: type = ptr_type Derived [template = constants.%.11]
 // CHECK:STDOUT:     %p.loc28_26.1: Derived* = param p
 // CHECK:STDOUT:     @AccessDerivedIndirect.%p: Derived* = bind_name p, %p.loc28_26.1
-// CHECK:STDOUT:     %.loc28_45: type = ptr_type i32 [template = constants.%.11]
+// CHECK:STDOUT:     %.loc28_45: type = ptr_type i32 [template = constants.%.12]
 // CHECK:STDOUT:     @AccessDerivedIndirect.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessBaseIndirect: <function> = fn_decl @AccessBaseIndirect [template] {
+// CHECK:STDOUT:   %AccessBaseIndirect.decl: AccessBaseIndirect = fn_decl @AccessBaseIndirect [template = constants.%struct.4] {
 // CHECK:STDOUT:     %Derived.ref.loc32: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:     %.loc32_33: type = ptr_type Derived [template = constants.%.10]
+// CHECK:STDOUT:     %.loc32_33: type = ptr_type Derived [template = constants.%.11]
 // CHECK:STDOUT:     %p.loc32_23.1: Derived* = param p
 // CHECK:STDOUT:     @AccessBaseIndirect.%p: Derived* = bind_name p, %p.loc32_23.1
-// CHECK:STDOUT:     %.loc32_42: type = ptr_type i32 [template = constants.%.11]
+// CHECK:STDOUT:     %.loc32_42: type = ptr_type i32 [template = constants.%.12]
 // CHECK:STDOUT:     @AccessBaseIndirect.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }

+ 8 - 2
toolchain/check/testdata/class/cross_package_import.carbon

@@ -145,13 +145,19 @@ var c: Other.C = {};
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- other_conflict.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %C: type = fn_type @C [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: C = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .C = %C
+// CHECK:STDOUT:     .C = %C.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %C: <function> = fn_decl @C [template] {}
+// CHECK:STDOUT:   %C.decl: C = fn_decl @C [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @C() {

+ 51 - 38
toolchain/check/testdata/class/derived_to_base.carbon

@@ -54,18 +54,31 @@ fn ConvertInit() {
 // CHECK:STDOUT:   %.12: type = struct_type {.base: B, .c: i32} [template]
 // CHECK:STDOUT:   %.13: type = ptr_type C [template]
 // CHECK:STDOUT:   %.14: type = ptr_type B [template]
-// CHECK:STDOUT:   %.15: type = struct_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
-// CHECK:STDOUT:   %.16: type = ptr_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
-// CHECK:STDOUT:   %.17: type = ptr_type {.base: B, .c: i32} [template]
-// CHECK:STDOUT:   %.18: type = ptr_type A [template]
-// CHECK:STDOUT:   %.19: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.20: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.21: type = struct_type {.base: {.a: i32}, .b: i32} [template]
-// CHECK:STDOUT:   %.22: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.23: type = struct_type {.base: {.base: {.a: i32}, .b: i32}, .c: i32} [template]
-// CHECK:STDOUT:   %struct.1: A = struct_value (%.19) [template]
-// CHECK:STDOUT:   %struct.2: B = struct_value (%struct.1, %.20) [template]
-// CHECK:STDOUT:   %struct.3: C = struct_value (%struct.2, %.22) [template]
+// CHECK:STDOUT:   %ConvertCToB: type = fn_type @ConvertCToB [template]
+// CHECK:STDOUT:   %.15: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: ConvertCToB = struct_value () [template]
+// CHECK:STDOUT:   %.16: type = struct_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
+// CHECK:STDOUT:   %.17: type = ptr_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
+// CHECK:STDOUT:   %.18: type = ptr_type {.base: B, .c: i32} [template]
+// CHECK:STDOUT:   %.19: type = ptr_type A [template]
+// CHECK:STDOUT:   %ConvertBToA: type = fn_type @ConvertBToA [template]
+// CHECK:STDOUT:   %struct.2: ConvertBToA = struct_value () [template]
+// CHECK:STDOUT:   %ConvertCToA: type = fn_type @ConvertCToA [template]
+// CHECK:STDOUT:   %struct.3: ConvertCToA = struct_value () [template]
+// CHECK:STDOUT:   %ConvertValue: type = fn_type @ConvertValue [template]
+// CHECK:STDOUT:   %struct.4: ConvertValue = struct_value () [template]
+// CHECK:STDOUT:   %ConvertRef: type = fn_type @ConvertRef [template]
+// CHECK:STDOUT:   %struct.5: ConvertRef = struct_value () [template]
+// CHECK:STDOUT:   %ConvertInit: type = fn_type @ConvertInit [template]
+// CHECK:STDOUT:   %struct.6: ConvertInit = struct_value () [template]
+// CHECK:STDOUT:   %.20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.21: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.22: type = struct_type {.base: {.a: i32}, .b: i32} [template]
+// CHECK:STDOUT:   %.23: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.24: type = struct_type {.base: {.base: {.a: i32}, .b: i32}, .c: i32} [template]
+// CHECK:STDOUT:   %struct.7: A = struct_value (%.20) [template]
+// CHECK:STDOUT:   %struct.8: B = struct_value (%struct.7, %.21) [template]
+// CHECK:STDOUT:   %struct.9: C = struct_value (%struct.8, %.23) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -74,18 +87,18 @@ fn ConvertInit() {
 // CHECK:STDOUT:     .A = %A.decl
 // CHECK:STDOUT:     .B = %B.decl
 // CHECK:STDOUT:     .C = %C.decl
-// CHECK:STDOUT:     .ConvertCToB = %ConvertCToB
-// CHECK:STDOUT:     .ConvertBToA = %ConvertBToA
-// CHECK:STDOUT:     .ConvertCToA = %ConvertCToA
-// CHECK:STDOUT:     .ConvertValue = %ConvertValue
-// CHECK:STDOUT:     .ConvertRef = %ConvertRef
-// CHECK:STDOUT:     .ConvertInit = %ConvertInit
+// CHECK:STDOUT:     .ConvertCToB = %ConvertCToB.decl
+// CHECK:STDOUT:     .ConvertBToA = %ConvertBToA.decl
+// CHECK:STDOUT:     .ConvertCToA = %ConvertCToA.decl
+// CHECK:STDOUT:     .ConvertValue = %ConvertValue.decl
+// CHECK:STDOUT:     .ConvertRef = %ConvertRef.decl
+// CHECK:STDOUT:     .ConvertInit = %ConvertInit.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %ConvertCToB: <function> = fn_decl @ConvertCToB [template] {
+// CHECK:STDOUT:   %ConvertCToB.decl: ConvertCToB = fn_decl @ConvertCToB [template = constants.%struct.1] {
 // CHECK:STDOUT:     %C.ref.loc21: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21_20: type = ptr_type C [template = constants.%.13]
 // CHECK:STDOUT:     %p.loc21_16.1: C* = param p
@@ -94,39 +107,39 @@ fn ConvertInit() {
 // CHECK:STDOUT:     %.loc21_27: type = ptr_type B [template = constants.%.14]
 // CHECK:STDOUT:     @ConvertCToB.%return: ref B* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertBToA: <function> = fn_decl @ConvertBToA [template] {
+// CHECK:STDOUT:   %ConvertBToA.decl: ConvertBToA = fn_decl @ConvertBToA [template = constants.%struct.2] {
 // CHECK:STDOUT:     %B.ref.loc22: type = name_ref B, %B.decl [template = constants.%B]
 // CHECK:STDOUT:     %.loc22_20: type = ptr_type B [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc22_16.1: B* = param p
 // CHECK:STDOUT:     @ConvertBToA.%p: B* = bind_name p, %p.loc22_16.1
 // CHECK:STDOUT:     %A.ref.loc22: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT:     %.loc22_27: type = ptr_type A [template = constants.%.18]
+// CHECK:STDOUT:     %.loc22_27: type = ptr_type A [template = constants.%.19]
 // CHECK:STDOUT:     @ConvertBToA.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertCToA: <function> = fn_decl @ConvertCToA [template] {
+// CHECK:STDOUT:   %ConvertCToA.decl: ConvertCToA = fn_decl @ConvertCToA [template = constants.%struct.3] {
 // CHECK:STDOUT:     %C.ref.loc23: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc23_20: type = ptr_type C [template = constants.%.13]
 // CHECK:STDOUT:     %p.loc23_16.1: C* = param p
 // CHECK:STDOUT:     @ConvertCToA.%p: C* = bind_name p, %p.loc23_16.1
 // CHECK:STDOUT:     %A.ref.loc23: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT:     %.loc23_27: type = ptr_type A [template = constants.%.18]
+// CHECK:STDOUT:     %.loc23_27: type = ptr_type A [template = constants.%.19]
 // CHECK:STDOUT:     @ConvertCToA.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertValue: <function> = fn_decl @ConvertValue [template] {
+// CHECK:STDOUT:   %ConvertValue.decl: ConvertValue = fn_decl @ConvertValue [template = constants.%struct.4] {
 // CHECK:STDOUT:     %C.ref.loc25: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %c.loc25_17.1: C = param c
 // CHECK:STDOUT:     @ConvertValue.%c: C = bind_name c, %c.loc25_17.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertRef: <function> = fn_decl @ConvertRef [template] {
+// CHECK:STDOUT:   %ConvertRef.decl: ConvertRef = fn_decl @ConvertRef [template = constants.%struct.5] {
 // CHECK:STDOUT:     %C.ref.loc29: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc29_19: type = ptr_type C [template = constants.%.13]
 // CHECK:STDOUT:     %c.loc29_15.1: C* = param c
 // CHECK:STDOUT:     @ConvertRef.%c: C* = bind_name c, %c.loc29_15.1
 // CHECK:STDOUT:     %A.ref.loc29: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT:     %.loc29_26: type = ptr_type A [template = constants.%.18]
+// CHECK:STDOUT:     %.loc29_26: type = ptr_type A [template = constants.%.19]
 // CHECK:STDOUT:     @ConvertRef.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertInit: <function> = fn_decl @ConvertInit [template] {}
+// CHECK:STDOUT:   %ConvertInit.decl: ConvertInit = fn_decl @ConvertInit [template = constants.%struct.6] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
@@ -219,27 +232,27 @@ fn ConvertInit() {
 // CHECK:STDOUT: fn @ConvertInit() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1 [template = constants.%.19]
+// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1 [template = constants.%.20]
 // CHECK:STDOUT:   %.loc34_39.1: {.a: i32} = struct_literal (%.loc34_38)
-// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2 [template = constants.%.20]
+// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2 [template = constants.%.21]
 // CHECK:STDOUT:   %.loc34_48.1: {.base: {.a: i32}, .b: i32} = struct_literal (%.loc34_39.1, %.loc34_47)
-// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3 [template = constants.%.22]
+// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3 [template = constants.%.23]
 // CHECK:STDOUT:   %.loc34_57.1: {.base: {.base: {.a: i32}, .b: i32}, .c: i32} = struct_literal (%.loc34_48.1, %.loc34_56)
 // CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
 // CHECK:STDOUT:   %.loc34_57.2: ref C = temporary_storage
 // CHECK:STDOUT:   %.loc34_57.3: ref B = class_element_access %.loc34_57.2, element0
 // CHECK:STDOUT:   %.loc34_48.2: ref A = class_element_access %.loc34_57.3, element0
 // CHECK:STDOUT:   %.loc34_39.2: ref i32 = class_element_access %.loc34_48.2, element0
-// CHECK:STDOUT:   %.loc34_39.3: init i32 = initialize_from %.loc34_38 to %.loc34_39.2 [template = constants.%.19]
-// CHECK:STDOUT:   %.loc34_39.4: init A = class_init (%.loc34_39.3), %.loc34_48.2 [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc34_48.3: init A = converted %.loc34_39.1, %.loc34_39.4 [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc34_39.3: init i32 = initialize_from %.loc34_38 to %.loc34_39.2 [template = constants.%.20]
+// CHECK:STDOUT:   %.loc34_39.4: init A = class_init (%.loc34_39.3), %.loc34_48.2 [template = constants.%struct.7]
+// CHECK:STDOUT:   %.loc34_48.3: init A = converted %.loc34_39.1, %.loc34_39.4 [template = constants.%struct.7]
 // CHECK:STDOUT:   %.loc34_48.4: ref i32 = class_element_access %.loc34_57.3, element1
-// CHECK:STDOUT:   %.loc34_48.5: init i32 = initialize_from %.loc34_47 to %.loc34_48.4 [template = constants.%.20]
-// CHECK:STDOUT:   %.loc34_48.6: init B = class_init (%.loc34_48.3, %.loc34_48.5), %.loc34_57.3 [template = constants.%struct.2]
-// CHECK:STDOUT:   %.loc34_57.4: init B = converted %.loc34_48.1, %.loc34_48.6 [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc34_48.5: init i32 = initialize_from %.loc34_47 to %.loc34_48.4 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc34_48.6: init B = class_init (%.loc34_48.3, %.loc34_48.5), %.loc34_57.3 [template = constants.%struct.8]
+// CHECK:STDOUT:   %.loc34_57.4: init B = converted %.loc34_48.1, %.loc34_48.6 [template = constants.%struct.8]
 // CHECK:STDOUT:   %.loc34_57.5: ref i32 = class_element_access %.loc34_57.2, element1
-// CHECK:STDOUT:   %.loc34_57.6: init i32 = initialize_from %.loc34_56 to %.loc34_57.5 [template = constants.%.22]
-// CHECK:STDOUT:   %.loc34_57.7: init C = class_init (%.loc34_57.4, %.loc34_57.6), %.loc34_57.2 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc34_57.6: init i32 = initialize_from %.loc34_56 to %.loc34_57.5 [template = constants.%.23]
+// CHECK:STDOUT:   %.loc34_57.7: init C = class_init (%.loc34_57.4, %.loc34_57.6), %.loc34_57.2 [template = constants.%struct.9]
 // CHECK:STDOUT:   %.loc34_57.8: ref C = temporary %.loc34_57.2, %.loc34_57.7
 // CHECK:STDOUT:   %.loc34_59: ref C = converted %.loc34_57.1, %.loc34_57.8
 // CHECK:STDOUT:   %.loc34_63.1: ref B = class_element_access %.loc34_59, element0

+ 41 - 26
toolchain/check/testdata/class/extend_adapt.carbon

@@ -92,9 +92,17 @@ class StructAdapter {
 // CHECK:STDOUT:   %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
 // CHECK:STDOUT:   %SomeClass: type = class_type @SomeClass [template]
 // CHECK:STDOUT:   %.1: type = unbound_element_type SomeClass, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32, .b: i32} [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32, .b: i32} [template]
-// CHECK:STDOUT:   %.4: type = tuple_type () [template]
+// CHECK:STDOUT:   %StaticMemberFunction: type = fn_type @StaticMemberFunction [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: StaticMemberFunction = struct_value () [template]
+// CHECK:STDOUT:   %AdapterMethod: type = fn_type @AdapterMethod [template]
+// CHECK:STDOUT:   %struct.2: AdapterMethod = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %TestStaticMemberFunction: type = fn_type @TestStaticMemberFunction [template]
+// CHECK:STDOUT:   %struct.3: TestStaticMemberFunction = struct_value () [template]
+// CHECK:STDOUT:   %TestAdapterMethod: type = fn_type @TestAdapterMethod [template]
+// CHECK:STDOUT:   %struct.4: TestAdapterMethod = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -102,19 +110,19 @@ class StructAdapter {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .SomeClassAdapter = %SomeClassAdapter.decl.loc4
 // CHECK:STDOUT:     .SomeClass = %SomeClass.decl
-// CHECK:STDOUT:     .TestStaticMemberFunction = %TestStaticMemberFunction
-// CHECK:STDOUT:     .TestAdapterMethod = %TestAdapterMethod
+// CHECK:STDOUT:     .TestStaticMemberFunction = %TestStaticMemberFunction.decl
+// CHECK:STDOUT:     .TestAdapterMethod = %TestAdapterMethod.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %SomeClassAdapter.decl.loc4: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
 // CHECK:STDOUT:   %SomeClass.decl: type = class_decl @SomeClass [template = constants.%SomeClass] {}
 // CHECK:STDOUT:   %SomeClassAdapter.decl.loc15: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
-// CHECK:STDOUT:   %TestStaticMemberFunction: <function> = fn_decl @TestStaticMemberFunction [template] {
+// CHECK:STDOUT:   %TestStaticMemberFunction.decl: TestStaticMemberFunction = fn_decl @TestStaticMemberFunction [template = constants.%struct.3] {
 // CHECK:STDOUT:     %SomeClassAdapter.ref.loc19: type = name_ref SomeClassAdapter, %SomeClassAdapter.decl.loc4 [template = constants.%SomeClassAdapter]
 // CHECK:STDOUT:     %a.loc19_29.1: SomeClassAdapter = param a
 // CHECK:STDOUT:     @TestStaticMemberFunction.%a: SomeClassAdapter = bind_name a, %a.loc19_29.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TestAdapterMethod: <function> = fn_decl @TestAdapterMethod [template] {
+// CHECK:STDOUT:   %TestAdapterMethod.decl: TestAdapterMethod = fn_decl @TestAdapterMethod [template = constants.%struct.4] {
 // CHECK:STDOUT:     %SomeClassAdapter.ref.loc23: type = name_ref SomeClassAdapter, %SomeClassAdapter.decl.loc4 [template = constants.%SomeClassAdapter]
 // CHECK:STDOUT:     %a.loc23_22.1: SomeClassAdapter = param a
 // CHECK:STDOUT:     @TestAdapterMethod.%a: SomeClassAdapter = bind_name a, %a.loc23_22.1
@@ -133,8 +141,8 @@ class StructAdapter {
 // CHECK:STDOUT: class @SomeClass {
 // CHECK:STDOUT:   %.loc7: <unbound element of class SomeClass> = field_decl a, element0 [template]
 // CHECK:STDOUT:   %.loc8: <unbound element of class SomeClass> = field_decl b, element1 [template]
-// CHECK:STDOUT:   %StaticMemberFunction: <function> = fn_decl @StaticMemberFunction [template] {}
-// CHECK:STDOUT:   %AdapterMethod: <function> = fn_decl @AdapterMethod [template] {
+// CHECK:STDOUT:   %StaticMemberFunction.decl: StaticMemberFunction = fn_decl @StaticMemberFunction [template = constants.%struct.1] {}
+// CHECK:STDOUT:   %AdapterMethod.decl: AdapterMethod = fn_decl @AdapterMethod [template = constants.%struct.2] {
 // CHECK:STDOUT:     %SomeClassAdapter.ref: type = name_ref SomeClassAdapter, file.%SomeClassAdapter.decl.loc4 [template = constants.%SomeClassAdapter]
 // CHECK:STDOUT:     %self.loc12_20.1: SomeClassAdapter = param self
 // CHECK:STDOUT:     %self.loc12_20.2: SomeClassAdapter = bind_name self, %self.loc12_20.1
@@ -144,8 +152,8 @@ class StructAdapter {
 // CHECK:STDOUT:   .Self = constants.%SomeClass
 // CHECK:STDOUT:   .a = %.loc7
 // CHECK:STDOUT:   .b = %.loc8
-// CHECK:STDOUT:   .StaticMemberFunction = %StaticMemberFunction
-// CHECK:STDOUT:   .AdapterMethod = %AdapterMethod
+// CHECK:STDOUT:   .StaticMemberFunction = %StaticMemberFunction.decl
+// CHECK:STDOUT:   .AdapterMethod = %AdapterMethod.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @StaticMemberFunction();
@@ -155,7 +163,7 @@ class StructAdapter {
 // CHECK:STDOUT: fn @TestStaticMemberFunction(%a: SomeClassAdapter) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: SomeClassAdapter = name_ref a, %a
-// CHECK:STDOUT:   %StaticMemberFunction.ref: <function> = name_ref StaticMemberFunction, @SomeClass.%StaticMemberFunction [template = @SomeClass.%StaticMemberFunction]
+// CHECK:STDOUT:   %StaticMemberFunction.ref: StaticMemberFunction = name_ref StaticMemberFunction, @SomeClass.%StaticMemberFunction.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %StaticMemberFunction.call: init () = call %StaticMemberFunction.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -163,9 +171,9 @@ class StructAdapter {
 // CHECK:STDOUT: fn @TestAdapterMethod(%a: SomeClassAdapter) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: SomeClassAdapter = name_ref a, %a
-// CHECK:STDOUT:   %AdapterMethod.ref: <function> = name_ref AdapterMethod, @SomeClass.%AdapterMethod [template = @SomeClass.%AdapterMethod]
-// CHECK:STDOUT:   %.loc24_4: <bound method> = bound_method %a.ref, %AdapterMethod.ref
-// CHECK:STDOUT:   %.loc24_18: init () = call %.loc24_4(%a.ref)
+// CHECK:STDOUT:   %AdapterMethod.ref: AdapterMethod = name_ref AdapterMethod, @SomeClass.%AdapterMethod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc24: <bound method> = bound_method %a.ref, %AdapterMethod.ref
+// CHECK:STDOUT:   %AdapterMethod.call: init () = call %.loc24(%a.ref)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -173,10 +181,14 @@ class StructAdapter {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %SomeClass: type = class_type @SomeClass [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -184,12 +196,12 @@ class StructAdapter {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .SomeClass = %SomeClass.decl
 // CHECK:STDOUT:     .SomeClassAdapter = %SomeClassAdapter.decl
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %SomeClass.decl: type = class_decl @SomeClass [template = constants.%SomeClass] {}
 // CHECK:STDOUT:   %SomeClassAdapter.decl: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.2] {
 // CHECK:STDOUT:     %SomeClassAdapter.ref: type = name_ref SomeClassAdapter, %SomeClassAdapter.decl [template = constants.%SomeClassAdapter]
 // CHECK:STDOUT:     %a.loc12_6.1: SomeClassAdapter = param a
 // CHECK:STDOUT:     @F.2.%a: SomeClassAdapter = bind_name a, %a.loc12_6.1
@@ -197,7 +209,7 @@ class StructAdapter {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClass {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%SomeClass [template = constants.%SomeClass]
 // CHECK:STDOUT:     %self.loc5_8.1: SomeClass = param self
 // CHECK:STDOUT:     %self.loc5_8.2: SomeClass = bind_name self, %self.loc5_8.1
@@ -205,7 +217,7 @@ class StructAdapter {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%SomeClass
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClassAdapter {
@@ -222,9 +234,9 @@ class StructAdapter {
 // CHECK:STDOUT: fn @F.2(%a: SomeClassAdapter) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: SomeClassAdapter = name_ref a, %a
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @SomeClass.%F [template = @SomeClass.%F]
-// CHECK:STDOUT:   %.loc20_4: <bound method> = bound_method %a.ref, %F.ref
-// CHECK:STDOUT:   %.loc20_6: init () = call %.loc20_4(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @SomeClass.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc20: <bound method> = bound_method %a.ref, %F.ref
+// CHECK:STDOUT:   %F.call: init () = call %.loc20(<invalid>) [template = <error>]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -236,6 +248,9 @@ class StructAdapter {
 // CHECK:STDOUT:   %.2: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %SomeClassAdapter: type = class_type @SomeClassAdapter [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.4: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -243,12 +258,12 @@ class StructAdapter {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .SomeClass = %SomeClass.decl
 // CHECK:STDOUT:     .SomeClassAdapter = %SomeClassAdapter.decl
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %SomeClass.decl: type = class_decl @SomeClass [template = constants.%SomeClass] {}
 // CHECK:STDOUT:   %SomeClassAdapter.decl: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
 // CHECK:STDOUT:     %SomeClassAdapter.ref: type = name_ref SomeClassAdapter, %SomeClassAdapter.decl [template = constants.%SomeClassAdapter]
 // CHECK:STDOUT:     %a.loc13_6.1: SomeClassAdapter = param a
 // CHECK:STDOUT:     @F.%a: SomeClassAdapter = bind_name a, %a.loc13_6.1

+ 4 - 1
toolchain/check/testdata/class/extern.carbon

@@ -342,6 +342,9 @@ extern class C;
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %.1: type = fn_type @.1 [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: <invalid> = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -351,7 +354,7 @@ extern class C;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %.loc12: <function> = fn_decl @.1 [template] {}
+// CHECK:STDOUT:   %.decl: <invalid> = fn_decl @.1 [template = constants.%struct] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C;

+ 21 - 16
toolchain/check/testdata/class/fail_abstract.carbon

@@ -37,15 +37,20 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.4: type = unbound_element_type Derived, Abstract [template]
 // CHECK:STDOUT:   %.5: type = unbound_element_type Derived, i32 [template]
 // CHECK:STDOUT:   %.6: type = struct_type {.base: Abstract, .d: i32} [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: {.a: i32}*, .d: i32} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type {.base: {.a: i32}*, .d: i32} [template]
-// CHECK:STDOUT:   %.9: type = ptr_type {.base: Abstract, .d: i32} [template]
-// CHECK:STDOUT:   %.10: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.11: i32 = int_literal 7 [template]
-// CHECK:STDOUT:   %.12: type = struct_type {.base: {.a: i32}, .d: i32} [template]
-// CHECK:STDOUT:   %.13: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.14: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.15: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %Make: type = fn_type @Make [template]
+// CHECK:STDOUT:   %.7: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Make = struct_value () [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.base: {.a: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type {.base: {.a: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.10: type = ptr_type {.base: Abstract, .d: i32} [template]
+// CHECK:STDOUT:   %.11: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.12: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.13: type = struct_type {.base: {.a: i32}, .d: i32} [template]
+// CHECK:STDOUT:   %.14: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.15: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %Access: type = fn_type @Access [template]
+// CHECK:STDOUT:   %struct.2: Access = struct_value () [template]
+// CHECK:STDOUT:   %.16: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -53,22 +58,22 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Abstract = %Abstract.decl
 // CHECK:STDOUT:     .Derived = %Derived.decl
-// CHECK:STDOUT:     .Make = %Make
-// CHECK:STDOUT:     .Access = %Access
+// CHECK:STDOUT:     .Make = %Make.decl
+// CHECK:STDOUT:     .Access = %Access.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Abstract.decl: type = class_decl @Abstract [template = constants.%Abstract] {}
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template] {
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Derived.ref.loc17: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     @Make.%return: ref Derived = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template] {
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Derived.ref.loc25: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %d.loc25_11.1: Derived = param d
 // CHECK:STDOUT:     @Access.%d: Derived = bind_name d, %d.loc25_11.1
 // CHECK:STDOUT:     %.loc25_35.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:     %.loc25_35.2: type = converted %.loc25_35.1, constants.%.14 [template = constants.%.14]
+// CHECK:STDOUT:     %.loc25_35.2: type = converted %.loc25_35.1, constants.%.15 [template = constants.%.15]
 // CHECK:STDOUT:     @Access.%return: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -95,9 +100,9 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc22_26: {.a: i32} = struct_literal (%.loc22_25)
-// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc22_35: {.base: {.a: i32}, .d: i32} = struct_literal (%.loc22_26, %.loc22_34)
 // CHECK:STDOUT:   return <error> to %return
 // CHECK:STDOUT: }

+ 10 - 4
toolchain/check/testdata/class/fail_adapt_bad_decl.carbon

@@ -97,17 +97,20 @@ class C {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Bad: type = class_type @Bad [template]
 // CHECK:STDOUT:   %.1: i32 = int_literal 100 [template]
+// CHECK:STDOUT:   %Use: type = fn_type @Use [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Use = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Bad = %Bad.decl
-// CHECK:STDOUT:     .Use = %Use
+// CHECK:STDOUT:     .Use = %Use.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Bad.decl: type = class_decl @Bad [template = constants.%Bad] {}
-// CHECK:STDOUT:   %Use: <function> = fn_decl @Use [template] {
+// CHECK:STDOUT:   %Use.decl: Use = fn_decl @Use [template = constants.%struct] {
 // CHECK:STDOUT:     %Bad.ref: type = name_ref Bad, %Bad.decl [template = constants.%Bad]
 // CHECK:STDOUT:     %b.loc16_8.1: Bad = param b
 // CHECK:STDOUT:     @Use.%b: Bad = bind_name b, %b.loc16_8.1
@@ -134,17 +137,20 @@ class C {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Bad: type = class_type @Bad [template]
 // CHECK:STDOUT:   %.1: i32 = int_literal 100 [template]
+// CHECK:STDOUT:   %Use: type = fn_type @Use [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Use = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Bad = %Bad.decl
-// CHECK:STDOUT:     .Use = %Use
+// CHECK:STDOUT:     .Use = %Use.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Bad.decl: type = class_decl @Bad [template = constants.%Bad] {}
-// CHECK:STDOUT:   %Use: <function> = fn_decl @Use [template] {
+// CHECK:STDOUT:   %Use.decl: Use = fn_decl @Use [template = constants.%struct] {
 // CHECK:STDOUT:     %Bad.ref: type = name_ref Bad, %Bad.decl [template = constants.%Bad]
 // CHECK:STDOUT:     %b.loc13_8.1: Bad = param b
 // CHECK:STDOUT:     @Use.%b: Bad = bind_name b, %b.loc13_8.1

+ 10 - 5
toolchain/check/testdata/class/fail_addr_not_self.carbon

@@ -22,7 +22,12 @@ class Class {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = ptr_type Class [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -35,13 +40,13 @@ class Class {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Class.ref.loc12: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc12: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %a.loc12_13.1: Class* = param a
 // CHECK:STDOUT:     %a.loc12_13.2: Class* = bind_name a, %a.loc12_13.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Class.ref.loc17: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc17: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %b.loc17_13.1: Class* = param b
@@ -50,8 +55,8 @@ class Class {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .F = %F
-// CHECK:STDOUT:   .G = %G
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F[@Class.%a.loc12_13.2: Class*]();

+ 24 - 18
toolchain/check/testdata/class/fail_addr_self.carbon

@@ -45,8 +45,14 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = ptr_type Class [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
-// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %G: type = fn_type @G [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.4: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -54,11 +60,11 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Class = %Class.decl
-// CHECK:STDOUT:     .F = %F
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Class.ref.loc12_9: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %c.loc12_6.1: Class = param c
 // CHECK:STDOUT:     @F.2.%c: Class = bind_name c, %c.loc12_6.1
@@ -70,14 +76,14 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {
 // CHECK:STDOUT:     %Class.ref.loc8: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc8_24: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc8_13.1: Class* = param self
 // CHECK:STDOUT:     %self.loc8_13.3: Class* = bind_name self, %self.loc8_13.1
 // CHECK:STDOUT:     %.loc8_8: Class* = addr_pattern %self.loc8_13.3
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G: <function> = fn_decl @G [template] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Class.ref.loc9: type = name_ref Class, file.%Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc9_13.1: Class = param self
 // CHECK:STDOUT:     %self.loc9_13.3: Class = bind_name self, %self.loc9_13.1
@@ -86,8 +92,8 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .F = %F
-// CHECK:STDOUT:   .G = %G
+// CHECK:STDOUT:   .F = %F.decl
+// CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1[addr @Class.%self.loc8_13.3: Class*]();
@@ -97,25 +103,25 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT: fn @F.2(%c: Class, %p: Class*) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %c.ref.loc20: Class = name_ref c, %c
-// CHECK:STDOUT:   %F.ref.loc20: <function> = name_ref F, @Class.%F [template = @Class.%F]
-// CHECK:STDOUT:   %.loc20_4: <bound method> = bound_method %c.ref.loc20, %F.ref.loc20
-// CHECK:STDOUT:   %.loc20_6: init () = call %.loc20_4(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %F.ref.loc20: F = name_ref F, @Class.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %.loc20: <bound method> = bound_method %c.ref.loc20, %F.ref.loc20
+// CHECK:STDOUT:   %F.call.loc20: init () = call %.loc20(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %c.ref.loc29: Class = name_ref c, %c
-// CHECK:STDOUT:   %G.ref.loc29: <function> = name_ref G, @Class.%G [template = @Class.%G]
-// CHECK:STDOUT:   %.loc29_4: <bound method> = bound_method %c.ref.loc29, %G.ref.loc29
-// CHECK:STDOUT:   %.loc29_6: init () = call %.loc29_4(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %G.ref.loc29: G = name_ref G, @Class.%G.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc29: <bound method> = bound_method %c.ref.loc29, %G.ref.loc29
+// CHECK:STDOUT:   %G.call.loc29: init () = call %.loc29(<invalid>) [template = <error>]
 // CHECK:STDOUT:   %p.ref.loc32: Class* = name_ref p, %p
 // CHECK:STDOUT:   %.loc32_4.1: ref Class = deref %p.ref.loc32
-// CHECK:STDOUT:   %F.ref.loc32: <function> = name_ref F, @Class.%F [template = @Class.%F]
+// CHECK:STDOUT:   %F.ref.loc32: F = name_ref F, @Class.%F.decl [template = constants.%struct.1]
 // CHECK:STDOUT:   %.loc32_7: <bound method> = bound_method %.loc32_4.1, %F.ref.loc32
 // CHECK:STDOUT:   %.loc32_4.2: Class* = addr_of %.loc32_4.1
-// CHECK:STDOUT:   %.loc32_9: init () = call %.loc32_7(%.loc32_4.2)
+// CHECK:STDOUT:   %F.call.loc32: init () = call %.loc32_7(%.loc32_4.2)
 // CHECK:STDOUT:   %p.ref.loc40: Class* = name_ref p, %p
 // CHECK:STDOUT:   %.loc40_4.1: ref Class = deref %p.ref.loc40
-// CHECK:STDOUT:   %G.ref.loc40: <function> = name_ref G, @Class.%G [template = @Class.%G]
+// CHECK:STDOUT:   %G.ref.loc40: G = name_ref G, @Class.%G.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc40_7: <bound method> = bound_method %.loc40_4.1, %G.ref.loc40
 // CHECK:STDOUT:   %.loc40_4.2: Class* = addr_of %.loc40_4.1
-// CHECK:STDOUT:   %.loc40_9: init () = call %.loc40_7(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %G.call.loc40: init () = call %.loc40_7(<invalid>) [template = <error>]
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 66 - 40
toolchain/check/testdata/class/fail_base_bad_type.carbon

@@ -138,36 +138,62 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %DeriveFromError: type = class_type @DeriveFromError [template]
 // CHECK:STDOUT:   %.4: type = ptr_type DeriveFromError [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError: type = fn_type @AccessMemberWithInvalidBaseError [template]
+// CHECK:STDOUT:   %.5: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: AccessMemberWithInvalidBaseError = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromNonType: type = class_type @DeriveFromNonType [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 32 [template]
-// CHECK:STDOUT:   %.6: type = ptr_type DeriveFromNonType [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %.7: type = ptr_type DeriveFromNonType [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType: type = fn_type @AccessMemberWithInvalidBasNonType [template]
+// CHECK:STDOUT:   %struct.2: AccessMemberWithInvalidBasNonType = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromi32: type = class_type @DeriveFromi32 [template]
-// CHECK:STDOUT:   %.7: type = ptr_type DeriveFromi32 [template]
-// CHECK:STDOUT:   %.8: type = ptr_type i32 [template]
+// CHECK:STDOUT:   %.8: type = ptr_type DeriveFromi32 [template]
+// CHECK:STDOUT:   %.9: type = ptr_type i32 [template]
+// CHECK:STDOUT:   %ConvertToBadBasei32: type = fn_type @ConvertToBadBasei32 [template]
+// CHECK:STDOUT:   %struct.3: ConvertToBadBasei32 = struct_value () [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32: type = fn_type @AccessMemberWithInvalidBasei32 [template]
+// CHECK:STDOUT:   %struct.4: AccessMemberWithInvalidBasei32 = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromTuple: type = class_type @DeriveFromTuple [template]
-// CHECK:STDOUT:   %.9: type = tuple_type (type) [template]
-// CHECK:STDOUT:   %.10: type = tuple_type (Base) [template]
-// CHECK:STDOUT:   %.11: type = tuple_type () [template]
+// CHECK:STDOUT:   %.10: type = tuple_type (type) [template]
+// CHECK:STDOUT:   %.11: type = tuple_type (Base) [template]
 // CHECK:STDOUT:   %.12: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.13: type = tuple_type ({}*) [template]
 // CHECK:STDOUT:   %.14: type = ptr_type DeriveFromTuple [template]
 // CHECK:STDOUT:   %.15: type = ptr_type (Base,) [template]
+// CHECK:STDOUT:   %ConvertToBadBaseTuple: type = fn_type @ConvertToBadBaseTuple [template]
+// CHECK:STDOUT:   %struct.5: ConvertToBadBaseTuple = struct_value () [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple: type = fn_type @AccessMemberWithInvalidBaseTuple [template]
+// CHECK:STDOUT:   %struct.6: AccessMemberWithInvalidBaseTuple = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromStruct: type = class_type @DeriveFromStruct [template]
 // CHECK:STDOUT:   %.16: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %.17: type = ptr_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %.18: type = ptr_type DeriveFromStruct [template]
+// CHECK:STDOUT:   %ConvertToBadBaseStruct: type = fn_type @ConvertToBadBaseStruct [template]
+// CHECK:STDOUT:   %struct.7: ConvertToBadBaseStruct = struct_value () [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct: type = fn_type @AccessMemberWithInvalidBaseStruct [template]
+// CHECK:STDOUT:   %struct.8: AccessMemberWithInvalidBaseStruct = struct_value () [template]
 // CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
 // CHECK:STDOUT:   %DeriveFromIncomplete: type = class_type @DeriveFromIncomplete [template]
 // CHECK:STDOUT:   %.19: type = ptr_type DeriveFromIncomplete [template]
 // CHECK:STDOUT:   %.20: type = ptr_type Incomplete [template]
+// CHECK:STDOUT:   %ConvertToBadBaseIncomplete: type = fn_type @ConvertToBadBaseIncomplete [template]
+// CHECK:STDOUT:   %struct.9: ConvertToBadBaseIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete: type = fn_type @AccessMemberWithInvalidBaseIncomplete [template]
+// CHECK:STDOUT:   %struct.10: AccessMemberWithInvalidBaseIncomplete = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromFinal: type = class_type @DeriveFromFinal [template]
 // CHECK:STDOUT:   %.21: type = ptr_type {.a: i32} [template]
 // CHECK:STDOUT:   %.22: type = unbound_element_type DeriveFromFinal, Final [template]
 // CHECK:STDOUT:   %.23: type = struct_type {.base: Final} [template]
 // CHECK:STDOUT:   %.24: type = ptr_type DeriveFromFinal [template]
 // CHECK:STDOUT:   %.25: type = ptr_type Final [template]
+// CHECK:STDOUT:   %ConvertToBadBaseFinal: type = fn_type @ConvertToBadBaseFinal [template]
+// CHECK:STDOUT:   %struct.11: ConvertToBadBaseFinal = struct_value () [template]
 // CHECK:STDOUT:   %.26: type = struct_type {.base: {.a: i32}*} [template]
 // CHECK:STDOUT:   %.27: type = ptr_type {.base: Final} [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember: type = fn_type @AccessMemberWithInvalidBaseFinal_WithMember [template]
+// CHECK:STDOUT:   %struct.12: AccessMemberWithInvalidBaseFinal_WithMember = struct_value () [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember: type = fn_type @AccessMemberWithInvalidBaseFinal_NoMember [template]
+// CHECK:STDOUT:   %struct.13: AccessMemberWithInvalidBaseFinal_NoMember = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -176,32 +202,32 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     .Base = %Base.decl
 // CHECK:STDOUT:     .Final = %Final.decl
 // CHECK:STDOUT:     .DeriveFromError = %DeriveFromError.decl
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseError = %AccessMemberWithInvalidBaseError
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseError = %AccessMemberWithInvalidBaseError.decl
 // CHECK:STDOUT:     .DeriveFromNonType = %DeriveFromNonType.decl
-// CHECK:STDOUT:     .AccessMemberWithInvalidBasNonType = %AccessMemberWithInvalidBasNonType
+// CHECK:STDOUT:     .AccessMemberWithInvalidBasNonType = %AccessMemberWithInvalidBasNonType.decl
 // CHECK:STDOUT:     .DeriveFromi32 = %DeriveFromi32.decl
-// CHECK:STDOUT:     .ConvertToBadBasei32 = %ConvertToBadBasei32
-// CHECK:STDOUT:     .AccessMemberWithInvalidBasei32 = %AccessMemberWithInvalidBasei32
+// CHECK:STDOUT:     .ConvertToBadBasei32 = %ConvertToBadBasei32.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBasei32 = %AccessMemberWithInvalidBasei32.decl
 // CHECK:STDOUT:     .DeriveFromTuple = %DeriveFromTuple.decl
-// CHECK:STDOUT:     .ConvertToBadBaseTuple = %ConvertToBadBaseTuple
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseTuple = %AccessMemberWithInvalidBaseTuple
+// CHECK:STDOUT:     .ConvertToBadBaseTuple = %ConvertToBadBaseTuple.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseTuple = %AccessMemberWithInvalidBaseTuple.decl
 // CHECK:STDOUT:     .DeriveFromStruct = %DeriveFromStruct.decl
-// CHECK:STDOUT:     .ConvertToBadBaseStruct = %ConvertToBadBaseStruct
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseStruct = %AccessMemberWithInvalidBaseStruct
+// CHECK:STDOUT:     .ConvertToBadBaseStruct = %ConvertToBadBaseStruct.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseStruct = %AccessMemberWithInvalidBaseStruct.decl
 // CHECK:STDOUT:     .Incomplete = %Incomplete.decl
 // CHECK:STDOUT:     .DeriveFromIncomplete = %DeriveFromIncomplete.decl
-// CHECK:STDOUT:     .ConvertToBadBaseIncomplete = %ConvertToBadBaseIncomplete
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseIncomplete = %AccessMemberWithInvalidBaseIncomplete
+// CHECK:STDOUT:     .ConvertToBadBaseIncomplete = %ConvertToBadBaseIncomplete.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseIncomplete = %AccessMemberWithInvalidBaseIncomplete.decl
 // CHECK:STDOUT:     .DeriveFromFinal = %DeriveFromFinal.decl
-// CHECK:STDOUT:     .ConvertToBadBaseFinal = %ConvertToBadBaseFinal
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseFinal_WithMember = %AccessMemberWithInvalidBaseFinal_WithMember
-// CHECK:STDOUT:     .AccessMemberWithInvalidBaseFinal_NoMember = %AccessMemberWithInvalidBaseFinal_NoMember
+// CHECK:STDOUT:     .ConvertToBadBaseFinal = %ConvertToBadBaseFinal.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseFinal_WithMember = %AccessMemberWithInvalidBaseFinal_WithMember.decl
+// CHECK:STDOUT:     .AccessMemberWithInvalidBaseFinal_NoMember = %AccessMemberWithInvalidBaseFinal_NoMember.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Final.decl: type = class_decl @Final [template = constants.%Final] {}
 // CHECK:STDOUT:   %DeriveFromError.decl: type = class_decl @DeriveFromError [template = constants.%DeriveFromError] {}
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError: <function> = fn_decl @AccessMemberWithInvalidBaseError [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError.decl: AccessMemberWithInvalidBaseError = fn_decl @AccessMemberWithInvalidBaseError [template = constants.%struct.1] {
 // CHECK:STDOUT:     %DeriveFromError.ref: type = name_ref DeriveFromError, %DeriveFromError.decl [template = constants.%DeriveFromError]
 // CHECK:STDOUT:     %.loc21: type = ptr_type DeriveFromError [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc21_37.1: DeriveFromError* = param p
@@ -209,42 +235,42 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseError.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %DeriveFromNonType.decl: type = class_decl @DeriveFromNonType [template = constants.%DeriveFromNonType] {}
-// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType: <function> = fn_decl @AccessMemberWithInvalidBasNonType [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType.decl: AccessMemberWithInvalidBasNonType = fn_decl @AccessMemberWithInvalidBasNonType [template = constants.%struct.2] {
 // CHECK:STDOUT:     %DeriveFromNonType.ref: type = name_ref DeriveFromNonType, %DeriveFromNonType.decl [template = constants.%DeriveFromNonType]
-// CHECK:STDOUT:     %.loc31: type = ptr_type DeriveFromNonType [template = constants.%.6]
+// CHECK:STDOUT:     %.loc31: type = ptr_type DeriveFromNonType [template = constants.%.7]
 // CHECK:STDOUT:     %p.loc31_38.1: DeriveFromNonType* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBasNonType.%p: DeriveFromNonType* = bind_name p, %p.loc31_38.1
 // CHECK:STDOUT:     @AccessMemberWithInvalidBasNonType.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %DeriveFromi32.decl: type = class_decl @DeriveFromi32 [template = constants.%DeriveFromi32] {}
-// CHECK:STDOUT:   %ConvertToBadBasei32: <function> = fn_decl @ConvertToBadBasei32 [template] {
+// CHECK:STDOUT:   %ConvertToBadBasei32.decl: ConvertToBadBasei32 = fn_decl @ConvertToBadBasei32 [template = constants.%struct.3] {
 // CHECK:STDOUT:     %DeriveFromi32.ref.loc47: type = name_ref DeriveFromi32, %DeriveFromi32.decl [template = constants.%DeriveFromi32]
-// CHECK:STDOUT:     %.loc47_40: type = ptr_type DeriveFromi32 [template = constants.%.7]
+// CHECK:STDOUT:     %.loc47_40: type = ptr_type DeriveFromi32 [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc47_24.1: DeriveFromi32* = param p
 // CHECK:STDOUT:     @ConvertToBadBasei32.%p: DeriveFromi32* = bind_name p, %p.loc47_24.1
-// CHECK:STDOUT:     %.loc47_49: type = ptr_type i32 [template = constants.%.8]
+// CHECK:STDOUT:     %.loc47_49: type = ptr_type i32 [template = constants.%.9]
 // CHECK:STDOUT:     @ConvertToBadBasei32.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32: <function> = fn_decl @AccessMemberWithInvalidBasei32 [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32.decl: AccessMemberWithInvalidBasei32 = fn_decl @AccessMemberWithInvalidBasei32 [template = constants.%struct.4] {
 // CHECK:STDOUT:     %DeriveFromi32.ref.loc49: type = name_ref DeriveFromi32, %DeriveFromi32.decl [template = constants.%DeriveFromi32]
-// CHECK:STDOUT:     %.loc49: type = ptr_type DeriveFromi32 [template = constants.%.7]
+// CHECK:STDOUT:     %.loc49: type = ptr_type DeriveFromi32 [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc49_35.1: DeriveFromi32* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBasei32.%p: DeriveFromi32* = bind_name p, %p.loc49_35.1
 // CHECK:STDOUT:     @AccessMemberWithInvalidBasei32.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %DeriveFromTuple.decl: type = class_decl @DeriveFromTuple [template = constants.%DeriveFromTuple] {}
-// CHECK:STDOUT:   %ConvertToBadBaseTuple: <function> = fn_decl @ConvertToBadBaseTuple [template] {
+// CHECK:STDOUT:   %ConvertToBadBaseTuple.decl: ConvertToBadBaseTuple = fn_decl @ConvertToBadBaseTuple [template = constants.%struct.5] {
 // CHECK:STDOUT:     %DeriveFromTuple.ref.loc63: type = name_ref DeriveFromTuple, %DeriveFromTuple.decl [template = constants.%DeriveFromTuple]
 // CHECK:STDOUT:     %.loc63_44: type = ptr_type DeriveFromTuple [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc63_26.1: DeriveFromTuple* = param p
 // CHECK:STDOUT:     @ConvertToBadBaseTuple.%p: DeriveFromTuple* = bind_name p, %p.loc63_26.1
 // CHECK:STDOUT:     %Base.ref: type = name_ref Base, %Base.decl [template = constants.%Base]
 // CHECK:STDOUT:     %.loc63_56: (type,) = tuple_literal (%Base.ref)
-// CHECK:STDOUT:     %.loc63_57.1: type = converted %.loc63_56, constants.%.10 [template = constants.%.10]
+// CHECK:STDOUT:     %.loc63_57.1: type = converted %.loc63_56, constants.%.11 [template = constants.%.11]
 // CHECK:STDOUT:     %.loc63_57.2: type = ptr_type (Base,) [template = constants.%.15]
 // CHECK:STDOUT:     @ConvertToBadBaseTuple.%return: ref (Base,)* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple: <function> = fn_decl @AccessMemberWithInvalidBaseTuple [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple.decl: AccessMemberWithInvalidBaseTuple = fn_decl @AccessMemberWithInvalidBaseTuple [template = constants.%struct.6] {
 // CHECK:STDOUT:     %DeriveFromTuple.ref.loc65: type = name_ref DeriveFromTuple, %DeriveFromTuple.decl [template = constants.%DeriveFromTuple]
 // CHECK:STDOUT:     %.loc65: type = ptr_type DeriveFromTuple [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc65_37.1: DeriveFromTuple* = param p
@@ -252,7 +278,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseTuple.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %DeriveFromStruct.decl: type = class_decl @DeriveFromStruct [template = constants.%DeriveFromStruct] {}
-// CHECK:STDOUT:   %ConvertToBadBaseStruct: <function> = fn_decl @ConvertToBadBaseStruct [template] {
+// CHECK:STDOUT:   %ConvertToBadBaseStruct.decl: ConvertToBadBaseStruct = fn_decl @ConvertToBadBaseStruct [template = constants.%struct.7] {
 // CHECK:STDOUT:     %DeriveFromStruct.ref.loc81: type = name_ref DeriveFromStruct, %DeriveFromStruct.decl [template = constants.%DeriveFromStruct]
 // CHECK:STDOUT:     %.loc81_46: type = ptr_type DeriveFromStruct [template = constants.%.18]
 // CHECK:STDOUT:     %p.loc81_27.1: DeriveFromStruct* = param p
@@ -261,7 +287,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     %.loc81_70: type = ptr_type {.a: i32, .b: i32} [template = constants.%.17]
 // CHECK:STDOUT:     @ConvertToBadBaseStruct.%return: ref {.a: i32, .b: i32}* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct: <function> = fn_decl @AccessMemberWithInvalidBaseStruct [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct.decl: AccessMemberWithInvalidBaseStruct = fn_decl @AccessMemberWithInvalidBaseStruct [template = constants.%struct.8] {
 // CHECK:STDOUT:     %DeriveFromStruct.ref.loc84: type = name_ref DeriveFromStruct, %DeriveFromStruct.decl [template = constants.%DeriveFromStruct]
 // CHECK:STDOUT:     %.loc84: type = ptr_type DeriveFromStruct [template = constants.%.18]
 // CHECK:STDOUT:     %p.loc84_38.1: DeriveFromStruct* = param p
@@ -270,7 +296,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Incomplete.decl: type = class_decl @Incomplete [template = constants.%Incomplete] {}
 // CHECK:STDOUT:   %DeriveFromIncomplete.decl: type = class_decl @DeriveFromIncomplete [template = constants.%DeriveFromIncomplete] {}
-// CHECK:STDOUT:   %ConvertToBadBaseIncomplete: <function> = fn_decl @ConvertToBadBaseIncomplete [template] {
+// CHECK:STDOUT:   %ConvertToBadBaseIncomplete.decl: ConvertToBadBaseIncomplete = fn_decl @ConvertToBadBaseIncomplete [template = constants.%struct.9] {
 // CHECK:STDOUT:     %DeriveFromIncomplete.ref.loc103: type = name_ref DeriveFromIncomplete, %DeriveFromIncomplete.decl [template = constants.%DeriveFromIncomplete]
 // CHECK:STDOUT:     %.loc103_54: type = ptr_type DeriveFromIncomplete [template = constants.%.19]
 // CHECK:STDOUT:     %p.loc103_31.1: DeriveFromIncomplete* = param p
@@ -279,7 +305,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     %.loc103_70: type = ptr_type Incomplete [template = constants.%.20]
 // CHECK:STDOUT:     @ConvertToBadBaseIncomplete.%return: ref Incomplete* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete: <function> = fn_decl @AccessMemberWithInvalidBaseIncomplete [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete.decl: AccessMemberWithInvalidBaseIncomplete = fn_decl @AccessMemberWithInvalidBaseIncomplete [template = constants.%struct.10] {
 // CHECK:STDOUT:     %DeriveFromIncomplete.ref.loc105: type = name_ref DeriveFromIncomplete, %DeriveFromIncomplete.decl [template = constants.%DeriveFromIncomplete]
 // CHECK:STDOUT:     %.loc105: type = ptr_type DeriveFromIncomplete [template = constants.%.19]
 // CHECK:STDOUT:     %p.loc105_42.1: DeriveFromIncomplete* = param p
@@ -287,7 +313,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseIncomplete.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %DeriveFromFinal.decl: type = class_decl @DeriveFromFinal [template = constants.%DeriveFromFinal] {}
-// CHECK:STDOUT:   %ConvertToBadBaseFinal: <function> = fn_decl @ConvertToBadBaseFinal [template] {
+// CHECK:STDOUT:   %ConvertToBadBaseFinal.decl: ConvertToBadBaseFinal = fn_decl @ConvertToBadBaseFinal [template = constants.%struct.11] {
 // CHECK:STDOUT:     %DeriveFromFinal.ref.loc116: type = name_ref DeriveFromFinal, %DeriveFromFinal.decl [template = constants.%DeriveFromFinal]
 // CHECK:STDOUT:     %.loc116_44: type = ptr_type DeriveFromFinal [template = constants.%.24]
 // CHECK:STDOUT:     %p.loc116_26.1: DeriveFromFinal* = param p
@@ -296,14 +322,14 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:     %.loc116_55: type = ptr_type Final [template = constants.%.25]
 // CHECK:STDOUT:     @ConvertToBadBaseFinal.%return: ref Final* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember.decl: AccessMemberWithInvalidBaseFinal_WithMember = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember [template = constants.%struct.12] {
 // CHECK:STDOUT:     %DeriveFromFinal.ref.loc120: type = name_ref DeriveFromFinal, %DeriveFromFinal.decl [template = constants.%DeriveFromFinal]
 // CHECK:STDOUT:     %.loc120: type = ptr_type DeriveFromFinal [template = constants.%.24]
 // CHECK:STDOUT:     %p.loc120_48.1: DeriveFromFinal* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseFinal_WithMember.%p: DeriveFromFinal* = bind_name p, %p.loc120_48.1
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseFinal_WithMember.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember [template] {
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember.decl: AccessMemberWithInvalidBaseFinal_NoMember = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember [template = constants.%struct.13] {
 // CHECK:STDOUT:     %DeriveFromFinal.ref.loc124: type = name_ref DeriveFromFinal, %DeriveFromFinal.decl [template = constants.%DeriveFromFinal]
 // CHECK:STDOUT:     %.loc124: type = ptr_type DeriveFromFinal [template = constants.%.24]
 // CHECK:STDOUT:     %p.loc124_46.1: DeriveFromFinal* = param p
@@ -336,7 +362,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromNonType {
-// CHECK:STDOUT:   %.loc28_16: i32 = int_literal 32 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc28_16: i32 = int_literal 32 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc28_18: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -357,7 +383,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: class @DeriveFromTuple {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc56_22.1: (type,) = tuple_literal (%Base.ref)
-// CHECK:STDOUT:   %.loc56_22.2: type = converted %.loc56_22.1, constants.%.10 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc56_22.2: type = converted %.loc56_22.1, constants.%.11 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc56_23: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:

+ 17 - 9
toolchain/check/testdata/class/fail_base_method_define.carbon

@@ -31,13 +31,21 @@ fn D.C.F() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
-// CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F.2: type = fn_type @F.2 [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %D: type = class_type @D [template]
-// CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type D, B [template]
 // CHECK:STDOUT:   %.5: type = struct_type {.base: B} [template]
+// CHECK:STDOUT:   %F.3: type = fn_type @F.3 [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %.6: type = fn_type @.1 [template]
+// CHECK:STDOUT:   %struct.4: <invalid> = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -49,26 +57,26 @@ fn D.C.F() {}
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %D.decl: type = class_decl @D [template = constants.%D] {}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.3 [template] {}
-// CHECK:STDOUT:   %.loc28: <function> = fn_decl @.1 [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.3 [template = constants.%struct.3] {}
+// CHECK:STDOUT:   %.decl: <invalid> = fn_decl @.1 [template = constants.%struct.4] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   .C = %C.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.2] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%C
-// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
@@ -78,7 +86,7 @@ fn D.C.F() {}
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT:   .base = %.loc16
-// CHECK:STDOUT:   .F = file.%F
+// CHECK:STDOUT:   .F = file.%F.decl
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 0
toolchain/check/testdata/class/fail_base_misplaced.carbon

@@ -28,6 +28,9 @@ fn F() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}

+ 7 - 4
toolchain/check/testdata/class/fail_compound_type_mismatch.carbon

@@ -28,8 +28,11 @@ fn AccessBInA(a: A) -> i32 {
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %.3: type = unbound_element_type B, i32 [template]
 // CHECK:STDOUT:   %.4: type = struct_type {.b: i32} [template]
-// CHECK:STDOUT:   %.5: type = ptr_type {.a: i32} [template]
-// CHECK:STDOUT:   %.6: type = ptr_type {.b: i32} [template]
+// CHECK:STDOUT:   %AccessBInA: type = fn_type @AccessBInA [template]
+// CHECK:STDOUT:   %.5: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: AccessBInA = struct_value () [template]
+// CHECK:STDOUT:   %.6: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.7: type = ptr_type {.b: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -37,12 +40,12 @@ fn AccessBInA(a: A) -> i32 {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .A = %A.decl
 // CHECK:STDOUT:     .B = %B.decl
-// CHECK:STDOUT:     .AccessBInA = %AccessBInA
+// CHECK:STDOUT:     .AccessBInA = %AccessBInA.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
-// CHECK:STDOUT:   %AccessBInA: <function> = fn_decl @AccessBInA [template] {
+// CHECK:STDOUT:   %AccessBInA.decl: AccessBInA = fn_decl @AccessBInA [template = constants.%struct] {
 // CHECK:STDOUT:     %A.ref: type = name_ref A, %A.decl [template = constants.%A]
 // CHECK:STDOUT:     %a.loc15_15.1: A = param a
 // CHECK:STDOUT:     @AccessBInA.%a: A = bind_name a, %a.loc15_15.1

Некоторые файлы не были показаны из-за большого количества измененных файлов