Browse Source

Switch type literals to use builtin functions. (#3978)

Modifies the core package and literal handling to use factory functions
for standard type literals.

Updates function/builtin/import.carbon to stop depending on the prelude,
since it would list all the impls in the core file. Updates
alias/builtins.carbon to be failing (the type values cannot be aliased).
Jon Ross-Perkins 1 year ago
parent
commit
55300d1ebb
100 changed files with 6035 additions and 1911 deletions
  1. 0 6
      core/prelude.carbon
  2. 2 0
      core/prelude/operators/comparison.carbon
  3. 6 1
      core/prelude/types.carbon
  4. 7 0
      core/prelude/types/bool.carbon
  5. 2 0
      core/prelude/types/i32.carbon
  6. 16 23
      toolchain/check/handle_literal.cpp
  7. 0 36
      toolchain/check/testdata/alias/builtins.carbon
  8. 9 0
      toolchain/check/testdata/alias/fail_bool_value.carbon
  9. 46 0
      toolchain/check/testdata/alias/fail_builtins.carbon
  10. 41 13
      toolchain/check/testdata/array/array_in_place.carbon
  11. 24 4
      toolchain/check/testdata/array/array_vs_tuple.carbon
  12. 22 10
      toolchain/check/testdata/array/assign_return_value.carbon
  13. 44 23
      toolchain/check/testdata/array/assign_var.carbon
  14. 59 41
      toolchain/check/testdata/array/base.carbon
  15. 28 4
      toolchain/check/testdata/array/canonicalize_index.carbon
  16. 20 4
      toolchain/check/testdata/array/fail_bound_negative.carbon
  17. 12 3
      toolchain/check/testdata/array/fail_bound_overflow.carbon
  18. 20 11
      toolchain/check/testdata/array/fail_out_of_bound.carbon
  19. 38 25
      toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon
  20. 69 36
      toolchain/check/testdata/array/fail_type_mismatch.carbon
  21. 8 0
      toolchain/check/testdata/array/fail_undefined_bound.carbon
  22. 33 13
      toolchain/check/testdata/array/function_param.carbon
  23. 38 25
      toolchain/check/testdata/array/index_not_literal.carbon
  24. 52 43
      toolchain/check/testdata/array/nine_elements.carbon
  25. 100 45
      toolchain/check/testdata/as/adapter_conversion.carbon
  26. 18 5
      toolchain/check/testdata/as/as_type.carbon
  27. 17 5
      toolchain/check/testdata/as/basic.carbon
  28. 30 9
      toolchain/check/testdata/as/fail_no_conversion.carbon
  29. 13 4
      toolchain/check/testdata/as/fail_not_type.carbon
  30. 29 8
      toolchain/check/testdata/basics/builtin_types.carbon
  31. 11 3
      toolchain/check/testdata/basics/fail_bad_run_2.carbon
  32. 35 0
      toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon
  33. 16 0
      toolchain/check/testdata/basics/fail_qualifier_unsupported.carbon
  34. 43 25
      toolchain/check/testdata/basics/numeric_literals.carbon
  35. 17 4
      toolchain/check/testdata/basics/parens.carbon
  36. 11 3
      toolchain/check/testdata/basics/run_i32.carbon
  37. 102 40
      toolchain/check/testdata/basics/type_literals.carbon
  38. 183 31
      toolchain/check/testdata/builtins/float/add.carbon
  39. 209 47
      toolchain/check/testdata/builtins/float/div.carbon
  40. 86 29
      toolchain/check/testdata/builtins/float/eq.carbon
  41. 103 56
      toolchain/check/testdata/builtins/float/greater.carbon
  42. 103 56
      toolchain/check/testdata/builtins/float/greater_eq.carbon
  43. 103 56
      toolchain/check/testdata/builtins/float/less.carbon
  44. 103 56
      toolchain/check/testdata/builtins/float/less_eq.carbon
  45. 38 14
      toolchain/check/testdata/builtins/float/make_type.carbon
  46. 183 31
      toolchain/check/testdata/builtins/float/mul.carbon
  47. 158 31
      toolchain/check/testdata/builtins/float/negate.carbon
  48. 86 29
      toolchain/check/testdata/builtins/float/neq.carbon
  49. 183 31
      toolchain/check/testdata/builtins/float/sub.carbon
  50. 43 7
      toolchain/check/testdata/builtins/int/and.carbon
  51. 50 10
      toolchain/check/testdata/builtins/int/complement.carbon
  52. 61 13
      toolchain/check/testdata/builtins/int/eq.carbon
  53. 57 17
      toolchain/check/testdata/builtins/int/greater.carbon
  54. 57 17
      toolchain/check/testdata/builtins/int/greater_eq.carbon
  55. 113 21
      toolchain/check/testdata/builtins/int/left_shift.carbon
  56. 57 17
      toolchain/check/testdata/builtins/int/less.carbon
  57. 57 17
      toolchain/check/testdata/builtins/int/less_eq.carbon
  58. 51 23
      toolchain/check/testdata/builtins/int/make_type_signed.carbon
  59. 51 23
      toolchain/check/testdata/builtins/int/make_type_unsigned.carbon
  60. 42 10
      toolchain/check/testdata/builtins/int/neq.carbon
  61. 43 7
      toolchain/check/testdata/builtins/int/or.carbon
  62. 144 28
      toolchain/check/testdata/builtins/int/right_shift.carbon
  63. 196 34
      toolchain/check/testdata/builtins/int/sadd.carbon
  64. 137 29
      toolchain/check/testdata/builtins/int/sdiv.carbon
  65. 137 29
      toolchain/check/testdata/builtins/int/smod.carbon
  66. 72 12
      toolchain/check/testdata/builtins/int/smul.carbon
  67. 195 41
      toolchain/check/testdata/builtins/int/snegate.carbon
  68. 79 15
      toolchain/check/testdata/builtins/int/ssub.carbon
  69. 196 34
      toolchain/check/testdata/builtins/int/uadd.carbon
  70. 137 29
      toolchain/check/testdata/builtins/int/udiv.carbon
  71. 137 29
      toolchain/check/testdata/builtins/int/umod.carbon
  72. 72 12
      toolchain/check/testdata/builtins/int/umul.carbon
  73. 195 41
      toolchain/check/testdata/builtins/int/unegate.carbon
  74. 79 15
      toolchain/check/testdata/builtins/int/usub.carbon
  75. 43 7
      toolchain/check/testdata/builtins/int/xor.carbon
  76. 29 8
      toolchain/check/testdata/class/adapt.carbon
  77. 45 25
      toolchain/check/testdata/class/base.carbon
  78. 52 24
      toolchain/check/testdata/class/base_field.carbon
  79. 22 14
      toolchain/check/testdata/class/base_method.carbon
  80. 51 23
      toolchain/check/testdata/class/base_method_qualified.carbon
  81. 47 11
      toolchain/check/testdata/class/basic.carbon
  82. 18 6
      toolchain/check/testdata/class/complete_in_member_fn.carbon
  83. 71 31
      toolchain/check/testdata/class/compound_field.carbon
  84. 9 9
      toolchain/check/testdata/class/cross_package_import.carbon
  85. 62 46
      toolchain/check/testdata/class/derived_to_base.carbon
  86. 71 30
      toolchain/check/testdata/class/extend_adapt.carbon
  87. 39 19
      toolchain/check/testdata/class/fail_abstract.carbon
  88. 57 12
      toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon
  89. 108 44
      toolchain/check/testdata/class/fail_base_bad_type.carbon
  90. 28 12
      toolchain/check/testdata/class/fail_compound_type_mismatch.carbon
  91. 38 22
      toolchain/check/testdata/class/fail_derived_to_base.carbon
  92. 33 12
      toolchain/check/testdata/class/fail_field_modifiers.carbon
  93. 33 21
      toolchain/check/testdata/class/fail_incomplete.carbon
  94. 21 9
      toolchain/check/testdata/class/fail_init.carbon
  95. 28 16
      toolchain/check/testdata/class/fail_init_as_inplace.carbon
  96. 13 5
      toolchain/check/testdata/class/fail_member_of_let.carbon
  97. 17 5
      toolchain/check/testdata/class/fail_scope.carbon
  98. 14 7
      toolchain/check/testdata/class/fail_self_type_member.carbon
  99. 26 14
      toolchain/check/testdata/class/fail_todo_modifiers.carbon
  100. 26 10
      toolchain/check/testdata/class/fail_unbound_field.carbon

+ 0 - 6
core/prelude.carbon

@@ -8,9 +8,3 @@ package Core library "prelude";
 
 export import library "prelude/operators";
 export import library "prelude/types";
-
-// TODO: Uncomment once name deduplication works.
-// TODO: These are here for name lookup. Add a way to export import and move them out.
-// fn Int32() -> type = "int.make_type_32";
-// fn Float(size: i32) -> type = "float.make_type";
-// fn Bool() -> type = "bool.make_type";

+ 2 - 0
core/prelude/operators/comparison.carbon

@@ -4,6 +4,8 @@
 
 package Core library "prelude/operators/comparison";
 
+export import library "prelude/types/bool";
+
 // Equality comparison: `a == b` and `a != b`.
 interface Eq {
   fn Equal[self: Self](other: Self) -> bool;

+ 6 - 1
core/prelude/types.carbon

@@ -4,9 +4,14 @@
 
 package Core library "prelude/types";
 
-// TODO: Add a mechanism to re-export the names declared here.
+export import library "prelude/types/bool";
 
 // TODO: Start importing `prelude/types/i32` here once we stop eagerly importing
 // all `impl`s from all imported files. Currently, this introduces too much
 // noise in the toolchain tests.
 // import library "prelude/types/i32";
+
+fn Int32() -> type = "int.make_type_32";
+fn Int(size: i32) -> type = "int.make_type_signed";
+fn UInt(size: i32) -> type = "int.make_type_unsigned";
+fn Float(size: i32) -> type = "float.make_type";

+ 7 - 0
core/prelude/types/bool.carbon

@@ -0,0 +1,7 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+package Core library "prelude/types/bool";
+
+fn Bool() -> type = "bool.make_type";

+ 2 - 0
core/prelude/types/i32.carbon

@@ -4,6 +4,8 @@
 
 package Core library "prelude/types/i32";
 
+// For Int32():
+import library "prelude/types";
 import library "prelude/operators";
 
 impl i32 as Add {

+ 16 - 23
toolchain/check/handle_literal.cpp

@@ -113,11 +113,9 @@ auto HandleStringLiteral(Context& context, Parse::StringLiteralId node_id)
 
 auto HandleBoolTypeLiteral(Context& context, Parse::BoolTypeLiteralId node_id)
     -> bool {
-  // TODO: Migrate once functions can be in prelude.carbon.
-  // auto fn_inst_id = context.LookupNameInCore(node_id, "Bool");
-  // auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {});
-  // context.node_stack().Push(node_id, type_inst_id);
-  context.node_stack().Push(node_id, SemIR::InstId::BuiltinBoolType);
+  auto fn_inst_id = context.LookupNameInCore(node_id, "Bool");
+  auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {});
+  context.node_stack().Push(node_id, type_inst_id);
   return true;
 }
 
@@ -135,13 +133,11 @@ static auto HandleIntOrUnsignedIntTypeLiteral(Context& context,
         node_id, IntWidthNotMultipleOf8, int_kind.is_signed() ? "Int" : "UInt",
         llvm::APSInt(context.ints().Get(size_id), /*isUnsigned=*/true));
   }
-  // TODO: Migrate to a call to `Core.Int` or `Core.UInt`.
   auto width_id = MakeI32Literal(context, node_id, size_id);
-  context.AddInstAndPush(
-      {node_id, SemIR::IntType{.type_id = context.GetBuiltinType(
-                                   SemIR::BuiltinKind::TypeType),
-                               .int_kind = int_kind,
-                               .bit_width_id = width_id}});
+  auto fn_inst_id = context.LookupNameInCore(
+      node_id, int_kind == SemIR::IntKind::Signed ? "Int" : "UInt");
+  auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {width_id});
+  context.node_stack().Push(node_id, type_inst_id);
   return true;
 }
 
@@ -152,7 +148,9 @@ auto HandleIntTypeLiteral(Context& context, Parse::IntTypeLiteralId node_id)
   // Special case: `i32` has a custom builtin for now.
   // TODO: Remove this special case.
   if (context.ints().Get(size_id) == 32) {
-    context.node_stack().Push(node_id, SemIR::InstId::BuiltinIntType);
+    auto fn_inst_id = context.LookupNameInCore(node_id, "Int32");
+    auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {});
+    context.node_stack().Push(node_id, type_inst_id);
     return true;
   }
   return HandleIntOrUnsignedIntTypeLiteral(context, node_id,
@@ -175,17 +173,12 @@ auto HandleFloatTypeLiteral(Context& context, Parse::FloatTypeLiteralId node_id)
   if (text != "f64") {
     return context.TODO(node_id, "Currently only f64 is allowed");
   }
-  // TODO: Migrate once functions can be in prelude.carbon.
-  // auto fn_inst_id = context.LookupNameInCore(node_id, "Float");
-  // auto width_inst_id = context.AddInstInNoBlock(
-  //     {node_id,
-  //      SemIR::IntLiteral{
-  //          context.GetBuiltinType(SemIR::BuiltinKind::IntType),
-  //          context.ints().Add(llvm::APInt(/*numBits=*/32, /*val=*/64))}});
-  // auto type_inst_id =
-  //     PerformCall(context, node_id, fn_inst_id, {width_inst_id});
-  // context.node_stack().Push(node_id, type_inst_id);
-  context.node_stack().Push(node_id, SemIR::InstId::BuiltinFloatType);
+  auto tok_id = context.parse_tree().node_token(node_id);
+  auto size_id = context.tokens().GetTypeLiteralSize(tok_id);
+  auto width_id = MakeI32Literal(context, node_id, size_id);
+  auto fn_inst_id = context.LookupNameInCore(node_id, "Float");
+  auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {width_id});
+  context.node_stack().Push(node_id, type_inst_id);
   return true;
 }
 

+ 0 - 36
toolchain/check/testdata/alias/builtins.carbon

@@ -1,36 +0,0 @@
-// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
-// Exceptions. See /LICENSE for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-// AUTOUPDATE
-
-alias a = i32;
-let a_test: a = 0;
-
-alias b = bool;
-let b_test: b = false;
-
-// CHECK:STDOUT: --- builtins.carbon
-// CHECK:STDOUT:
-// CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.2: bool = bool_literal false [template]
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
-// CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Core = %Core
-// CHECK:STDOUT:     .a = %a
-// CHECK:STDOUT:     .b = %b
-// CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %a: type = bind_alias a, i32 [template = i32]
-// CHECK:STDOUT:   %a.ref: type = name_ref a, %a [template = i32]
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 0 [template = constants.%.1]
-// CHECK:STDOUT:   %a_test: i32 = bind_name a_test, %.loc8
-// CHECK:STDOUT:   %b: type = bind_alias b, bool [template = bool]
-// CHECK:STDOUT:   %b.ref: type = name_ref b, %b [template = bool]
-// CHECK:STDOUT:   %.loc11: bool = bool_literal false [template = constants.%.2]
-// CHECK:STDOUT:   %b_test: bool = bind_name b_test, %.loc11
-// CHECK:STDOUT: }
-// CHECK:STDOUT:

+ 9 - 0
toolchain/check/testdata/alias/fail_bool_value.carbon

@@ -14,6 +14,9 @@ let a_test: bool = a;
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: bool = bool_literal false [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Bool = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -24,7 +27,13 @@ let a_test: bool = a;
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.loc10: bool = bool_literal false [template = constants.%.1]
 // CHECK:STDOUT:   %a: <error> = bind_alias a, <error> [template = <error>]
+// CHECK:STDOUT:   %import_ref: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %bool.make_type: init type = call constants.%struct() [template = bool]
+// CHECK:STDOUT:   %.loc11_13.1: type = value_of_initializer %bool.make_type [template = bool]
+// CHECK:STDOUT:   %.loc11_13.2: type = converted %bool.make_type, %.loc11_13.1 [template = bool]
 // CHECK:STDOUT:   %a.ref: <error> = name_ref a, %a [template = <error>]
 // CHECK:STDOUT:   %a_test: bool = bind_name a_test, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:

+ 46 - 0
toolchain/check/testdata/alias/fail_builtins.carbon

@@ -0,0 +1,46 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+// CHECK:STDERR: fail_builtins.carbon:[[@LINE+4]]:11: ERROR: Alias initializer must be a name reference.
+// CHECK:STDERR: alias a = i32;
+// CHECK:STDERR:           ^~~
+// CHECK:STDERR:
+alias a = i32;
+
+// CHECK:STDERR: fail_builtins.carbon:[[@LINE+3]]:11: ERROR: Alias initializer must be a name reference.
+// CHECK:STDERR: alias b = bool;
+// CHECK:STDERR:           ^~~~
+alias b = bool;
+
+// CHECK:STDOUT: --- fail_builtins.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = 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:     .b = %b
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %a: <error> = bind_alias a, <error> [template = <error>]
+// CHECK:STDOUT:   %import_ref.2: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %bool.make_type: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:   %b: <error> = bind_alias b, <error> [template = <error>]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:

+ 41 - 13
toolchain/check/testdata/array/array_in_place.carbon

@@ -13,13 +13,15 @@ fn G() {
 // CHECK:STDOUT: --- array_in_place.carbon
 // CHECK:STDOUT:
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (i32, i32, i32) [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:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -36,31 +38,57 @@ fn G() {
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %int.make_type_32.loc7_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %int.make_type_32.loc7_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_25.1: (type, type, type) = tuple_literal (%int.make_type_32.loc7_12, %int.make_type_32.loc7_17, %int.make_type_32.loc7_22)
+// CHECK:STDOUT:     %.loc7_25.2: type = value_of_initializer %int.make_type_32.loc7_12 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.3: type = converted %int.make_type_32.loc7_12, %.loc7_25.2 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.4: type = value_of_initializer %int.make_type_32.loc7_17 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.5: type = converted %int.make_type_32.loc7_17, %.loc7_25.4 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.6: type = value_of_initializer %int.make_type_32.loc7_22 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.7: type = converted %int.make_type_32.loc7_22, %.loc7_25.6 [template = i32]
+// CHECK:STDOUT:     %.loc7_25.8: type = converted %.loc7_25.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:     @F.%return: ref (i32, i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {}
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> (i32, i32, i32);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_25.1: (type, type, type) = tuple_literal (i32, i32, i32)
+// CHECK:STDOUT:   %int.make_type_32.loc10_12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc10_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc10_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_25.1: (type, type, type) = tuple_literal (%int.make_type_32.loc10_12, %int.make_type_32.loc10_17, %int.make_type_32.loc10_22)
 // 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_25.2: type = value_of_initializer %int.make_type_32.loc10_12 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.3: type = converted %int.make_type_32.loc10_12, %.loc10_25.2 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.4: type = value_of_initializer %int.make_type_32.loc10_17 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.5: type = converted %int.make_type_32.loc10_17, %.loc10_25.4 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.6: type = value_of_initializer %int.make_type_32.loc10_22 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.7: type = converted %int.make_type_32.loc10_22, %.loc10_25.6 [template = i32]
+// CHECK:STDOUT:   %.loc10_25.8: type = converted %.loc10_25.1, constants.%.3 [template = constants.%.3]
 // 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: F = name_ref F, file.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref.loc10_34: F = name_ref F, file.%F.decl [template = constants.%struct.2]
 // 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.%.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: F = name_ref F, file.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref.loc10_39: F = name_ref F, file.%F.decl [template = constants.%struct.2]
 // 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.%.10]
 // CHECK:STDOUT:     %.loc10_42.5: ref (i32, i32, i32) = array_index %v.var, %.loc10_42.4

+ 24 - 4
toolchain/check/testdata/array/array_vs_tuple.carbon

@@ -15,7 +15,9 @@ fn G() {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: G = struct_value () [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.2: Int32 = 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]
@@ -35,12 +37,19 @@ fn G() {
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct] {}
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.1] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.2() [template = i32]
 // CHECK:STDOUT:   %.loc9_16: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc9_11.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_11.2: type = converted %int.make_type_32.loc9, %.loc9_11.1 [template = i32]
 // 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
@@ -60,8 +69,17 @@ fn G() {
 // 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.%.7 [template = constants.%.7]
+// CHECK:STDOUT:   %int.make_type_32.loc10_11: init type = call constants.%struct.2() [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc10_16: init type = call constants.%struct.2() [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc10_21: init type = call constants.%struct.2() [template = i32]
+// CHECK:STDOUT:   %.loc10_24.1: (type, type, type) = tuple_literal (%int.make_type_32.loc10_11, %int.make_type_32.loc10_16, %int.make_type_32.loc10_21)
+// CHECK:STDOUT:   %.loc10_24.2: type = value_of_initializer %int.make_type_32.loc10_11 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.3: type = converted %int.make_type_32.loc10_11, %.loc10_24.2 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.4: type = value_of_initializer %int.make_type_32.loc10_16 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.5: type = converted %int.make_type_32.loc10_16, %.loc10_24.4 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.6: type = value_of_initializer %int.make_type_32.loc10_21 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.7: type = converted %int.make_type_32.loc10_21, %.loc10_24.6 [template = i32]
+// CHECK:STDOUT:   %.loc10_24.8: 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.%.5]
@@ -80,3 +98,5 @@ fn G() {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 22 - 10
toolchain/check/testdata/array/assign_return_value.carbon

@@ -13,15 +13,17 @@ fn Run() {
 // CHECK:STDOUT: --- assign_return_value.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: type = tuple_type (type) [template]
-// CHECK:STDOUT:   %.2: type = tuple_type (i32) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = tuple_type (type) [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (i32) [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:   %struct.2: 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:   %struct.3: 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]
@@ -34,14 +36,21 @@ fn Run() {
 // CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_16.1: (type,) = tuple_literal (%int.make_type_32)
+// CHECK:STDOUT:     %.loc7_16.2: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc7_16.3: type = converted %int.make_type_32, %.loc7_16.2 [template = i32]
+// CHECK:STDOUT:     %.loc7_16.4: type = converted %.loc7_16.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:     @F.%return: ref (i32,) = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.3] {}
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> (i32,) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0 [template = constants.%.4]
@@ -53,11 +62,14 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_11.2: type = converted %int.make_type_32, %.loc10_11.1 [template = i32]
 // 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: F = name_ref F, file.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, file.%F.decl [template = constants.%struct.2]
 // 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

+ 44 - 23
toolchain/check/testdata/array/assign_var.carbon

@@ -10,16 +10,19 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT: --- assign_var.carbon
 // CHECK:STDOUT:
 // 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: type = ptr_type (i32, i32, i32) [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %tuple: (i32, i32, i32) = tuple_value (%.4, %.5, %.6) [template]
-// CHECK:STDOUT:   %.7: type = array_type %.6, i32 [template]
-// CHECK:STDOUT:   %.8: type = ptr_type [i32; 3] [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.4: type = ptr_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %tuple: (i32, i32, i32) = tuple_value (%.5, %.6, %.7) [template]
+// CHECK:STDOUT:   %.8: type = array_type %.7, i32 [template]
+// CHECK:STDOUT:   %.9: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -29,45 +32,63 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_22.1: (type, type, type) = tuple_literal (i32, i32, i32)
-// CHECK:STDOUT:   %.loc7_22.2: type = converted %.loc7_22.1, constants.%.2 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7_9: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7_14: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7_19: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc7_22.1: (type, type, type) = tuple_literal (%int.make_type_32.loc7_9, %int.make_type_32.loc7_14, %int.make_type_32.loc7_19)
+// CHECK:STDOUT:   %.loc7_22.2: type = value_of_initializer %int.make_type_32.loc7_9 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.3: type = converted %int.make_type_32.loc7_9, %.loc7_22.2 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.4: type = value_of_initializer %int.make_type_32.loc7_14 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.5: type = converted %int.make_type_32.loc7_14, %.loc7_22.4 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.6: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.7: type = converted %int.make_type_32.loc7_19, %.loc7_22.6 [template = i32]
+// CHECK:STDOUT:   %.loc7_22.8: type = converted %.loc7_22.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref (i32, i32, i32) = var a
 // CHECK:STDOUT:   %a: ref (i32, i32, i32) = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, i32 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc8_9.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_9.2: type = converted %int.make_type_32.loc8, %.loc8_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, i32 [template = constants.%.8]
 // CHECK:STDOUT:   %b.var: ref [i32; 3] = var b
 // CHECK:STDOUT:   %b: ref [i32; 3] = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc7_34.1: (i32, i32, i32) = tuple_literal (%.loc7_27, %.loc7_30, %.loc7_33)
 // CHECK:STDOUT:   %.loc7_34.2: ref i32 = tuple_access file.%a.var, element0
-// CHECK:STDOUT:   %.loc7_34.3: init i32 = initialize_from %.loc7_27 to %.loc7_34.2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_34.3: init i32 = initialize_from %.loc7_27 to %.loc7_34.2 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc7_34.4: ref i32 = tuple_access file.%a.var, element1
-// CHECK:STDOUT:   %.loc7_34.5: init i32 = initialize_from %.loc7_30 to %.loc7_34.4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_34.5: init i32 = initialize_from %.loc7_30 to %.loc7_34.4 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc7_34.6: ref i32 = tuple_access file.%a.var, element2
-// CHECK:STDOUT:   %.loc7_34.7: init i32 = initialize_from %.loc7_33 to %.loc7_34.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_34.7: init i32 = initialize_from %.loc7_33 to %.loc7_34.6 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc7_34.8: init (i32, i32, i32) = tuple_init (%.loc7_34.3, %.loc7_34.5, %.loc7_34.7) to file.%a.var [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc7_35: init (i32, i32, i32) = converted %.loc7_34.1, %.loc7_34.8 [template = constants.%tuple]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7_35
 // CHECK:STDOUT:   %a.ref: ref (i32, i32, i32) = name_ref a, file.%a
 // CHECK:STDOUT:   %.loc8_19.1: ref i32 = tuple_access %a.ref, element0
 // CHECK:STDOUT:   %.loc8_19.2: i32 = bind_value %.loc8_19.1
-// CHECK:STDOUT:   %.loc8_19.3: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc8_19.3: i32 = int_literal 0 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc8_19.4: ref i32 = array_index file.%b.var, %.loc8_19.3
 // CHECK:STDOUT:   %.loc8_19.5: init i32 = initialize_from %.loc8_19.2 to %.loc8_19.4
 // CHECK:STDOUT:   %.loc8_19.6: ref i32 = tuple_access %a.ref, element1
 // CHECK:STDOUT:   %.loc8_19.7: i32 = bind_value %.loc8_19.6
-// CHECK:STDOUT:   %.loc8_19.8: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_19.8: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc8_19.9: ref i32 = array_index file.%b.var, %.loc8_19.8
 // CHECK:STDOUT:   %.loc8_19.10: init i32 = initialize_from %.loc8_19.7 to %.loc8_19.9
 // CHECK:STDOUT:   %.loc8_19.11: ref i32 = tuple_access %a.ref, element2
 // CHECK:STDOUT:   %.loc8_19.12: i32 = bind_value %.loc8_19.11
-// CHECK:STDOUT:   %.loc8_19.13: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_19.13: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc8_19.14: ref i32 = array_index file.%b.var, %.loc8_19.13
 // CHECK:STDOUT:   %.loc8_19.15: init i32 = initialize_from %.loc8_19.12 to %.loc8_19.14
 // CHECK:STDOUT:   %.loc8_19.16: init [i32; 3] = array_init (%.loc8_19.5, %.loc8_19.10, %.loc8_19.15) to file.%b.var

+ 59 - 41
toolchain/check/testdata/array/base.carbon

@@ -11,27 +11,32 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT: --- base.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 1] [template]
-// CHECK:STDOUT:   %.4: type = tuple_type (i32) [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %array.1: [i32; 1] = tuple_value (%.1) [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.7: type = array_type %.6, f64 [template]
-// CHECK:STDOUT:   %.8: type = ptr_type [f64; 2] [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal 11.100000000000001 [template]
-// CHECK:STDOUT:   %.10: f64 = float_literal 2.2000000000000002 [template]
-// CHECK:STDOUT:   %.11: type = tuple_type (f64, f64) [template]
-// CHECK:STDOUT:   %array.2: [f64; 2] = tuple_value (%.9, %.10) [template]
-// CHECK:STDOUT:   %.12: type = tuple_type () [template]
-// CHECK:STDOUT:   %.13: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.14: type = array_type %.13, () [template]
-// CHECK:STDOUT:   %.15: type = ptr_type [(); 5] [template]
-// CHECK:STDOUT:   %.16: type = tuple_type ((), (), (), (), ()) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %.5: type = tuple_type (i32) [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %array.1: [i32; 1] = tuple_value (%.2) [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %struct.2: Float = struct_value () [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.9: type = array_type %.8, f64 [template]
+// CHECK:STDOUT:   %.10: type = ptr_type [f64; 2] [template]
+// CHECK:STDOUT:   %.11: f64 = float_literal 11.100000000000001 [template]
+// CHECK:STDOUT:   %.12: f64 = float_literal 2.2000000000000002 [template]
+// CHECK:STDOUT:   %.13: type = tuple_type (f64, f64) [template]
+// CHECK:STDOUT:   %array.2: [f64; 2] = tuple_value (%.11, %.12) [template]
+// CHECK:STDOUT:   %.14: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.15: type = array_type %.14, () [template]
+// CHECK:STDOUT:   %.16: type = ptr_type [(); 5] [template]
+// CHECK:STDOUT:   %.17: type = tuple_type ((), (), (), (), ()) [template]
 // CHECK:STDOUT:   %tuple: () = tuple_value () [template]
-// CHECK:STDOUT:   %.17: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.18: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.18: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.19: i32 = int_literal 4 [template]
 // CHECK:STDOUT:   %array.3: [(); 5] = tuple_value (%tuple, %tuple, %tuple, %tuple, %tuple) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -43,41 +48,54 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc7_9.2: type = converted %int.make_type_32, %.loc7_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref [i32; 1] = var a
 // CHECK:STDOUT:   %a: ref [i32; 1] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, f64 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc8_9.1: i32 = int_literal 64 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %float.make_type: init type = call constants.%struct.2(%.loc8_9.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc8_9.2: type = value_of_initializer %float.make_type [template = f64]
+// CHECK:STDOUT:   %.loc8_9.3: type = converted %float.make_type, %.loc8_9.2 [template = f64]
+// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, f64 [template = constants.%.9]
 // CHECK:STDOUT:   %b.var: ref [f64; 2] = var b
 // CHECK:STDOUT:   %b: ref [f64; 2] = bind_name b, %b.var
 // CHECK:STDOUT:   %.loc9_10.1: () = tuple_literal ()
-// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5 [template = constants.%.13]
-// CHECK:STDOUT:   %.loc9_10.2: type = converted %.loc9_10.1, constants.%.12 [template = constants.%.12]
-// CHECK:STDOUT:   %.loc9_14: type = array_type %.loc9_13, () [template = constants.%.14]
+// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5 [template = constants.%.14]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %.loc9_10.1, constants.%.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_14: type = array_type %.loc9_13, () [template = constants.%.15]
 // CHECK:STDOUT:   %c.var: ref [(); 5] = var c
 // CHECK:STDOUT:   %c: ref [(); 5] = bind_name c, %c.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_22.1: (i32,) = tuple_literal (%.loc7_20)
-// CHECK:STDOUT:   %.loc7_22.2: i32 = int_literal 0 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_22.2: i32 = int_literal 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc7_22.3: ref i32 = array_index file.%a.var, %.loc7_22.2
-// CHECK:STDOUT:   %.loc7_22.4: init i32 = initialize_from %.loc7_20 to %.loc7_22.3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_22.4: init i32 = initialize_from %.loc7_20 to %.loc7_22.3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_22.5: init [i32; 1] = array_init (%.loc7_22.4) to file.%a.var [template = constants.%array.1]
 // CHECK:STDOUT:   %.loc7_23: init [i32; 1] = converted %.loc7_22.1, %.loc7_22.5 [template = constants.%array.1]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7_23
-// CHECK:STDOUT:   %.loc8_20: f64 = float_literal 11.100000000000001 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc8_26: f64 = float_literal 2.2000000000000002 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc8_20: f64 = float_literal 11.100000000000001 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc8_26: f64 = float_literal 2.2000000000000002 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc8_30.1: (f64, f64) = tuple_literal (%.loc8_20, %.loc8_26)
-// CHECK:STDOUT:   %.loc8_30.2: i32 = int_literal 0 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_30.2: i32 = int_literal 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc8_30.3: ref f64 = array_index file.%b.var, %.loc8_30.2
-// CHECK:STDOUT:   %.loc8_30.4: init f64 = initialize_from %.loc8_20 to %.loc8_30.3 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc8_30.5: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_30.4: init f64 = initialize_from %.loc8_20 to %.loc8_30.3 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc8_30.5: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc8_30.6: ref f64 = array_index file.%b.var, %.loc8_30.5
-// CHECK:STDOUT:   %.loc8_30.7: init f64 = initialize_from %.loc8_26 to %.loc8_30.6 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc8_30.7: init f64 = initialize_from %.loc8_26 to %.loc8_30.6 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc8_30.8: init [f64; 2] = array_init (%.loc8_30.4, %.loc8_30.7) to file.%b.var [template = constants.%array.2]
 // CHECK:STDOUT:   %.loc8_31: init [f64; 2] = converted %.loc8_30.1, %.loc8_30.8 [template = constants.%array.2]
 // CHECK:STDOUT:   assign file.%b.var, %.loc8_31
@@ -87,23 +105,23 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   %.loc9_32.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc9_36.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc9_38.1: ((), (), (), (), ()) = tuple_literal (%.loc9_20.1, %.loc9_24.1, %.loc9_28.1, %.loc9_32.1, %.loc9_36.1)
-// CHECK:STDOUT:   %.loc9_38.2: i32 = int_literal 0 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_38.2: i32 = int_literal 0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc9_38.3: ref () = array_index file.%c.var, %.loc9_38.2
 // CHECK:STDOUT:   %.loc9_20.2: init () = tuple_init () to %.loc9_38.3 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc9_38.4: init () = converted %.loc9_20.1, %.loc9_20.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc9_38.5: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc9_38.5: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc9_38.6: ref () = array_index file.%c.var, %.loc9_38.5
 // CHECK:STDOUT:   %.loc9_24.2: init () = tuple_init () to %.loc9_38.6 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc9_38.7: init () = converted %.loc9_24.1, %.loc9_24.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc9_38.8: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_38.8: i32 = int_literal 2 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc9_38.9: ref () = array_index file.%c.var, %.loc9_38.8
 // CHECK:STDOUT:   %.loc9_28.2: init () = tuple_init () to %.loc9_38.9 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc9_38.10: init () = converted %.loc9_28.1, %.loc9_28.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc9_38.11: i32 = int_literal 3 [template = constants.%.17]
+// CHECK:STDOUT:   %.loc9_38.11: i32 = int_literal 3 [template = constants.%.18]
 // CHECK:STDOUT:   %.loc9_38.12: ref () = array_index file.%c.var, %.loc9_38.11
 // CHECK:STDOUT:   %.loc9_32.2: init () = tuple_init () to %.loc9_38.12 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc9_38.13: init () = converted %.loc9_32.1, %.loc9_32.2 [template = constants.%tuple]
-// CHECK:STDOUT:   %.loc9_38.14: i32 = int_literal 4 [template = constants.%.18]
+// CHECK:STDOUT:   %.loc9_38.14: i32 = int_literal 4 [template = constants.%.19]
 // CHECK:STDOUT:   %.loc9_38.15: ref () = array_index file.%c.var, %.loc9_38.14
 // CHECK:STDOUT:   %.loc9_36.2: init () = tuple_init () to %.loc9_38.15 [template = constants.%tuple]
 // CHECK:STDOUT:   %.loc9_38.16: init () = converted %.loc9_36.1, %.loc9_36.2 [template = constants.%tuple]

+ 28 - 4
toolchain/check/testdata/array/canonicalize_index.carbon

@@ -12,9 +12,11 @@ let b: [i32; 3]* = &a;
 // CHECK:STDOUT: --- canonicalize_index.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -32,21 +34,41 @@ let b: [i32; 3]* = &a;
 // CHECK:STDOUT:     .a = %a.loc9
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_11.1: type = value_of_initializer %int.make_type_32.loc7_11 [template = i32]
+// CHECK:STDOUT:     %.loc7_11.2: type = converted %int.make_type_32.loc7_11, %.loc7_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc7_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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_9.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_9.2: type = converted %int.make_type_32.loc9, %.loc9_9.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc10_9.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_9.2: type = converted %int.make_type_32.loc10, %.loc10_9.1 [template = i32]
 // 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
@@ -54,6 +76,8 @@ let b: [i32; 3]* = &a;
 // CHECK:STDOUT:   %b.loc10: [i32; 3]* = bind_name b, %.loc10_20
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: i32, %b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {

+ 20 - 4
toolchain/check/testdata/array/fail_bound_negative.carbon

@@ -14,9 +14,11 @@ var a: [i32; Negate(1)];
 // CHECK:STDOUT: --- fail_bound_negative.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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: }
@@ -28,18 +30,32 @@ var a: [i32; Negate(1)];
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_14.1: type = value_of_initializer %int.make_type_32.loc7_14 [template = i32]
+// CHECK:STDOUT:     %.loc7_14.2: type = converted %int.make_type_32.loc7_14, %.loc7_14.1 [template = i32]
 // CHECK:STDOUT:     %n.loc7_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc7_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_22.1: type = value_of_initializer %int.make_type_32.loc7_22 [template = i32]
+// CHECK:STDOUT:     %.loc7_22.2: type = converted %int.make_type_32.loc7_22, %.loc7_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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_9.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_9.2: type = converted %int.make_type_32.loc12, %.loc12_9.1 [template = i32]
 // 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
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%n: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:

+ 12 - 3
toolchain/check/testdata/array/fail_bound_overflow.carbon

@@ -25,7 +25,10 @@ var b: [1; 39999999999999999993];
 // CHECK:STDOUT: --- fail_bound_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -35,12 +38,18 @@ var b: [1; 39999999999999999993];
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc14: type = array_type <error>, i32 [template = <error>]
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc14_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc14_9.2: type = converted %int.make_type_32, %.loc14_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc14_34: type = array_type <error>, i32 [template = <error>]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc23_9: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc23_9: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc23_32: type = array_type <error>, <error> [template = <error>]
 // CHECK:STDOUT:   %b.var: ref <error> = var b
 // CHECK:STDOUT:   %b: ref <error> = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 20 - 11
toolchain/check/testdata/array/fail_out_of_bound.carbon

@@ -12,12 +12,15 @@ var a: [i32; 1] = (1, 2, 3);
 // CHECK:STDOUT: --- fail_out_of_bound.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 1] [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.6: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.7: type = tuple_type (i32, i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -26,17 +29,23 @@ var a: [i32; 1] = (1, 2, 3);
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_9.2: type = converted %int.make_type_32, %.loc10_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref [i32; 1] = var a
 // CHECK:STDOUT:   %a: ref [i32; 1] = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc10_27: (i32, i32, i32) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_26)
 // CHECK:STDOUT:   assign file.%a.var, <error>
 // CHECK:STDOUT:   return

+ 38 - 25
toolchain/check/testdata/array/fail_out_of_bound_non_literal.carbon

@@ -13,16 +13,19 @@ var b: i32 = a[{.index = 3}.index];
 // CHECK:STDOUT: --- fail_out_of_bound_non_literal.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 = struct_type {.index: i32} [template]
-// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.1) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 = struct_type {.index: i32} [template]
+// CHECK:STDOUT:   %struct.2: {.index: i32} = struct_value (%.2) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -32,38 +35,48 @@ var b: i32 = a[{.index = 3}.index];
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_9.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_9.2: type = converted %int.make_type_32.loc7, %.loc7_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, 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:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc11_8.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_8.2: type = converted %int.make_type_32.loc11, %.loc11_8.1 [template = i32]
 // CHECK:STDOUT:   %b.var: ref i32 = var b
 // CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_27.1: (i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26)
-// CHECK:STDOUT:   %.loc7_27.2: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_27.2: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc7_27.3: ref i32 = array_index file.%a.var, %.loc7_27.2
-// CHECK:STDOUT:   %.loc7_27.4: init i32 = initialize_from %.loc7_20 to %.loc7_27.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_27.5: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_27.4: init i32 = initialize_from %.loc7_20 to %.loc7_27.3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_27.5: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc7_27.6: ref i32 = array_index file.%a.var, %.loc7_27.5
-// CHECK:STDOUT:   %.loc7_27.7: init i32 = initialize_from %.loc7_23 to %.loc7_27.6 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_27.8: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_27.7: init i32 = initialize_from %.loc7_23 to %.loc7_27.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_27.8: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc7_27.9: ref i32 = array_index file.%a.var, %.loc7_27.8
-// CHECK:STDOUT:   %.loc7_27.10: init i32 = initialize_from %.loc7_26 to %.loc7_27.9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_27.10: init i32 = initialize_from %.loc7_26 to %.loc7_27.9 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_27.11: init [i32; 3] = array_init (%.loc7_27.4, %.loc7_27.7, %.loc7_27.10) to file.%a.var [template = constants.%array]
 // CHECK:STDOUT:   %.loc7_28: init [i32; 3] = converted %.loc7_27.1, %.loc7_27.11 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7_28
 // CHECK:STDOUT:   %a.ref: ref [i32; 3] = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc11_26: i32 = int_literal 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc11_26: i32 = int_literal 3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc11_27.1: {.index: i32} = struct_literal (%.loc11_26)
-// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.loc11_26) [template = constants.%struct]
-// CHECK:STDOUT:   %.loc11_27.2: {.index: i32} = converted %.loc11_27.1, %struct [template = constants.%struct]
-// CHECK:STDOUT:   %.loc11_28: i32 = struct_access %.loc11_27.2, element0 [template = constants.%.1]
+// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.loc11_26) [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc11_27.2: {.index: i32} = converted %.loc11_27.1, %struct [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc11_28: i32 = struct_access %.loc11_27.2, element0 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc11_34.1: ref i32 = array_index %a.ref, %.loc11_28 [template = <error>]
 // CHECK:STDOUT:   %.loc11_34.2: i32 = bind_value %.loc11_34.1
 // CHECK:STDOUT:   assign file.%b.var, %.loc11_34.2

+ 69 - 36
toolchain/check/testdata/array/fail_type_mismatch.carbon

@@ -32,22 +32,25 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT: --- fail_type_mismatch.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: type = ptr_type String [template]
-// CHECK:STDOUT:   %.6: String = string_literal "Hello" [template]
-// CHECK:STDOUT:   %.7: String = string_literal "World" [template]
-// CHECK:STDOUT:   %.8: type = tuple_type (i32, String, String) [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.10: type = tuple_type (type, type, type) [template]
-// CHECK:STDOUT:   %.11: type = tuple_type (i32, String*, String*) [template]
-// CHECK:STDOUT:   %.12: type = ptr_type (i32, String*, String*) [template]
-// CHECK:STDOUT:   %.13: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.14: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.15: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.16: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = 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: type = ptr_type String [template]
+// CHECK:STDOUT:   %.7: String = string_literal "Hello" [template]
+// CHECK:STDOUT:   %.8: String = string_literal "World" [template]
+// CHECK:STDOUT:   %.9: type = tuple_type (i32, String, String) [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.11: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.12: type = tuple_type (i32, String*, String*) [template]
+// CHECK:STDOUT:   %.13: type = ptr_type (i32, String*, String*) [template]
+// CHECK:STDOUT:   %.14: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.15: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.16: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.17: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -61,52 +64,82 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc11_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc11_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_9.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_9.2: type = converted %int.make_type_32.loc11, %.loc11_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc11_15: type = array_type %.loc11_14, 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:   %.loc13_29.1: (type, type, type) = tuple_literal (i32, String, String)
-// CHECK:STDOUT:   %.loc13_29.2: type = converted %.loc13_29.1, constants.%.8 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc13_29.1: (type, type, type) = tuple_literal (%int.make_type_32.loc13, String, String)
+// CHECK:STDOUT:   %.loc13_29.2: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
+// CHECK:STDOUT:   %.loc13_29.3: type = converted %int.make_type_32.loc13, %.loc13_29.2 [template = i32]
+// CHECK:STDOUT:   %.loc13_29.4: type = converted %.loc13_29.1, constants.%.9 [template = constants.%.9]
 // CHECK:STDOUT:   %t1.var: ref (i32, String, String) = var t1
 // CHECK:STDOUT:   %t1: ref (i32, String, String) = bind_name t1, %t1.var
-// CHECK:STDOUT:   %.loc18_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc18_15: type = array_type %.loc18_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc18: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc18_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc18_9.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
+// CHECK:STDOUT:   %.loc18_9.2: type = converted %int.make_type_32.loc18, %.loc18_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc18_15: type = array_type %.loc18_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %b.var: ref [i32; 3] = var b
 // CHECK:STDOUT:   %b: ref [i32; 3] = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc24_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc24_15: type = array_type %.loc24_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc24: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc24_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc24_9.1: type = value_of_initializer %int.make_type_32.loc24 [template = i32]
+// CHECK:STDOUT:   %.loc24_9.2: type = converted %int.make_type_32.loc24, %.loc24_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc24_15: type = array_type %.loc24_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %c.var: ref [i32; 3] = var c
 // CHECK:STDOUT:   %c: ref [i32; 3] = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc26_18.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc26_18.2: type = converted %.loc26_18.1, constants.%.14 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc26_10: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc26_15: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc26_18.1: (type, type) = tuple_literal (%int.make_type_32.loc26_10, %int.make_type_32.loc26_15)
+// CHECK:STDOUT:   %.loc26_18.2: type = value_of_initializer %int.make_type_32.loc26_10 [template = i32]
+// CHECK:STDOUT:   %.loc26_18.3: type = converted %int.make_type_32.loc26_10, %.loc26_18.2 [template = i32]
+// CHECK:STDOUT:   %.loc26_18.4: type = value_of_initializer %int.make_type_32.loc26_15 [template = i32]
+// CHECK:STDOUT:   %.loc26_18.5: type = converted %int.make_type_32.loc26_15, %.loc26_18.4 [template = i32]
+// CHECK:STDOUT:   %.loc26_18.6: type = converted %.loc26_18.1, constants.%.15 [template = constants.%.15]
 // CHECK:STDOUT:   %t2.var: ref (i32, i32) = var t2
 // CHECK:STDOUT:   %t2: ref (i32, i32) = bind_name t2, %t2.var
-// CHECK:STDOUT:   %.loc30_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc30_15: type = array_type %.loc30_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc30_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc30_9.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
+// CHECK:STDOUT:   %.loc30_9.2: type = converted %int.make_type_32.loc30, %.loc30_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc30_15: type = array_type %.loc30_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %d.var: ref [i32; 3] = var d
 // CHECK:STDOUT:   %d: ref [i32; 3] = bind_name d, %d.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc11_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_23: String = string_literal "Hello" [template = constants.%.6]
-// CHECK:STDOUT:   %.loc11_32: String = string_literal "World" [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_23: String = string_literal "Hello" [template = constants.%.7]
+// CHECK:STDOUT:   %.loc11_32: String = string_literal "World" [template = constants.%.8]
 // CHECK:STDOUT:   %.loc11_39.1: (i32, String, String) = tuple_literal (%.loc11_20, %.loc11_23, %.loc11_32)
-// CHECK:STDOUT:   %.loc11_39.2: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_39.2: i32 = int_literal 0 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc11_39.3: ref i32 = array_index file.%a.var, %.loc11_39.2
-// CHECK:STDOUT:   %.loc11_39.4: init i32 = initialize_from %.loc11_20 to %.loc11_39.3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc11_39.4: init i32 = initialize_from %.loc11_20 to %.loc11_39.3 [template = constants.%.5]
 // CHECK:STDOUT:   assign file.%a.var, <error>
 // CHECK:STDOUT:   %t1.ref: ref (i32, String, String) = name_ref t1, file.%t1
 // CHECK:STDOUT:   %.loc18_19.1: ref i32 = tuple_access %t1.ref, element0
 // CHECK:STDOUT:   %.loc18_19.2: i32 = bind_value %.loc18_19.1
-// CHECK:STDOUT:   %.loc18_19.3: i32 = int_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc18_19.3: i32 = int_literal 0 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc18_19.4: ref i32 = array_index file.%b.var, %.loc18_19.3
 // CHECK:STDOUT:   %.loc18_19.5: init i32 = initialize_from %.loc18_19.2 to %.loc18_19.4
 // CHECK:STDOUT:   %.loc18_19.6: ref String = tuple_access %t1.ref, element1
 // CHECK:STDOUT:   assign file.%b.var, <error>
-// CHECK:STDOUT:   %.loc24_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc24_23: i32 = int_literal 2 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc24_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc24_23: i32 = int_literal 2 [template = constants.%.14]
 // CHECK:STDOUT:   %.loc24_24: (i32, i32) = tuple_literal (%.loc24_20, %.loc24_23)
 // CHECK:STDOUT:   assign file.%c.var, <error>
 // CHECK:STDOUT:   %t2.ref: ref (i32, i32) = name_ref t2, file.%t2

+ 8 - 0
toolchain/check/testdata/array/fail_undefined_bound.carbon

@@ -11,5 +11,13 @@ var a: [i32; ];
 
 // CHECK:STDOUT: --- fail_undefined_bound.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {}
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 33 - 13
toolchain/check/testdata/array/function_param.carbon

@@ -15,19 +15,21 @@ fn G() -> i32 {
 // CHECK:STDOUT: --- function_param.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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [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:   %struct.2: 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:   %struct.3: 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:   %array: [i32; 3] = tuple_value (%.5, %.6, %.2) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -37,20 +39,38 @@ fn G() -> i32 {
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_17: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:     %.loc7_12.1: type = value_of_initializer %int.make_type_32.loc7_12 [template = i32]
+// CHECK:STDOUT:     %.loc7_12.2: type = converted %int.make_type_32.loc7_12, %.loc7_12.1 [template = i32]
+// CHECK:STDOUT:     %.loc7_18: type = array_type %.loc7_17, i32 [template = constants.%.3]
 // CHECK:STDOUT:     %arr.loc7_6.1: [i32; 3] = param arr
 // CHECK:STDOUT:     @F.%arr: [i32; 3] = bind_name arr, %arr.loc7_6.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_24: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_24.1: type = value_of_initializer %int.make_type_32.loc7_24 [template = i32]
+// CHECK:STDOUT:     %.loc7_24.2: type = converted %int.make_type_32.loc7_24, %.loc7_24.1 [template = i32]
 // CHECK:STDOUT:     %i.loc7_21.1: i32 = param i
 // CHECK:STDOUT:     @F.%i: i32 = bind_name i, %i.loc7_21.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_32.1: type = value_of_initializer %int.make_type_32.loc7_32 [template = i32]
+// CHECK:STDOUT:     %.loc7_32.2: type = converted %int.make_type_32.loc7_32, %.loc7_32.1 [template = i32]
 // CHECK:STDOUT:     @F.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc11_11.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:     %.loc11_11.2: type = converted %int.make_type_32.loc11, %.loc11_11.1 [template = i32]
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%arr: [i32; 3], %i: i32) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %arr.ref: [i32; 3] = name_ref arr, %arr
@@ -63,10 +83,10 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: F = name_ref F, file.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, file.%F.decl [template = constants.%struct.2]
 // 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_19: i32 = int_literal 3 [template = constants.%.2]
 // 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.%.5]
 // CHECK:STDOUT:   %.loc12_20.2: ref [i32; 3] = temporary_storage
@@ -78,7 +98,7 @@ fn G() -> i32 {
 // 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.11: init i32 = initialize_from %.loc12_19 to %.loc12_20.10 [template = constants.%.2]
 // 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]
 // CHECK:STDOUT:   %.loc12_11.1: init [i32; 3] = converted %.loc12_20.1, %.loc12_20.12 [template = constants.%array]
 // CHECK:STDOUT:   %.loc12_11.2: ref [i32; 3] = temporary %.loc12_20.2, %.loc12_11.1

+ 38 - 25
toolchain/check/testdata/array/index_not_literal.carbon

@@ -10,16 +10,19 @@ var b: i32 = a[{.index = 2}.index];
 // CHECK:STDOUT: --- index_not_literal.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 = struct_type {.index: i32} [template]
-// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.5) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 = struct_type {.index: i32} [template]
+// CHECK:STDOUT:   %struct.2: {.index: i32} = struct_value (%.6) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -29,38 +32,48 @@ var b: i32 = a[{.index = 2}.index];
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 3 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 3 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_9.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_9.2: type = converted %int.make_type_32.loc7, %.loc7_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, 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:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
 // CHECK:STDOUT:   %b.var: ref i32 = var b
 // CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_27.1: (i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26)
-// CHECK:STDOUT:   %.loc7_27.2: i32 = int_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_27.2: i32 = int_literal 0 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc7_27.3: ref i32 = array_index file.%a.var, %.loc7_27.2
-// CHECK:STDOUT:   %.loc7_27.4: init i32 = initialize_from %.loc7_20 to %.loc7_27.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_27.5: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_27.4: init i32 = initialize_from %.loc7_20 to %.loc7_27.3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_27.5: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc7_27.6: ref i32 = array_index file.%a.var, %.loc7_27.5
-// CHECK:STDOUT:   %.loc7_27.7: init i32 = initialize_from %.loc7_23 to %.loc7_27.6 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_27.8: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_27.7: init i32 = initialize_from %.loc7_23 to %.loc7_27.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_27.8: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc7_27.9: ref i32 = array_index file.%a.var, %.loc7_27.8
-// CHECK:STDOUT:   %.loc7_27.10: init i32 = initialize_from %.loc7_26 to %.loc7_27.9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_27.10: init i32 = initialize_from %.loc7_26 to %.loc7_27.9 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_27.11: init [i32; 3] = array_init (%.loc7_27.4, %.loc7_27.7, %.loc7_27.10) to file.%a.var [template = constants.%array]
 // CHECK:STDOUT:   %.loc7_28: init [i32; 3] = converted %.loc7_27.1, %.loc7_27.11 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7_28
 // CHECK:STDOUT:   %a.ref: ref [i32; 3] = name_ref a, file.%a
-// CHECK:STDOUT:   %.loc8_26: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_26: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc8_27.1: {.index: i32} = struct_literal (%.loc8_26)
-// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.loc8_26) [template = constants.%struct]
-// CHECK:STDOUT:   %.loc8_27.2: {.index: i32} = converted %.loc8_27.1, %struct [template = constants.%struct]
-// CHECK:STDOUT:   %.loc8_28: i32 = struct_access %.loc8_27.2, element0 [template = constants.%.5]
+// CHECK:STDOUT:   %struct: {.index: i32} = struct_value (%.loc8_26) [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_27.2: {.index: i32} = converted %.loc8_27.1, %struct [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_28: i32 = struct_access %.loc8_27.2, element0 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc8_34.1: ref i32 = array_index %a.ref, %.loc8_28
 // CHECK:STDOUT:   %.loc8_34.2: i32 = bind_value %.loc8_34.1
 // CHECK:STDOUT:   assign file.%b.var, %.loc8_34.2

+ 52 - 43
toolchain/check/testdata/array/nine_elements.carbon

@@ -9,20 +9,23 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
 // CHECK:STDOUT: --- nine_elements.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 9 [template]
-// CHECK:STDOUT:   %.2: type = array_type %.1, i32 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type [i32; 9] [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %.6: i32 = int_literal 3 [template]
-// CHECK:STDOUT:   %.7: i32 = int_literal 4 [template]
-// CHECK:STDOUT:   %.8: i32 = int_literal 5 [template]
-// CHECK:STDOUT:   %.9: i32 = int_literal 6 [template]
-// CHECK:STDOUT:   %.10: i32 = int_literal 7 [template]
-// CHECK:STDOUT:   %.11: i32 = int_literal 8 [template]
-// CHECK:STDOUT:   %.12: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32) [template]
-// CHECK:STDOUT:   %.13: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %array: [i32; 9] = tuple_value (%.4, %.5, %.6, %.7, %.8, %.9, %.10, %.11, %.1) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 9 [template]
+// CHECK:STDOUT:   %.3: type = array_type %.2, i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type [i32; 9] [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.7: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.8: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.9: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.10: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.11: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.12: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.13: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32) [template]
+// CHECK:STDOUT:   %.14: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %array: [i32; 9] = tuple_value (%.5, %.6, %.7, %.8, %.9, %.10, %.11, %.12, %.2) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -31,51 +34,57 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc7_9.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc7_9.2: type = converted %int.make_type_32, %.loc7_9.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref [i32; 9] = var a
 // CHECK:STDOUT:   %a: ref [i32; 9] = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8 [template = constants.%.11]
-// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_45.1: (i32, i32, i32, i32, i32, i32, i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26, %.loc7_29, %.loc7_32, %.loc7_35, %.loc7_38, %.loc7_41, %.loc7_44)
-// CHECK:STDOUT:   %.loc7_45.2: i32 = int_literal 0 [template = constants.%.13]
+// CHECK:STDOUT:   %.loc7_45.2: i32 = int_literal 0 [template = constants.%.14]
 // CHECK:STDOUT:   %.loc7_45.3: ref i32 = array_index file.%a.var, %.loc7_45.2
-// CHECK:STDOUT:   %.loc7_45.4: init i32 = initialize_from %.loc7_20 to %.loc7_45.3 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc7_45.5: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc7_45.4: init i32 = initialize_from %.loc7_20 to %.loc7_45.3 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_45.5: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc7_45.6: ref i32 = array_index file.%a.var, %.loc7_45.5
-// CHECK:STDOUT:   %.loc7_45.7: init i32 = initialize_from %.loc7_23 to %.loc7_45.6 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc7_45.8: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc7_45.7: init i32 = initialize_from %.loc7_23 to %.loc7_45.6 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_45.8: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc7_45.9: ref i32 = array_index file.%a.var, %.loc7_45.8
-// CHECK:STDOUT:   %.loc7_45.10: init i32 = initialize_from %.loc7_26 to %.loc7_45.9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc7_45.11: i32 = int_literal 3 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc7_45.10: init i32 = initialize_from %.loc7_26 to %.loc7_45.9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_45.11: i32 = int_literal 3 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc7_45.12: ref i32 = array_index file.%a.var, %.loc7_45.11
-// CHECK:STDOUT:   %.loc7_45.13: init i32 = initialize_from %.loc7_29 to %.loc7_45.12 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc7_45.14: i32 = int_literal 4 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc7_45.13: init i32 = initialize_from %.loc7_29 to %.loc7_45.12 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc7_45.14: i32 = int_literal 4 [template = constants.%.8]
 // CHECK:STDOUT:   %.loc7_45.15: ref i32 = array_index file.%a.var, %.loc7_45.14
-// CHECK:STDOUT:   %.loc7_45.16: init i32 = initialize_from %.loc7_32 to %.loc7_45.15 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc7_45.17: i32 = int_literal 5 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc7_45.16: init i32 = initialize_from %.loc7_32 to %.loc7_45.15 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc7_45.17: i32 = int_literal 5 [template = constants.%.9]
 // CHECK:STDOUT:   %.loc7_45.18: ref i32 = array_index file.%a.var, %.loc7_45.17
-// CHECK:STDOUT:   %.loc7_45.19: init i32 = initialize_from %.loc7_35 to %.loc7_45.18 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc7_45.20: i32 = int_literal 6 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc7_45.19: init i32 = initialize_from %.loc7_35 to %.loc7_45.18 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc7_45.20: i32 = int_literal 6 [template = constants.%.10]
 // CHECK:STDOUT:   %.loc7_45.21: ref i32 = array_index file.%a.var, %.loc7_45.20
-// CHECK:STDOUT:   %.loc7_45.22: init i32 = initialize_from %.loc7_38 to %.loc7_45.21 [template = constants.%.10]
-// CHECK:STDOUT:   %.loc7_45.23: i32 = int_literal 7 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc7_45.22: init i32 = initialize_from %.loc7_38 to %.loc7_45.21 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc7_45.23: i32 = int_literal 7 [template = constants.%.11]
 // CHECK:STDOUT:   %.loc7_45.24: ref i32 = array_index file.%a.var, %.loc7_45.23
-// CHECK:STDOUT:   %.loc7_45.25: init i32 = initialize_from %.loc7_41 to %.loc7_45.24 [template = constants.%.11]
-// CHECK:STDOUT:   %.loc7_45.26: i32 = int_literal 8 [template = constants.%.11]
+// CHECK:STDOUT:   %.loc7_45.25: init i32 = initialize_from %.loc7_41 to %.loc7_45.24 [template = constants.%.12]
+// CHECK:STDOUT:   %.loc7_45.26: i32 = int_literal 8 [template = constants.%.12]
 // CHECK:STDOUT:   %.loc7_45.27: ref i32 = array_index file.%a.var, %.loc7_45.26
-// CHECK:STDOUT:   %.loc7_45.28: init i32 = initialize_from %.loc7_44 to %.loc7_45.27 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7_45.28: init i32 = initialize_from %.loc7_44 to %.loc7_45.27 [template = constants.%.2]
 // CHECK:STDOUT:   %.loc7_45.29: init [i32; 9] = array_init (%.loc7_45.4, %.loc7_45.7, %.loc7_45.10, %.loc7_45.13, %.loc7_45.16, %.loc7_45.19, %.loc7_45.22, %.loc7_45.25, %.loc7_45.28) to file.%a.var [template = constants.%array]
 // CHECK:STDOUT:   %.loc7_46: init [i32; 9] = converted %.loc7_45.1, %.loc7_45.29 [template = constants.%array]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7_46

+ 100 - 45
toolchain/check/testdata/as/adapter_conversion.carbon

@@ -102,15 +102,17 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A, i32 [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:   %struct.2: 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:   %struct.3: A = struct_value (%.5, %.6) [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %.7: type = ptr_type B [template]
 // CHECK:STDOUT: }
@@ -125,6 +127,8 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %A.ref.loc17: type = name_ref A, %A.decl [template = constants.%A]
 // CHECK:STDOUT:   %a_ref.var: ref A = var a_ref
@@ -153,17 +157,23 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // 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.decl: Make = fn_decl @Make [template = constants.%struct.1] {
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32.loc5, %.loc5_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc5_8: <unbound element of class A> = field_decl x, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc6_8: <unbound element of class A> = field_decl y, element1 [template]
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.2] {
 // 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:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .x = %.loc5
-// CHECK:STDOUT:   .y = %.loc6
+// CHECK:STDOUT:   .x = %.loc5_8
+// CHECK:STDOUT:   .y = %.loc6_8
 // CHECK:STDOUT:   .Make = %Make.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -175,6 +185,8 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> @A.%return.var: A {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc9_18: i32 = int_literal 1 [template = constants.%.5]
@@ -184,8 +196,8 @@ var b: B = {.x = 1} as B;
 // 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.%.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:   %.loc9_27.6: init A = class_init (%.loc9_27.3, %.loc9_27.5), @A.%return.var [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_28: init A = converted %.loc9_27.1, %.loc9_27.6 [template = constants.%struct.3]
 // CHECK:STDOUT:   return %.loc9_28 to @A.%return.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -198,11 +210,11 @@ var b: B = {.x = 1} as B;
 // 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.%.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:   %.loc17_31.6: init A = class_init (%.loc17_31.3, %.loc17_31.5), file.%a_ref.var [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc17_32: init A = converted %.loc17_31.1, %.loc17_31.6 [template = constants.%struct.3]
 // 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: Make = name_ref Make, @A.%Make.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Make.ref: Make = name_ref Make, @A.%Make.decl [template = constants.%struct.2]
 // 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]
@@ -216,7 +228,10 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A: type = class_type @A [template]
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -226,25 +241,43 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %A.ref.loc8_8: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc8_13: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_13: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_18.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_18.2: type = converted %int.make_type_32.loc8, %.loc8_18.1 [template = i32]
 // CHECK:STDOUT:   %A.ref.loc8_26: type = name_ref A, %A.decl [template = constants.%A]
-// CHECK:STDOUT:   %.loc8_23.1: A = as_compatible %.loc8_13 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc8_23.2: A = converted %.loc8_13, %.loc8_23.1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc8_23.1: A = as_compatible %.loc8_13 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8_23.2: A = converted %.loc8_13, %.loc8_23.1 [template = constants.%.2]
 // CHECK:STDOUT:   %a: A = bind_name a, %.loc8_23.2
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc9_8: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc9_8.1: type = value_of_initializer %int.make_type_32.loc9_8 [template = i32]
+// CHECK:STDOUT:   %.loc9_8.2: type = converted %int.make_type_32.loc9_8, %.loc9_8.1 [template = i32]
 // CHECK:STDOUT:   %a.ref: A = name_ref a, %a
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc9_19: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc9_19.1: type = value_of_initializer %int.make_type_32.loc9_19 [template = i32]
+// CHECK:STDOUT:   %.loc9_19.2: type = converted %int.make_type_32.loc9_19, %.loc9_19.1 [template = i32]
 // CHECK:STDOUT:   %.loc9_16.1: i32 = as_compatible %a.ref
 // CHECK:STDOUT:   %.loc9_16.2: i32 = converted %a.ref, %.loc9_16.1
 // CHECK:STDOUT:   %n: i32 = bind_name n, %.loc9_16.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc5_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc5_12.2: type = converted %int.make_type_32, %.loc5_12.1 [template = i32]
 // CHECK:STDOUT:   adapt_decl i32
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- multi_level_adapt.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -316,13 +349,16 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.x: i32, .y: i32} [template]
 // CHECK:STDOUT:   %B: type = class_type @B [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:   %.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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -334,18 +370,20 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %B.ref.loc13_14: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc13_33: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc13_33: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc13_34.1: {.x: i32, .y: i32} = struct_literal (%.loc13_25, %.loc13_33)
 // CHECK:STDOUT:   %A.ref: type = name_ref A, %A.decl [template = constants.%A]
 // CHECK:STDOUT:   %.loc13_34.2: ref A = temporary_storage
 // CHECK:STDOUT:   %.loc13_34.3: ref i32 = class_element_access %.loc13_34.2, element0
-// CHECK:STDOUT:   %.loc13_34.4: init i32 = initialize_from %.loc13_25 to %.loc13_34.3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc13_34.4: init i32 = initialize_from %.loc13_25 to %.loc13_34.3 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc13_34.5: ref i32 = class_element_access %.loc13_34.2, element1
-// CHECK:STDOUT:   %.loc13_34.6: init i32 = initialize_from %.loc13_33 to %.loc13_34.5 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc13_34.7: init A = class_init (%.loc13_34.4, %.loc13_34.6), %.loc13_34.2 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc13_34.6: init i32 = initialize_from %.loc13_33 to %.loc13_34.5 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc13_34.7: init A = class_init (%.loc13_34.4, %.loc13_34.6), %.loc13_34.2 [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc13_34.8: ref A = temporary %.loc13_34.2, %.loc13_34.7
 // CHECK:STDOUT:   %.loc13_36: ref A = converted %.loc13_34.1, %.loc13_34.8
 // CHECK:STDOUT:   %B.ref.loc13_45: type = name_ref B, %B.decl [template = constants.%B]
@@ -359,13 +397,19 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // 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:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32.loc5, %.loc5_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc5_8: <unbound element of class A> = field_decl x, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc6_8: <unbound element of class A> = field_decl y, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .x = %.loc5
-// CHECK:STDOUT:   .y = %.loc6
+// CHECK:STDOUT:   .x = %.loc5_8
+// CHECK:STDOUT:   .y = %.loc6_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
@@ -376,18 +420,20 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc24_24: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc24_32: i32 = int_literal 2 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc24_24: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc24_32: i32 = int_literal 2 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc24_33.1: {.x: i32, .y: i32} = struct_literal (%.loc24_24, %.loc24_32)
 // CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A.decl [template = constants.%A]
 // CHECK:STDOUT:   %.loc24_33.2: ref A = temporary_storage
 // CHECK:STDOUT:   %.loc24_33.3: ref i32 = class_element_access %.loc24_33.2, element0
-// CHECK:STDOUT:   %.loc24_33.4: init i32 = initialize_from %.loc24_24 to %.loc24_33.3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc24_33.4: init i32 = initialize_from %.loc24_24 to %.loc24_33.3 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc24_33.5: ref i32 = class_element_access %.loc24_33.2, element1
-// CHECK:STDOUT:   %.loc24_33.6: init i32 = initialize_from %.loc24_32 to %.loc24_33.5 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc24_33.7: init A = class_init (%.loc24_33.4, %.loc24_33.6), %.loc24_33.2 [template = constants.%struct]
+// CHECK:STDOUT:   %.loc24_33.6: init i32 = initialize_from %.loc24_32 to %.loc24_33.5 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc24_33.7: init A = class_init (%.loc24_33.4, %.loc24_33.6), %.loc24_33.2 [template = constants.%struct.2]
 // CHECK:STDOUT:   %.loc24_33.8: ref A = temporary %.loc24_33.2, %.loc24_33.7
 // CHECK:STDOUT:   %.loc24_35: ref A = converted %.loc24_33.1, %.loc24_33.8
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
@@ -402,11 +448,14 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:
 // 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} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.x: i32} [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.x: i32} [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.x: i32} [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -418,6 +467,7 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
 // CHECK:STDOUT:   %B.ref: type = name_ref B, %B.decl [template = constants.%B]
 // CHECK:STDOUT:   %b.var: ref B = var b
@@ -425,11 +475,14 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %.loc5: <unbound element of class A> = field_decl x, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32, %.loc5_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc5_8: <unbound element of class A> = field_decl x, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .x = %.loc5
+// CHECK:STDOUT:   .x = %.loc5_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
@@ -440,9 +493,11 @@ var b: B = {.x = 1} as B;
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc18_18: i32 = int_literal 1 [template = constants.%.5]
 // CHECK:STDOUT:   %.loc18_19: {.x: i32} = struct_literal (%.loc18_18)
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   assign file.%b.var, <error>

+ 18 - 5
toolchain/check/testdata/as/as_type.carbon

@@ -9,8 +9,11 @@ let t: type = (i32, i32) as type;
 // CHECK:STDOUT: --- as_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -18,8 +21,18 @@ let t: type = (i32, i32) as type;
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc7_24: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc7_26: type = converted %.loc7_24, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:   %t: type = bind_name t, %.loc7_26
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7_16: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7_21: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc7_24: (type, type) = tuple_literal (%int.make_type_32.loc7_16, %int.make_type_32.loc7_21)
+// CHECK:STDOUT:   %.loc7_26.1: type = value_of_initializer %int.make_type_32.loc7_16 [template = i32]
+// CHECK:STDOUT:   %.loc7_26.2: type = converted %int.make_type_32.loc7_16, %.loc7_26.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_26.3: type = value_of_initializer %int.make_type_32.loc7_21 [template = i32]
+// CHECK:STDOUT:   %.loc7_26.4: type = converted %int.make_type_32.loc7_21, %.loc7_26.3 [template = i32]
+// CHECK:STDOUT:   %.loc7_26.5: type = converted %.loc7_24, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:   %t: type = bind_name t, %.loc7_26.5
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 17 - 5
toolchain/check/testdata/as/basic.carbon

@@ -11,9 +11,11 @@ fn Main() -> i32 {
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Main: type = fn_type @Main [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Main = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Main: type = fn_type @Main [template]
+// CHECK:STDOUT:   %struct.2: Main = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -23,14 +25,24 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     .Main = %Main.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Main.decl: Main = fn_decl @Main [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Main.decl: Main = fn_decl @Main [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_14.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc7_14.2: type = converted %int.make_type_32, %.loc7_14.1 [template = i32]
 // CHECK:STDOUT:     @Main.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 1 [template = constants.%.2]
-// CHECK:STDOUT:   return %.loc8
+// CHECK:STDOUT:   %.loc8_10: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_15.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_15.2: type = converted %int.make_type_32, %.loc8_15.1 [template = i32]
+// CHECK:STDOUT:   return %.loc8_10
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 30 - 9
toolchain/check/testdata/as/fail_no_conversion.carbon

@@ -12,10 +12,13 @@ let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDOUT: --- fail_no_conversion.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: type = tuple_type (type, type) [template]
-// CHECK:STDOUT:   %.2: type = tuple_type (i32, i32) [template]
-// CHECK:STDOUT:   %.3: type = ptr_type (i32, i32) [template]
-// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.3: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.4: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %.5: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -23,11 +26,29 @@ let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc10_17.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc10_17.2: type = converted %.loc10_17.1, constants.%.2 [template = constants.%.2]
-// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_35.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc10_35.2: type = converted %.loc10_35.1, constants.%.2 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc10_9: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc10_14: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc10_17.1: (type, type) = tuple_literal (%int.make_type_32.loc10_9, %int.make_type_32.loc10_14)
+// CHECK:STDOUT:   %.loc10_17.2: type = value_of_initializer %int.make_type_32.loc10_9 [template = i32]
+// CHECK:STDOUT:   %.loc10_17.3: type = converted %int.make_type_32.loc10_9, %.loc10_17.2 [template = i32]
+// CHECK:STDOUT:   %.loc10_17.4: type = value_of_initializer %int.make_type_32.loc10_14 [template = i32]
+// CHECK:STDOUT:   %.loc10_17.5: type = converted %int.make_type_32.loc10_14, %.loc10_17.4 [template = i32]
+// CHECK:STDOUT:   %.loc10_17.6: type = converted %.loc10_17.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc10_27: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc10_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc10_35.1: (type, type) = tuple_literal (%int.make_type_32.loc10_27, %int.make_type_32.loc10_32)
+// CHECK:STDOUT:   %.loc10_35.2: type = value_of_initializer %int.make_type_32.loc10_27 [template = i32]
+// CHECK:STDOUT:   %.loc10_35.3: type = converted %int.make_type_32.loc10_27, %.loc10_35.2 [template = i32]
+// CHECK:STDOUT:   %.loc10_35.4: type = value_of_initializer %int.make_type_32.loc10_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_35.5: type = converted %int.make_type_32.loc10_32, %.loc10_35.4 [template = i32]
+// CHECK:STDOUT:   %.loc10_35.6: type = converted %.loc10_35.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:   %n: (i32, i32) = bind_name n, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 13 - 4
toolchain/check/testdata/as/fail_not_type.carbon

@@ -12,8 +12,11 @@ let n: i32 = 1 as 2;
 // CHECK:STDOUT: --- fail_not_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -21,8 +24,14 @@ let n: i32 = 1 as 2;
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc10_8.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_8.2: type = converted %int.make_type_32, %.loc10_8.1 [template = i32]
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   %n: i32 = bind_name n, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 29 - 8
toolchain/check/testdata/basics/builtin_types.carbon

@@ -12,10 +12,16 @@ var test_type: type = i32;
 // CHECK:STDOUT: --- builtin_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.2: f64 = float_literal 0.10000000000000001 [template]
-// CHECK:STDOUT:   %.3: type = ptr_type String [template]
-// CHECK:STDOUT:   %.4: String = string_literal "Test" [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %struct.2: Float = struct_value () [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 0.10000000000000001 [template]
+// CHECK:STDOUT:   %.5: type = ptr_type String [template]
+// CHECK:STDOUT:   %.6: String = string_literal "Test" [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -26,23 +32,38 @@ var test_type: type = i32;
 // CHECK:STDOUT:     .test_type = %test_type
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_15.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc7_15.2: type = converted %int.make_type_32, %.loc7_15.1 [template = i32]
 // CHECK:STDOUT:   %test_i32.var: ref i32 = var test_i32
 // CHECK:STDOUT:   %test_i32: ref i32 = bind_name test_i32, %test_i32.var
+// CHECK:STDOUT:   %.loc8_15.1: i32 = int_literal 64 [template = constants.%.3]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %float.make_type: init type = call constants.%struct.2(%.loc8_15.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_15.2: type = value_of_initializer %float.make_type [template = f64]
+// CHECK:STDOUT:   %.loc8_15.3: type = converted %float.make_type, %.loc8_15.2 [template = f64]
 // CHECK:STDOUT:   %test_f64.var: ref f64 = var test_f64
 // CHECK:STDOUT:   %test_f64: ref f64 = bind_name test_f64, %test_f64.var
-// CHECK:STDOUT:   %.loc9: String = string_literal "Test" [template = constants.%.4]
+// CHECK:STDOUT:   %.loc9: String = string_literal "Test" [template = constants.%.6]
 // CHECK:STDOUT:   %test_str: String = bind_name test_str, %.loc9
 // CHECK:STDOUT:   %test_type.var: ref type = var test_type
 // CHECK:STDOUT:   %test_type: ref type = bind_name test_type, %test_type.var
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // 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:   assign file.%test_i32.var, %.loc7
-// CHECK:STDOUT:   %.loc8: f64 = float_literal 0.10000000000000001 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8: f64 = float_literal 0.10000000000000001 [template = constants.%.4]
 // CHECK:STDOUT:   assign file.%test_f64.var, %.loc8
-// CHECK:STDOUT:   assign file.%test_type.var, i32
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   assign file.%test_type.var, %int.make_type_32
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 11 - 3
toolchain/check/testdata/basics/fail_bad_run_2.carbon

@@ -12,9 +12,11 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Run = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %struct.2: Run = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -23,12 +25,18 @@ fn Run(n: i32) {}
 // CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc10_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc10_11.2: type = converted %int.make_type_32, %.loc10_11.1 [template = i32]
 // CHECK:STDOUT:     %n.loc10_8.1: i32 = param n
 // CHECK:STDOUT:     @Run.%n: i32 = bind_name n, %n.loc10_8.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run(%n: i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return

+ 35 - 0
toolchain/check/testdata/basics/fail_numeric_literal_overflow.carbon

@@ -35,15 +35,50 @@ let e: f64 = 5.0e39999999999999999993;
 
 // CHECK:STDOUT: --- fail_numeric_literal_overflow.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %struct.2: Float = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc11_8.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_8.2: type = converted %int.make_type_32.loc11, %.loc11_8.1 [template = i32]
 // CHECK:STDOUT:   %a: i32 = bind_name a, <error>
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_8.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
+// CHECK:STDOUT:   %.loc17_8.2: type = converted %int.make_type_32.loc17, %.loc17_8.1 [template = i32]
 // CHECK:STDOUT:   %b: i32 = bind_name b, <error>
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc23_8.1: type = value_of_initializer %int.make_type_32.loc23 [template = i32]
+// CHECK:STDOUT:   %.loc23_8.2: type = converted %int.make_type_32.loc23, %.loc23_8.1 [template = i32]
 // CHECK:STDOUT:   %c: i32 = bind_name c, <error>
+// CHECK:STDOUT:   %.loc29_8.1: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %float.make_type.loc29: init type = call constants.%struct.2(%.loc29_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc29_8.2: type = value_of_initializer %float.make_type.loc29 [template = f64]
+// CHECK:STDOUT:   %.loc29_8.3: type = converted %float.make_type.loc29, %.loc29_8.2 [template = f64]
 // CHECK:STDOUT:   %d: f64 = bind_name d, <error>
+// CHECK:STDOUT:   %.loc34_8.1: i32 = int_literal 64 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %float.make_type.loc34: init type = call constants.%struct.2(%.loc34_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc34_8.2: type = value_of_initializer %float.make_type.loc34 [template = f64]
+// CHECK:STDOUT:   %.loc34_8.3: type = converted %float.make_type.loc34, %.loc34_8.2 [template = f64]
 // CHECK:STDOUT:   %e: f64 = bind_name e, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:

+ 16 - 0
toolchain/check/testdata/basics/fail_qualifier_unsupported.carbon

@@ -12,6 +12,12 @@ var y: i32 = x.b;
 
 // CHECK:STDOUT: --- fail_qualifier_unsupported.carbon
 // CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = %Core
@@ -19,12 +25,22 @@ var y: i32 = x.b;
 // CHECK:STDOUT:     .y = %y
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
 // CHECK:STDOUT:   %x.var: ref i32 = var x
 // CHECK:STDOUT:   %x: ref i32 = bind_name x, %x.var
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc11_8.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_8.2: type = converted %int.make_type_32.loc11, %.loc11_8.1 [template = i32]
 // CHECK:STDOUT:   %y.var: ref i32 = var y
 // CHECK:STDOUT:   %y: ref i32 = bind_name y, %y.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: ref i32 = name_ref x, file.%x

+ 43 - 25
toolchain/check/testdata/basics/numeric_literals.carbon

@@ -30,7 +30,9 @@ fn F() {
 // 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:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.2: Int32 = 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]
@@ -45,16 +47,19 @@ fn F() {
 // 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:   %.15: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %struct.3: Float = struct_value () [template]
+// CHECK:STDOUT:   %.16: type = array_type %.2, f64 [template]
+// CHECK:STDOUT:   %.17: type = ptr_type [f64; 6] [template]
+// CHECK:STDOUT:   %.18: f64 = float_literal 0.90000000000000002 [template]
+// CHECK:STDOUT:   %.19: f64 = float_literal 8 [template]
+// CHECK:STDOUT:   %.20: f64 = float_literal 80 [template]
+// CHECK:STDOUT:   %.21: f64 = float_literal 1.0E+7 [template]
+// CHECK:STDOUT:   %.22: f64 = float_literal 1.0E+8 [template]
+// CHECK:STDOUT:   %.23: f64 = float_literal 1.0E-8 [template]
+// CHECK:STDOUT:   %.24: type = tuple_type (f64, f64, f64, f64, f64, f64) [template]
+// CHECK:STDOUT:   %array.2: [f64; 6] = tuple_value (%.18, %.19, %.20, %.21, %.22, %.23) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -63,12 +68,17 @@ fn F() {
 // CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.3]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.2() [template = i32]
 // CHECK:STDOUT:   %.loc10_19: i32 = int_literal 6 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc10_14.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_14.2: type = converted %int.make_type_32, %.loc10_14.1 [template = i32]
 // 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
@@ -100,38 +110,46 @@ fn F() {
 // 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_16.1: i32 = int_literal 64 [template = constants.%.15]
+// CHECK:STDOUT:   %float.make_type: init type = call constants.%struct.3(%.loc18_16.1) [template = f64]
 // 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:   %.loc18_16.2: type = value_of_initializer %float.make_type [template = f64]
+// CHECK:STDOUT:   %.loc18_16.3: type = converted %float.make_type, %.loc18_16.2 [template = f64]
+// CHECK:STDOUT:   %.loc18_22: type = array_type %.loc18_21, f64 [template = constants.%.16]
 // 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.%.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:   %.loc19: f64 = float_literal 0.90000000000000002 [template = constants.%.18]
+// CHECK:STDOUT:   %.loc20: f64 = float_literal 8 [template = constants.%.19]
+// CHECK:STDOUT:   %.loc21: f64 = float_literal 80 [template = constants.%.20]
+// CHECK:STDOUT:   %.loc22: f64 = float_literal 1.0E+7 [template = constants.%.21]
+// CHECK:STDOUT:   %.loc23: f64 = float_literal 1.0E+8 [template = constants.%.22]
+// CHECK:STDOUT:   %.loc24: f64 = float_literal 1.0E-8 [template = constants.%.23]
 // 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.%.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.%.17]
+// CHECK:STDOUT:   %.loc25_3.4: init f64 = initialize_from %.loc19 to %.loc25_3.3 [template = constants.%.18]
 // 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.%.18]
+// CHECK:STDOUT:   %.loc25_3.7: init f64 = initialize_from %.loc20 to %.loc25_3.6 [template = constants.%.19]
 // 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.%.19]
+// CHECK:STDOUT:   %.loc25_3.10: init f64 = initialize_from %.loc21 to %.loc25_3.9 [template = constants.%.20]
 // 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.%.20]
+// CHECK:STDOUT:   %.loc25_3.13: init f64 = initialize_from %.loc22 to %.loc25_3.12 [template = constants.%.21]
 // 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.%.21]
+// CHECK:STDOUT:   %.loc25_3.16: init f64 = initialize_from %.loc23 to %.loc25_3.15 [template = constants.%.22]
 // 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.%.22]
+// CHECK:STDOUT:   %.loc25_3.19: init f64 = initialize_from %.loc24 to %.loc25_3.18 [template = constants.%.23]
 // 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
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:

+ 17 - 4
toolchain/check/testdata/basics/parens.carbon

@@ -10,8 +10,11 @@ var b: i32 = ((2));
 // CHECK:STDOUT: --- parens.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -21,17 +24,27 @@ var b: i32 = ((2));
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
 // CHECK:STDOUT:   %b.var: ref i32 = var b
 // CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 1 [template = constants.%.1]
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 1 [template = constants.%.2]
 // CHECK:STDOUT:   assign file.%a.var, %.loc7
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 2 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 2 [template = constants.%.3]
 // CHECK:STDOUT:   assign file.%b.var, %.loc8
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 11 - 3
toolchain/check/testdata/basics/run_i32.carbon

@@ -9,9 +9,11 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT: --- run_i32.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Run = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Run: type = fn_type @Run [template]
+// CHECK:STDOUT:   %struct.2: Run = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -21,11 +23,17 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT:     .Run = %Run.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_13.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc7_13.2: type = converted %int.make_type_32, %.loc7_13.1 [template = i32]
 // CHECK:STDOUT:     @Run.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template = constants.%.2]

+ 102 - 40
toolchain/check/testdata/basics/type_literals.carbon

@@ -111,11 +111,14 @@ var test_f128: f128;
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: i32 = int_literal 8 [template]
-// CHECK:STDOUT:   %.2: type = int_type signed, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 16 [template]
-// CHECK:STDOUT:   %.4: type = int_type signed, %.3 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 64 [template]
-// CHECK:STDOUT:   %.6: type = int_type signed, %.5 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = int_type signed, %.1 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 16 [template]
+// CHECK:STDOUT:   %.5: type = int_type signed, %.4 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %.7: type = int_type signed, %.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -127,27 +130,41 @@ var test_f128: f128;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.loc3_14.1: i32 = int_literal 8 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc3_14.2: type = int_type signed, %.loc3_14.1 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc3: init type = call constants.%struct(%.loc3_14.1) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc3_14.2: type = value_of_initializer %int.make_type_signed.loc3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc3_14.3: type = converted %int.make_type_signed.loc3, %.loc3_14.2 [template = constants.%.3]
 // CHECK:STDOUT:   %test_i8.var: ref i8 = var test_i8
 // CHECK:STDOUT:   %test_i8: ref i8 = bind_name test_i8, %test_i8.var
-// CHECK:STDOUT:   %.loc4_15.1: i32 = int_literal 16 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_15.2: type = int_type signed, %.loc4_15.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_15.1: i32 = int_literal 16 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc4: init type = call constants.%struct(%.loc4_15.1) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc4_15.2: type = value_of_initializer %int.make_type_signed.loc4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc4_15.3: type = converted %int.make_type_signed.loc4, %.loc4_15.2 [template = constants.%.5]
 // CHECK:STDOUT:   %test_i16.var: ref i16 = var test_i16
 // CHECK:STDOUT:   %test_i16: ref i16 = bind_name test_i16, %test_i16.var
-// CHECK:STDOUT:   %.loc5_15.1: i32 = int_literal 64 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc5_15.2: type = int_type signed, %.loc5_15.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc5_15.1: i32 = int_literal 64 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc5: init type = call constants.%struct(%.loc5_15.1) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc5_15.2: type = value_of_initializer %int.make_type_signed.loc5 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc5_15.3: type = converted %int.make_type_signed.loc5, %.loc5_15.2 [template = constants.%.7]
 // CHECK:STDOUT:   %test_i64.var: ref i64 = var test_i64
 // CHECK:STDOUT:   %test_i64: ref i64 = bind_name test_i64, %test_i64.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int(%size: i32) -> type = "int.make_type_signed";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_iN_bad_width.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: type = int_type signed, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 15 [template]
-// CHECK:STDOUT:   %.4: type = int_type signed, %.3 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 1000000000 [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = int_type signed, %.1 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 15 [template]
+// CHECK:STDOUT:   %.5: type = int_type signed, %.4 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -164,31 +181,48 @@ var test_f128: f128;
 // CHECK:STDOUT:   %test_i0.var: ref <error> = var test_i0
 // CHECK:STDOUT:   %test_i0: ref <error> = bind_name test_i0, %test_i0.var
 // CHECK:STDOUT:   %.loc12_14.1: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_14.2: type = int_type signed, %.loc12_14.1 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc12: init type = call constants.%struct(%.loc12_14.1) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_14.2: type = value_of_initializer %int.make_type_signed.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_14.3: type = converted %int.make_type_signed.loc12, %.loc12_14.2 [template = constants.%.3]
 // CHECK:STDOUT:   %test_i1.var: ref i1 = var test_i1
 // CHECK:STDOUT:   %test_i1: ref i1 = bind_name test_i1, %test_i1.var
-// CHECK:STDOUT:   %.loc17_15.1: i32 = int_literal 15 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc17_15.2: type = int_type signed, %.loc17_15.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc17_15.1: i32 = int_literal 15 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc17: init type = call constants.%struct(%.loc17_15.1) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_15.2: type = value_of_initializer %int.make_type_signed.loc17 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_15.3: type = converted %int.make_type_signed.loc17, %.loc17_15.2 [template = constants.%.5]
 // CHECK:STDOUT:   %test_i15.var: ref i15 = var test_i15
 // CHECK:STDOUT:   %test_i15: ref i15 = bind_name test_i15, %test_i15.var
-// CHECK:STDOUT:   %.loc22_23.1: i32 = int_literal 1000000000 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc22_23.2: type = int_type signed, %.loc22_23.1 [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.1: i32 = int_literal 1000000000 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc22: init type = call constants.%struct(%.loc22_23.1) [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.2: type = value_of_initializer %int.make_type_signed.loc22 [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.3: type = converted %int.make_type_signed.loc22, %.loc22_23.2 [template = <error>]
 // CHECK:STDOUT:   %test_i1000000000.var: ref <error> = var test_i1000000000
 // CHECK:STDOUT:   %test_i1000000000: ref <error> = bind_name test_i1000000000, %test_i1000000000.var
-// CHECK:STDOUT:   %.loc28: type = int_type signed, <error> [template = <error>]
+// CHECK:STDOUT:   %import_ref.4: Int = import_ref ir3, inst+13, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_signed.loc28: init type = call constants.%struct(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %.loc28_33.1: type = value_of_initializer %int.make_type_signed.loc28 [template = <error>]
+// CHECK:STDOUT:   %.loc28_33.2: type = converted %int.make_type_signed.loc28, %.loc28_33.1 [template = <error>]
 // CHECK:STDOUT:   %test_i10000000000000000000.var: ref <error> = var test_i10000000000000000000
 // CHECK:STDOUT:   %test_i10000000000000000000: ref <error> = bind_name test_i10000000000000000000, %test_i10000000000000000000.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int(%size: i32) -> type = "int.make_type_signed";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- uN.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: i32 = int_literal 8 [template]
-// CHECK:STDOUT:   %.2: type = int_type unsigned, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 16 [template]
-// CHECK:STDOUT:   %.4: type = int_type unsigned, %.3 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 64 [template]
-// CHECK:STDOUT:   %.6: type = int_type unsigned, %.5 [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = int_type unsigned, %.1 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 16 [template]
+// CHECK:STDOUT:   %.5: type = int_type unsigned, %.4 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %.7: type = int_type unsigned, %.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -200,27 +234,41 @@ var test_f128: f128;
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.loc3_14.1: i32 = int_literal 8 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc3_14.2: type = int_type unsigned, %.loc3_14.1 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc3: init type = call constants.%struct(%.loc3_14.1) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc3_14.2: type = value_of_initializer %int.make_type_unsigned.loc3 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc3_14.3: type = converted %int.make_type_unsigned.loc3, %.loc3_14.2 [template = constants.%.3]
 // CHECK:STDOUT:   %test_u8.var: ref u8 = var test_u8
 // CHECK:STDOUT:   %test_u8: ref u8 = bind_name test_u8, %test_u8.var
-// CHECK:STDOUT:   %.loc4_15.1: i32 = int_literal 16 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc4_15.2: type = int_type unsigned, %.loc4_15.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc4_15.1: i32 = int_literal 16 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc4: init type = call constants.%struct(%.loc4_15.1) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc4_15.2: type = value_of_initializer %int.make_type_unsigned.loc4 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc4_15.3: type = converted %int.make_type_unsigned.loc4, %.loc4_15.2 [template = constants.%.5]
 // CHECK:STDOUT:   %test_u16.var: ref u16 = var test_u16
 // CHECK:STDOUT:   %test_u16: ref u16 = bind_name test_u16, %test_u16.var
-// CHECK:STDOUT:   %.loc5_15.1: i32 = int_literal 64 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc5_15.2: type = int_type unsigned, %.loc5_15.1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc5_15.1: i32 = int_literal 64 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc5: init type = call constants.%struct(%.loc5_15.1) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc5_15.2: type = value_of_initializer %int.make_type_unsigned.loc5 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc5_15.3: type = converted %int.make_type_unsigned.loc5, %.loc5_15.2 [template = constants.%.7]
 // CHECK:STDOUT:   %test_u64.var: ref u64 = var test_u64
 // CHECK:STDOUT:   %test_u64: ref u64 = bind_name test_u64, %test_u64.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @UInt(%size: i32) -> type = "int.make_type_unsigned";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_uN_bad_width.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %.1: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.2: type = int_type unsigned, %.1 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 15 [template]
-// CHECK:STDOUT:   %.4: type = int_type unsigned, %.3 [template]
-// CHECK:STDOUT:   %.5: i32 = int_literal 1000000000 [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = int_type unsigned, %.1 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 15 [template]
+// CHECK:STDOUT:   %.5: type = int_type unsigned, %.4 [template]
+// CHECK:STDOUT:   %.6: i32 = int_literal 1000000000 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -237,22 +285,36 @@ var test_f128: f128;
 // CHECK:STDOUT:   %test_u0.var: ref <error> = var test_u0
 // CHECK:STDOUT:   %test_u0: ref <error> = bind_name test_u0, %test_u0.var
 // CHECK:STDOUT:   %.loc12_14.1: i32 = int_literal 1 [template = constants.%.1]
-// CHECK:STDOUT:   %.loc12_14.2: type = int_type unsigned, %.loc12_14.1 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.1: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc12: init type = call constants.%struct(%.loc12_14.1) [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_14.2: type = value_of_initializer %int.make_type_unsigned.loc12 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc12_14.3: type = converted %int.make_type_unsigned.loc12, %.loc12_14.2 [template = constants.%.3]
 // CHECK:STDOUT:   %test_u1.var: ref u1 = var test_u1
 // CHECK:STDOUT:   %test_u1: ref u1 = bind_name test_u1, %test_u1.var
-// CHECK:STDOUT:   %.loc17_15.1: i32 = int_literal 15 [template = constants.%.3]
-// CHECK:STDOUT:   %.loc17_15.2: type = int_type unsigned, %.loc17_15.1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc17_15.1: i32 = int_literal 15 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc17: init type = call constants.%struct(%.loc17_15.1) [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_15.2: type = value_of_initializer %int.make_type_unsigned.loc17 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc17_15.3: type = converted %int.make_type_unsigned.loc17, %.loc17_15.2 [template = constants.%.5]
 // CHECK:STDOUT:   %test_u15.var: ref u15 = var test_u15
 // CHECK:STDOUT:   %test_u15: ref u15 = bind_name test_u15, %test_u15.var
-// CHECK:STDOUT:   %.loc22_23.1: i32 = int_literal 1000000000 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc22_23.2: type = int_type unsigned, %.loc22_23.1 [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.1: i32 = int_literal 1000000000 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc22: init type = call constants.%struct(%.loc22_23.1) [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.2: type = value_of_initializer %int.make_type_unsigned.loc22 [template = <error>]
+// CHECK:STDOUT:   %.loc22_23.3: type = converted %int.make_type_unsigned.loc22, %.loc22_23.2 [template = <error>]
 // CHECK:STDOUT:   %test_u1000000000.var: ref <error> = var test_u1000000000
 // CHECK:STDOUT:   %test_u1000000000: ref <error> = bind_name test_u1000000000, %test_u1000000000.var
-// CHECK:STDOUT:   %.loc28: type = int_type unsigned, <error> [template = <error>]
+// CHECK:STDOUT:   %import_ref.4: UInt = import_ref ir3, inst+22, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %int.make_type_unsigned.loc28: init type = call constants.%struct(<invalid>) [template = <error>]
+// CHECK:STDOUT:   %.loc28_33.1: type = value_of_initializer %int.make_type_unsigned.loc28 [template = <error>]
+// CHECK:STDOUT:   %.loc28_33.2: type = converted %int.make_type_unsigned.loc28, %.loc28_33.1 [template = <error>]
 // CHECK:STDOUT:   %test_u10000000000000000000.var: ref <error> = var test_u10000000000000000000
 // CHECK:STDOUT:   %test_u10000000000000000000: ref <error> = bind_name test_u10000000000000000000, %test_u10000000000000000000.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @UInt(%size: i32) -> type = "int.make_type_unsigned";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_fN_bad_width.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}

+ 183 - 31
toolchain/check/testdata/builtins/float/add.carbon

@@ -49,14 +49,17 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 2.2000000000000002 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 2.3000000000000003 [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 4.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -67,29 +70,66 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc2_11.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_11: init type = call constants.%struct.1(%.loc2_11.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_11.2: type = value_of_initializer %float.make_type.loc2_11 [template = f64]
+// CHECK:STDOUT:     %.loc2_11.3: type = converted %float.make_type.loc2_11, %.loc2_11.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Add.%a: f64 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %.loc2_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_19: init type = call constants.%struct.1(%.loc2_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_19.2: type = value_of_initializer %float.make_type.loc2_19 [template = f64]
+// CHECK:STDOUT:     %.loc2_19.3: type = converted %float.make_type.loc2_19, %.loc2_19.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Add.%b: f64 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %.loc2_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_27: init type = call constants.%struct.1(%.loc2_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_27.2: type = value_of_initializer %float.make_type.loc2_27 [template = f64]
+// CHECK:STDOUT:     %.loc2_27.3: type = converted %float.make_type.loc2_27, %.loc2_27.2 [template = f64]
 // CHECK:STDOUT:     @Add.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc4_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_19: init type = call constants.%struct.1(%.loc4_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_19.2: type = value_of_initializer %float.make_type.loc4_19 [template = f64]
+// CHECK:STDOUT:     %.loc4_19.3: type = converted %float.make_type.loc4_19, %.loc4_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
+// CHECK:STDOUT:     %.loc4_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_27: init type = call constants.%struct.1(%.loc4_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_27.2: type = value_of_initializer %float.make_type.loc4_27 [template = f64]
+// CHECK:STDOUT:     %.loc4_27.3: type = converted %float.make_type.loc4_27, %.loc4_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
+// CHECK:STDOUT:     %.loc4_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_35: init type = call constants.%struct.1(%.loc4_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_35.2: type = value_of_initializer %float.make_type.loc4_35 [template = f64]
+// CHECK:STDOUT:     %.loc4_35.3: type = converted %float.make_type.loc4_35, %.loc4_35.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc8_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_8.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:   %.loc8_8.3: type = converted %float.make_type.loc8, %.loc8_8.2 [template = f64]
 // CHECK:STDOUT:   %x.var: ref f64 = var x
 // CHECK:STDOUT:   %x: ref f64 = bind_name x, %x.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: f64, %b: f64) -> f64 = "float.add";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.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:   %float.add: init f64 = call %Add.ref(%a.ref, %b.ref)
@@ -100,10 +140,10 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// 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:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2.2000000000000002 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 2.3000000000000003 [template = constants.%.4]
+// CHECK:STDOUT:   %float.add: init f64 = call %Add.ref(%.loc8_18, %.loc8_23) [template = constants.%.5]
 // CHECK:STDOUT:   assign file.%x.var, %float.add
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -111,21 +151,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: JustRight = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
-// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -140,68 +185,175 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc8_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_14: init type = call constants.%struct.1(%.loc8_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_14.2: type = value_of_initializer %float.make_type.loc8_14 [template = f64]
+// CHECK:STDOUT:     %.loc8_14.3: type = converted %float.make_type.loc8_14, %.loc8_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %.loc8_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_22: init type = call constants.%struct.1(%.loc8_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_22.2: type = value_of_initializer %float.make_type.loc8_22 [template = f64]
+// CHECK:STDOUT:     %.loc8_22.3: type = converted %float.make_type.loc8_22, %.loc8_22.2 [template = f64]
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc13_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_15: init type = call constants.%struct.1(%.loc13_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_15.2: type = value_of_initializer %float.make_type.loc13_15 [template = f64]
+// CHECK:STDOUT:     %.loc13_15.3: type = converted %float.make_type.loc13_15, %.loc13_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %.loc13_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_23: init type = call constants.%struct.1(%.loc13_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_23.2: type = value_of_initializer %float.make_type.loc13_23 [template = f64]
+// CHECK:STDOUT:     %.loc13_23.3: type = converted %float.make_type.loc13_23, %.loc13_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %.loc13_31.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_31: init type = call constants.%struct.1(%.loc13_31.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_31.2: type = value_of_initializer %float.make_type.loc13_31 [template = f64]
+// CHECK:STDOUT:     %.loc13_31.3: type = converted %float.make_type.loc13_31, %.loc13_31.2 [template = f64]
 // CHECK:STDOUT:     %c.loc13_28.1: f64 = param c
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %.loc13_39.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_39: init type = call constants.%struct.1(%.loc13_39.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_39.2: type = value_of_initializer %float.make_type.loc13_39 [template = f64]
+// CHECK:STDOUT:     %.loc13_39.3: type = converted %float.make_type.loc13_39, %.loc13_39.2 [template = f64]
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc17_21.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_21: init type = call constants.%struct.1(%.loc17_21.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_21.2: type = value_of_initializer %float.make_type.loc17_21 [template = f64]
+// CHECK:STDOUT:     %.loc17_21.3: type = converted %float.make_type.loc17_21, %.loc17_21.2 [template = f64]
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
+// CHECK:STDOUT:     %.loc17_29.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_29: init type = call constants.%struct.1(%.loc17_29.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_29.2: type = value_of_initializer %float.make_type.loc17_29 [template = f64]
+// CHECK:STDOUT:     %.loc17_29.3: type = converted %float.make_type.loc17_29, %.loc17_29.2 [template = f64]
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
+// CHECK:STDOUT:     %bool.make_type.loc17: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc17_37.1: type = value_of_initializer %bool.make_type.loc17 [template = bool]
+// CHECK:STDOUT:     %.loc17_37.2: type = converted %bool.make_type.loc17, %.loc17_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc18_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_17: init type = call constants.%struct.1(%.loc18_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_17.2: type = value_of_initializer %float.make_type.loc18_17 [template = f64]
+// CHECK:STDOUT:     %.loc18_17.3: type = converted %float.make_type.loc18_17, %.loc18_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
+// CHECK:STDOUT:     %.loc18_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_25: init type = call constants.%struct.1(%.loc18_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_25.2: type = value_of_initializer %float.make_type.loc18_25 [template = f64]
+// CHECK:STDOUT:     %.loc18_25.3: type = converted %float.make_type.loc18_25, %.loc18_25.2 [template = f64]
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
+// CHECK:STDOUT:     %.loc18_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_33: init type = call constants.%struct.1(%.loc18_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_33.2: type = value_of_initializer %float.make_type.loc18_33 [template = f64]
+// CHECK:STDOUT:     %.loc18_33.3: type = converted %float.make_type.loc18_33, %.loc18_33.2 [template = f64]
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %.loc20_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_25: init type = call constants.%struct.1(%.loc20_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_25.2: type = value_of_initializer %float.make_type.loc20_25 [template = f64]
+// CHECK:STDOUT:     %.loc20_25.3: type = converted %float.make_type.loc20_25, %.loc20_25.2 [template = f64]
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
+// CHECK:STDOUT:     %.loc20_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_33: init type = call constants.%struct.1(%.loc20_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_33.2: type = value_of_initializer %float.make_type.loc20_33 [template = f64]
+// CHECK:STDOUT:     %.loc20_33.3: type = converted %float.make_type.loc20_33, %.loc20_33.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %.loc24_26.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_26: init type = call constants.%struct.1(%.loc24_26.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_26.2: type = value_of_initializer %float.make_type.loc24_26 [template = f64]
+// CHECK:STDOUT:     %.loc24_26.3: type = converted %float.make_type.loc24_26, %.loc24_26.2 [template = f64]
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
+// CHECK:STDOUT:     %.loc24_34.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_34: init type = call constants.%struct.1(%.loc24_34.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_34.2: type = value_of_initializer %float.make_type.loc24_34 [template = f64]
+// CHECK:STDOUT:     %.loc24_34.3: type = converted %float.make_type.loc24_34, %.loc24_34.2 [template = f64]
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: f64 = bind_name b, %b.loc24_31.1
+// CHECK:STDOUT:     %.loc24_42.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_42: init type = call constants.%struct.1(%.loc24_42.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_42.2: type = value_of_initializer %float.make_type.loc24_42 [template = f64]
+// CHECK:STDOUT:     %.loc24_42.3: type = converted %float.make_type.loc24_42, %.loc24_42.2 [template = f64]
 // CHECK:STDOUT:     %c.loc24_39.1: f64 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
+// CHECK:STDOUT:     %.loc24_50.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_50: init type = call constants.%struct.1(%.loc24_50.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_50.2: type = value_of_initializer %float.make_type.loc24_50 [template = f64]
+// CHECK:STDOUT:     %.loc24_50.3: type = converted %float.make_type.loc24_50, %.loc24_50.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %.loc28_32.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_32: init type = call constants.%struct.1(%.loc28_32.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_32.2: type = value_of_initializer %float.make_type.loc28_32 [template = f64]
+// CHECK:STDOUT:     %.loc28_32.3: type = converted %float.make_type.loc28_32, %.loc28_32.2 [template = f64]
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
+// CHECK:STDOUT:     %.loc28_40.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_40: init type = call constants.%struct.1(%.loc28_40.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_40.2: type = value_of_initializer %float.make_type.loc28_40 [template = f64]
+// CHECK:STDOUT:     %.loc28_40.3: type = converted %float.make_type.loc28_40, %.loc28_40.2 [template = f64]
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: f64 = bind_name b, %b.loc28_37.1
+// CHECK:STDOUT:     %bool.make_type.loc28: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc28_48.1: type = value_of_initializer %bool.make_type.loc28 [template = bool]
+// CHECK:STDOUT:     %.loc28_48.2: type = converted %bool.make_type.loc28, %.loc28_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: f64) -> f64;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: f64, %b: f64, %c: f64) -> f64;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: f64, %b: f64) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: f64, %b: f64) -> f64 = "float.add";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -211,7 +363,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: f64 = name_ref c, %c
@@ -223,7 +375,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)

+ 209 - 47
toolchain/check/testdata/builtins/float/div.carbon

@@ -51,18 +51,21 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: 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 NaN [template]
+// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 10 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 2.5 [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 4 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.7: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.8: f64 = float_literal +Inf [template]
+// CHECK:STDOUT:   %.9: f64 = float_literal NaN [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -73,43 +76,90 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .a = %a.loc8
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc2_11.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_11: init type = call constants.%struct.1(%.loc2_11.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_11.2: type = value_of_initializer %float.make_type.loc2_11 [template = f64]
+// CHECK:STDOUT:     %.loc2_11.3: type = converted %float.make_type.loc2_11, %.loc2_11.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Div.%a: f64 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %.loc2_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_19: init type = call constants.%struct.1(%.loc2_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_19.2: type = value_of_initializer %float.make_type.loc2_19 [template = f64]
+// CHECK:STDOUT:     %.loc2_19.3: type = converted %float.make_type.loc2_19, %.loc2_19.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Div.%b: f64 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %.loc2_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_27: init type = call constants.%struct.1(%.loc2_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_27.2: type = value_of_initializer %float.make_type.loc2_27 [template = f64]
+// CHECK:STDOUT:     %.loc2_27.3: type = converted %float.make_type.loc2_27, %.loc2_27.2 [template = f64]
 // CHECK:STDOUT:     @Div.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc4_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_19: init type = call constants.%struct.1(%.loc4_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_19.2: type = value_of_initializer %float.make_type.loc4_19 [template = f64]
+// CHECK:STDOUT:     %.loc4_19.3: type = converted %float.make_type.loc4_19, %.loc4_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
+// CHECK:STDOUT:     %.loc4_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_27: init type = call constants.%struct.1(%.loc4_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_27.2: type = value_of_initializer %float.make_type.loc4_27 [template = f64]
+// CHECK:STDOUT:     %.loc4_27.3: type = converted %float.make_type.loc4_27, %.loc4_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
+// CHECK:STDOUT:     %.loc4_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_35: init type = call constants.%struct.1(%.loc4_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_35.2: type = value_of_initializer %float.make_type.loc4_35 [template = f64]
+// CHECK:STDOUT:     %.loc4_35.3: type = converted %float.make_type.loc4_35, %.loc4_35.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc8_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_8.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:   %.loc8_8.3: type = converted %float.make_type.loc8, %.loc8_8.2 [template = f64]
 // CHECK:STDOUT:   %a.var: ref f64 = var a
 // CHECK:STDOUT:   %a.loc8: ref f64 = bind_name a, %a.var
-// 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:   %.loc9_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc9: init type = call constants.%struct.1(%.loc9_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc9_8.2: type = value_of_initializer %float.make_type.loc9 [template = f64]
+// CHECK:STDOUT:   %.loc9_8.3: type = converted %float.make_type.loc9, %.loc9_8.2 [template = f64]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc9_18: f64 = float_literal 1 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc9_23: f64 = float_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %float.div.loc9: init f64 = call %Div.ref.loc9(%.loc9_18, %.loc9_23) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_27.1: f64 = value_of_initializer %float.div.loc9 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_27.2: f64 = converted %float.div.loc9, %.loc9_27.1 [template = constants.%.8]
 // CHECK:STDOUT:   %b.loc9: f64 = bind_name b, %.loc9_27.2
-// 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.%.6]
-// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 0 [template = constants.%.6]
-// CHECK:STDOUT:   %float.div.loc10: init f64 = call %Div.ref.loc10(%.loc10_18, %.loc10_23) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc10_27.1: f64 = value_of_initializer %float.div.loc10 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc10_27.2: f64 = converted %float.div.loc10, %.loc10_27.1 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.9: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc10: init type = call constants.%struct.1(%.loc10_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc10_8.2: type = value_of_initializer %float.make_type.loc10 [template = f64]
+// CHECK:STDOUT:   %.loc10_8.3: type = converted %float.make_type.loc10, %.loc10_8.2 [template = f64]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc10_18: f64 = float_literal 0 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 0 [template = constants.%.7]
+// 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:   %c: f64 = bind_name c, %.loc10_27.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: f64, %b: f64) -> f64 = "float.div";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.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:   %float.div: init f64 = call %Div.ref(%a.ref, %b.ref)
@@ -120,10 +170,10 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// 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:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 10 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_24: f64 = float_literal 2.5 [template = constants.%.4]
+// CHECK:STDOUT:   %float.div: init f64 = call %Div.ref(%.loc8_18, %.loc8_24) [template = constants.%.5]
 // CHECK:STDOUT:   assign file.%a.var, %float.div
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -131,21 +181,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: JustRight = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
-// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -160,68 +215,175 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc8_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_14: init type = call constants.%struct.1(%.loc8_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_14.2: type = value_of_initializer %float.make_type.loc8_14 [template = f64]
+// CHECK:STDOUT:     %.loc8_14.3: type = converted %float.make_type.loc8_14, %.loc8_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %.loc8_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_22: init type = call constants.%struct.1(%.loc8_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_22.2: type = value_of_initializer %float.make_type.loc8_22 [template = f64]
+// CHECK:STDOUT:     %.loc8_22.3: type = converted %float.make_type.loc8_22, %.loc8_22.2 [template = f64]
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc13_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_15: init type = call constants.%struct.1(%.loc13_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_15.2: type = value_of_initializer %float.make_type.loc13_15 [template = f64]
+// CHECK:STDOUT:     %.loc13_15.3: type = converted %float.make_type.loc13_15, %.loc13_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %.loc13_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_23: init type = call constants.%struct.1(%.loc13_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_23.2: type = value_of_initializer %float.make_type.loc13_23 [template = f64]
+// CHECK:STDOUT:     %.loc13_23.3: type = converted %float.make_type.loc13_23, %.loc13_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %.loc13_31.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_31: init type = call constants.%struct.1(%.loc13_31.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_31.2: type = value_of_initializer %float.make_type.loc13_31 [template = f64]
+// CHECK:STDOUT:     %.loc13_31.3: type = converted %float.make_type.loc13_31, %.loc13_31.2 [template = f64]
 // CHECK:STDOUT:     %c.loc13_28.1: f64 = param c
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %.loc13_39.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_39: init type = call constants.%struct.1(%.loc13_39.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_39.2: type = value_of_initializer %float.make_type.loc13_39 [template = f64]
+// CHECK:STDOUT:     %.loc13_39.3: type = converted %float.make_type.loc13_39, %.loc13_39.2 [template = f64]
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc17_21.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_21: init type = call constants.%struct.1(%.loc17_21.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_21.2: type = value_of_initializer %float.make_type.loc17_21 [template = f64]
+// CHECK:STDOUT:     %.loc17_21.3: type = converted %float.make_type.loc17_21, %.loc17_21.2 [template = f64]
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
+// CHECK:STDOUT:     %.loc17_29.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_29: init type = call constants.%struct.1(%.loc17_29.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_29.2: type = value_of_initializer %float.make_type.loc17_29 [template = f64]
+// CHECK:STDOUT:     %.loc17_29.3: type = converted %float.make_type.loc17_29, %.loc17_29.2 [template = f64]
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
+// CHECK:STDOUT:     %bool.make_type.loc17: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc17_37.1: type = value_of_initializer %bool.make_type.loc17 [template = bool]
+// CHECK:STDOUT:     %.loc17_37.2: type = converted %bool.make_type.loc17, %.loc17_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc18_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_17: init type = call constants.%struct.1(%.loc18_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_17.2: type = value_of_initializer %float.make_type.loc18_17 [template = f64]
+// CHECK:STDOUT:     %.loc18_17.3: type = converted %float.make_type.loc18_17, %.loc18_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
+// CHECK:STDOUT:     %.loc18_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_25: init type = call constants.%struct.1(%.loc18_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_25.2: type = value_of_initializer %float.make_type.loc18_25 [template = f64]
+// CHECK:STDOUT:     %.loc18_25.3: type = converted %float.make_type.loc18_25, %.loc18_25.2 [template = f64]
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
+// CHECK:STDOUT:     %.loc18_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_33: init type = call constants.%struct.1(%.loc18_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_33.2: type = value_of_initializer %float.make_type.loc18_33 [template = f64]
+// CHECK:STDOUT:     %.loc18_33.3: type = converted %float.make_type.loc18_33, %.loc18_33.2 [template = f64]
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %.loc20_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_25: init type = call constants.%struct.1(%.loc20_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_25.2: type = value_of_initializer %float.make_type.loc20_25 [template = f64]
+// CHECK:STDOUT:     %.loc20_25.3: type = converted %float.make_type.loc20_25, %.loc20_25.2 [template = f64]
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
+// CHECK:STDOUT:     %.loc20_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_33: init type = call constants.%struct.1(%.loc20_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_33.2: type = value_of_initializer %float.make_type.loc20_33 [template = f64]
+// CHECK:STDOUT:     %.loc20_33.3: type = converted %float.make_type.loc20_33, %.loc20_33.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %.loc24_26.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_26: init type = call constants.%struct.1(%.loc24_26.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_26.2: type = value_of_initializer %float.make_type.loc24_26 [template = f64]
+// CHECK:STDOUT:     %.loc24_26.3: type = converted %float.make_type.loc24_26, %.loc24_26.2 [template = f64]
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
+// CHECK:STDOUT:     %.loc24_34.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_34: init type = call constants.%struct.1(%.loc24_34.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_34.2: type = value_of_initializer %float.make_type.loc24_34 [template = f64]
+// CHECK:STDOUT:     %.loc24_34.3: type = converted %float.make_type.loc24_34, %.loc24_34.2 [template = f64]
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: f64 = bind_name b, %b.loc24_31.1
+// CHECK:STDOUT:     %.loc24_42.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_42: init type = call constants.%struct.1(%.loc24_42.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_42.2: type = value_of_initializer %float.make_type.loc24_42 [template = f64]
+// CHECK:STDOUT:     %.loc24_42.3: type = converted %float.make_type.loc24_42, %.loc24_42.2 [template = f64]
 // CHECK:STDOUT:     %c.loc24_39.1: f64 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
+// CHECK:STDOUT:     %.loc24_50.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_50: init type = call constants.%struct.1(%.loc24_50.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_50.2: type = value_of_initializer %float.make_type.loc24_50 [template = f64]
+// CHECK:STDOUT:     %.loc24_50.3: type = converted %float.make_type.loc24_50, %.loc24_50.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %.loc28_32.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_32: init type = call constants.%struct.1(%.loc28_32.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_32.2: type = value_of_initializer %float.make_type.loc28_32 [template = f64]
+// CHECK:STDOUT:     %.loc28_32.3: type = converted %float.make_type.loc28_32, %.loc28_32.2 [template = f64]
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
+// CHECK:STDOUT:     %.loc28_40.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_40: init type = call constants.%struct.1(%.loc28_40.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_40.2: type = value_of_initializer %float.make_type.loc28_40 [template = f64]
+// CHECK:STDOUT:     %.loc28_40.3: type = converted %float.make_type.loc28_40, %.loc28_40.2 [template = f64]
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: f64 = bind_name b, %b.loc28_37.1
+// CHECK:STDOUT:     %bool.make_type.loc28: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc28_48.1: type = value_of_initializer %bool.make_type.loc28 [template = bool]
+// CHECK:STDOUT:     %.loc28_48.2: type = converted %bool.make_type.loc28, %.loc28_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: f64) -> f64;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: f64, %b: f64, %c: f64) -> f64;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: f64, %b: f64) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: f64, %b: f64) -> f64 = "float.div";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -231,7 +393,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: f64 = name_ref c, %c
@@ -243,7 +405,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)

+ 86 - 29
toolchain/check/testdata/builtins/float/eq.carbon

@@ -32,21 +32,26 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT: --- float_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: Eq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %struct.4: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.7: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.8: bool = bool_literal false [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,16 +64,30 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_10.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_10: init type = call constants.%struct.1(%.loc2_10.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_10.2: type = value_of_initializer %float.make_type.loc2_10 [template = f64]
+// CHECK:STDOUT:     %.loc2_10.3: type = converted %float.make_type.loc2_10, %.loc2_10.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_7.1: f64 = param a
 // CHECK:STDOUT:     @Eq.%a: f64 = bind_name a, %a.loc2_7.1
+// CHECK:STDOUT:     %.loc2_18.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_18: init type = call constants.%struct.1(%.loc2_18.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_18.2: type = value_of_initializer %float.make_type.loc2_18 [template = f64]
+// CHECK:STDOUT:     %.loc2_18.3: type = converted %float.make_type.loc2_18, %.loc2_18.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_15.1: f64 = param b
 // CHECK:STDOUT:     @Eq.%b: f64 = bind_name b, %b.loc2_15.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_26.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_26.2: type = converted %bool.make_type.loc2, %.loc2_26.1 [template = bool]
 // CHECK:STDOUT:     @Eq.%return: ref bool = 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.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.4] {
 // 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
@@ -76,11 +95,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc12_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc12_19: init type = call constants.%struct.1(%.loc12_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc12_19.2: type = value_of_initializer %float.make_type.loc12_19 [template = f64]
+// CHECK:STDOUT:     %.loc12_19.3: type = converted %float.make_type.loc12_19, %.loc12_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc12_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc12_16.1
+// CHECK:STDOUT:     %.loc12_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc12_27: init type = call constants.%struct.1(%.loc12_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc12_27.2: type = value_of_initializer %float.make_type.loc12_27 [template = f64]
+// CHECK:STDOUT:     %.loc12_27.3: type = converted %float.make_type.loc12_27, %.loc12_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc12_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc12_24.1
+// CHECK:STDOUT:     %bool.make_type.loc12: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc12_35.1: type = value_of_initializer %bool.make_type.loc12 [template = bool]
+// CHECK:STDOUT:     %.loc12_35.2: type = converted %bool.make_type.loc12, %.loc12_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -95,17 +128,21 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Eq(%a: f64, %b: f64) -> bool = "float.eq";
 // CHECK:STDOUT:
 // 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: 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.%.4]
-// CHECK:STDOUT:   %float.eq.loc8: init bool = call %Eq.ref.loc8(%.loc8_19, %.loc8_24) [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %float.eq.loc8 [template = constants.%.5]
-// CHECK:STDOUT:   %.loc8_13.2: bool = converted %float.eq.loc8, %.loc8_13.1 [template = constants.%.5]
+// CHECK:STDOUT:   %Eq.ref.loc8: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc8_19: f64 = float_literal 1 [template = constants.%.5]
+// 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]
+// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %float.eq.loc8 [template = constants.%.6]
+// CHECK:STDOUT:   %.loc8_13.2: bool = converted %float.eq.loc8, %.loc8_13.1 [template = constants.%.6]
 // CHECK:STDOUT:   if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc8:
@@ -119,12 +156,12 @@ 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: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc9_20: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_25: f64 = float_literal 2 [template = constants.%.6]
-// CHECK:STDOUT:   %float.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_25) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.eq.loc9 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.eq.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %Eq.ref.loc9: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_20: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_25: f64 = float_literal 2 [template = constants.%.7]
+// CHECK:STDOUT:   %float.eq.loc9: init bool = call %Eq.ref.loc9(%.loc9_20, %.loc9_25) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.eq.loc9 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.eq.loc9, %.loc9_14.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -142,7 +179,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: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Eq.ref: Eq = name_ref Eq, file.%Eq.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:   %float.eq: init bool = call %Eq.ref(%a.ref, %b.ref)
@@ -154,9 +191,12 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
 // CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
-// CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT:   %struct.2: WrongResult = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -165,14 +205,31 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.eq";
 // CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc7_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_19: init type = call constants.%struct.1(%.loc7_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_19.2: type = value_of_initializer %float.make_type.loc7_19 [template = f64]
+// CHECK:STDOUT:     %.loc7_19.3: type = converted %float.make_type.loc7_19, %.loc7_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc7_16.1: f64 = param a
 // CHECK:STDOUT:     @WrongResult.%a: f64 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %.loc7_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_27: init type = call constants.%struct.1(%.loc7_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_27.2: type = value_of_initializer %float.make_type.loc7_27 [template = f64]
+// CHECK:STDOUT:     %.loc7_27.3: type = converted %float.make_type.loc7_27, %.loc7_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc7_24.1: f64 = param b
 // CHECK:STDOUT:     @WrongResult.%b: f64 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %.loc7_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_35: init type = call constants.%struct.1(%.loc7_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_35.2: type = value_of_initializer %float.make_type.loc7_35 [template = f64]
+// CHECK:STDOUT:     %.loc7_35.3: type = converted %float.make_type.loc7_35, %.loc7_35.2 [template = f64]
 // CHECK:STDOUT:     @WrongResult.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @WrongResult(%a: f64, %b: f64) -> f64;
 // CHECK:STDOUT:

+ 103 - 56
toolchain/check/testdata/builtins/float/greater.carbon

@@ -27,25 +27,30 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_greater.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: Greater = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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]
-// CHECK:STDOUT:   %.6: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.7: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.8: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %struct.5: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.8: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.9: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.10: f64 = float_literal -1 [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +64,45 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_15: init type = call constants.%struct.1(%.loc2_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_15.2: type = value_of_initializer %float.make_type.loc2_15 [template = f64]
+// CHECK:STDOUT:     %.loc2_15.3: type = converted %float.make_type.loc2_15, %.loc2_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_12.1: f64 = param a
 // CHECK:STDOUT:     @Greater.%a: f64 = bind_name a, %a.loc2_12.1
+// CHECK:STDOUT:     %.loc2_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_23: init type = call constants.%struct.1(%.loc2_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_23.2: type = value_of_initializer %float.make_type.loc2_23 [template = f64]
+// CHECK:STDOUT:     %.loc2_23.3: type = converted %float.make_type.loc2_23, %.loc2_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_20.1: f64 = param b
 // CHECK:STDOUT:     @Greater.%b: f64 = bind_name b, %b.loc2_20.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_31.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_31.2: type = converted %bool.make_type.loc2, %.loc2_31.1 [template = bool]
 // CHECK:STDOUT:     @Greater.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %.loc3_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_14: init type = call constants.%struct.1(%.loc3_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_14.2: type = value_of_initializer %float.make_type.loc3_14 [template = f64]
+// CHECK:STDOUT:     %.loc3_14.3: type = converted %float.make_type.loc3_14, %.loc3_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %.loc3_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_22: init type = call constants.%struct.1(%.loc3_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_22.2: type = value_of_initializer %float.make_type.loc3_22 [template = f64]
+// CHECK:STDOUT:     %.loc3_22.3: type = converted %float.make_type.loc3_22, %.loc3_22.2 [template = f64]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +110,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc16_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_19: init type = call constants.%struct.1(%.loc16_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_19.2: type = value_of_initializer %float.make_type.loc16_19 [template = f64]
+// CHECK:STDOUT:     %.loc16_19.3: type = converted %float.make_type.loc16_19, %.loc16_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %.loc16_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_27: init type = call constants.%struct.1(%.loc16_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_27.2: type = value_of_initializer %float.make_type.loc16_27 [template = f64]
+// CHECK:STDOUT:     %.loc16_27.3: type = converted %float.make_type.loc16_27, %.loc16_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +143,10 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Greater(%a: f64, %b: f64) -> bool = "float.greater";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: f64) -> f64 = "float.negate";
@@ -107,12 +154,12 @@ 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: 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]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.greater.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.greater.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Greater.ref.loc9: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_25: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_30: f64 = float_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %float.greater.loc9: init bool = call %Greater.ref.loc9(%.loc9_25, %.loc9_30) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.greater.loc9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.greater.loc9, %.loc9_14.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -126,12 +173,12 @@ 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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc10_25: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_30: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %float.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_30) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %float.greater.loc10 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_14.2: bool = converted %float.greater.loc10, %.loc10_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Greater.ref.loc10: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc10_25: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_30: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.greater.loc10: init bool = call %Greater.ref.loc10(%.loc10_25, %.loc10_30) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %float.greater.loc10 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_14.2: bool = converted %float.greater.loc10, %.loc10_14.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -145,12 +192,12 @@ 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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %float.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %float.greater.loc11 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_13.2: bool = converted %float.greater.loc11, %.loc11_13.1 [template = constants.%.8]
+// CHECK:STDOUT:   %Greater.ref.loc11: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %float.greater.loc11: init bool = call %Greater.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %float.greater.loc11 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_13.2: bool = converted %float.greater.loc11, %.loc11_13.1 [template = constants.%.9]
 // CHECK:STDOUT:   if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -164,16 +211,16 @@ 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: 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_38: f64 = float_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc12_24.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_24.2: f64 = converted %float.negate.loc12, %.loc12_24.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_38) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %float.greater.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.2: bool = converted %float.greater.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Greater.ref.loc12: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc12_32: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_32) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_38: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc12_24.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_24.2: f64 = converted %float.negate.loc12, %.loc12_24.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.greater.loc12: init bool = call %Greater.ref.loc12(%.loc12_24.2, %.loc12_38) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %float.greater.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_14.2: bool = converted %float.greater.loc12, %.loc12_14.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -187,16 +234,16 @@ 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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.7]
-// 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %float.greater.loc13 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_13.2: bool = converted %float.greater.loc13, %.loc13_13.1 [template = constants.%.8]
+// CHECK:STDOUT:   %Greater.ref.loc13: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc13_36: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.greater.loc13: init bool = call %Greater.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %float.greater.loc13 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc13_13.2: bool = converted %float.greater.loc13, %.loc13_13.1 [template = constants.%.9]
 // CHECK:STDOUT:   if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:
@@ -214,7 +261,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref: Greater = name_ref Greater, file.%Greater.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:   %float.greater: init bool = call %Greater.ref(%a.ref, %b.ref)

+ 103 - 56
toolchain/check/testdata/builtins/float/greater_eq.carbon

@@ -27,25 +27,30 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_greater_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: GreaterEq = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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]
-// CHECK:STDOUT:   %.6: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.8: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %struct.5: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.8: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.9: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.10: f64 = float_literal -1 [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +64,45 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_17: init type = call constants.%struct.1(%.loc2_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_17.2: type = value_of_initializer %float.make_type.loc2_17 [template = f64]
+// CHECK:STDOUT:     %.loc2_17.3: type = converted %float.make_type.loc2_17, %.loc2_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_14.1: f64 = param a
 // CHECK:STDOUT:     @GreaterEq.%a: f64 = bind_name a, %a.loc2_14.1
+// CHECK:STDOUT:     %.loc2_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_25: init type = call constants.%struct.1(%.loc2_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_25.2: type = value_of_initializer %float.make_type.loc2_25 [template = f64]
+// CHECK:STDOUT:     %.loc2_25.3: type = converted %float.make_type.loc2_25, %.loc2_25.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_22.1: f64 = param b
 // CHECK:STDOUT:     @GreaterEq.%b: f64 = bind_name b, %b.loc2_22.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_33.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_33.2: type = converted %bool.make_type.loc2, %.loc2_33.1 [template = bool]
 // CHECK:STDOUT:     @GreaterEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %.loc3_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_14: init type = call constants.%struct.1(%.loc3_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_14.2: type = value_of_initializer %float.make_type.loc3_14 [template = f64]
+// CHECK:STDOUT:     %.loc3_14.3: type = converted %float.make_type.loc3_14, %.loc3_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %.loc3_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_22: init type = call constants.%struct.1(%.loc3_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_22.2: type = value_of_initializer %float.make_type.loc3_22 [template = f64]
+// CHECK:STDOUT:     %.loc3_22.3: type = converted %float.make_type.loc3_22, %.loc3_22.2 [template = f64]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +110,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc16_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_19: init type = call constants.%struct.1(%.loc16_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_19.2: type = value_of_initializer %float.make_type.loc16_19 [template = f64]
+// CHECK:STDOUT:     %.loc16_19.3: type = converted %float.make_type.loc16_19, %.loc16_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %.loc16_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_27: init type = call constants.%struct.1(%.loc16_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_27.2: type = value_of_initializer %float.make_type.loc16_27 [template = f64]
+// CHECK:STDOUT:     %.loc16_27.3: type = converted %float.make_type.loc16_27, %.loc16_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +143,10 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @GreaterEq(%a: f64, %b: f64) -> bool = "float.greater_eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: f64) -> f64 = "float.negate";
@@ -107,12 +154,12 @@ 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: 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]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.greater_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.greater_eq.loc9, %.loc9_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %GreaterEq.ref.loc9: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_27: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_32: f64 = float_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %float.greater_eq.loc9: init bool = call %GreaterEq.ref.loc9(%.loc9_27, %.loc9_32) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.greater_eq.loc9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.greater_eq.loc9, %.loc9_14.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -126,12 +173,12 @@ 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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc10_26: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_31: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %float.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_31) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %float.greater_eq.loc10 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_13.2: bool = converted %float.greater_eq.loc10, %.loc10_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %GreaterEq.ref.loc10: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc10_26: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_31: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.greater_eq.loc10: init bool = call %GreaterEq.ref.loc10(%.loc10_26, %.loc10_31) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %float.greater_eq.loc10 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_13.2: bool = converted %float.greater_eq.loc10, %.loc10_13.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -145,12 +192,12 @@ 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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc11_26: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_31: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %float.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_31) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %float.greater_eq.loc11 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_13.2: bool = converted %float.greater_eq.loc11, %.loc11_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %GreaterEq.ref.loc11: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc11_26: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_31: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %float.greater_eq.loc11: init bool = call %GreaterEq.ref.loc11(%.loc11_26, %.loc11_31) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_13.1: bool = value_of_initializer %float.greater_eq.loc11 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_13.2: bool = converted %float.greater_eq.loc11, %.loc11_13.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc11_13.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -164,16 +211,16 @@ 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: 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_40: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc12_26.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_26.2: f64 = converted %float.negate.loc12, %.loc12_26.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_40) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %float.greater_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_14.2: bool = converted %float.greater_eq.loc12, %.loc12_14.1 [template = constants.%.6]
+// CHECK:STDOUT:   %GreaterEq.ref.loc12: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc12_34: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_34) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_40: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc12_26.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_26.2: f64 = converted %float.negate.loc12, %.loc12_26.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.greater_eq.loc12: init bool = call %GreaterEq.ref.loc12(%.loc12_26.2, %.loc12_40) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_14.1: bool = value_of_initializer %float.greater_eq.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_14.2: bool = converted %float.greater_eq.loc12, %.loc12_14.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc12_14.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -187,16 +234,16 @@ 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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_26: f64 = float_literal 0 [template = constants.%.8]
-// 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_38) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_25.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_25.2: f64 = converted %float.negate.loc13, %.loc13_25.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %float.greater_eq.loc13 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_13.2: bool = converted %float.greater_eq.loc13, %.loc13_13.1 [template = constants.%.7]
+// CHECK:STDOUT:   %GreaterEq.ref.loc13: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc13_26: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc13_38: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_38) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_25.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_25.2: f64 = converted %float.negate.loc13, %.loc13_25.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.greater_eq.loc13: init bool = call %GreaterEq.ref.loc13(%.loc13_26, %.loc13_25.2) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_13.1: bool = value_of_initializer %float.greater_eq.loc13 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_13.2: bool = converted %float.greater_eq.loc13, %.loc13_13.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc13_13.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:
@@ -214,7 +261,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref: GreaterEq = name_ref GreaterEq, file.%GreaterEq.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:   %float.greater_eq: init bool = call %GreaterEq.ref(%a.ref, %b.ref)

+ 103 - 56
toolchain/check/testdata/builtins/float/less.carbon

@@ -27,25 +27,30 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_less.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: Less = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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]
-// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.8: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %struct.5: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.8: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.9: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.10: f64 = float_literal -1 [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +64,45 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_12.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_12: init type = call constants.%struct.1(%.loc2_12.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_12.2: type = value_of_initializer %float.make_type.loc2_12 [template = f64]
+// CHECK:STDOUT:     %.loc2_12.3: type = converted %float.make_type.loc2_12, %.loc2_12.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_9.1: f64 = param a
 // CHECK:STDOUT:     @Less.%a: f64 = bind_name a, %a.loc2_9.1
+// CHECK:STDOUT:     %.loc2_20.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_20: init type = call constants.%struct.1(%.loc2_20.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_20.2: type = value_of_initializer %float.make_type.loc2_20 [template = f64]
+// CHECK:STDOUT:     %.loc2_20.3: type = converted %float.make_type.loc2_20, %.loc2_20.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_17.1: f64 = param b
 // CHECK:STDOUT:     @Less.%b: f64 = bind_name b, %b.loc2_17.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_28.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_28.2: type = converted %bool.make_type.loc2, %.loc2_28.1 [template = bool]
 // CHECK:STDOUT:     @Less.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %.loc3_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_14: init type = call constants.%struct.1(%.loc3_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_14.2: type = value_of_initializer %float.make_type.loc3_14 [template = f64]
+// CHECK:STDOUT:     %.loc3_14.3: type = converted %float.make_type.loc3_14, %.loc3_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %.loc3_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_22: init type = call constants.%struct.1(%.loc3_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_22.2: type = value_of_initializer %float.make_type.loc3_22 [template = f64]
+// CHECK:STDOUT:     %.loc3_22.3: type = converted %float.make_type.loc3_22, %.loc3_22.2 [template = f64]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +110,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc16_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_19: init type = call constants.%struct.1(%.loc16_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_19.2: type = value_of_initializer %float.make_type.loc16_19 [template = f64]
+// CHECK:STDOUT:     %.loc16_19.3: type = converted %float.make_type.loc16_19, %.loc16_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %.loc16_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_27: init type = call constants.%struct.1(%.loc16_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_27.2: type = value_of_initializer %float.make_type.loc16_27 [template = f64]
+// CHECK:STDOUT:     %.loc16_27.3: type = converted %float.make_type.loc16_27, %.loc16_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +143,10 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Less(%a: f64, %b: f64) -> bool = "float.less";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: f64) -> f64 = "float.negate";
@@ -107,12 +154,12 @@ 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: 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]
-// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %float.less.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.2: bool = converted %float.less.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Less.ref.loc9: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_21: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_26: f64 = float_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %float.less.loc9: init bool = call %Less.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %float.less.loc9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_13.2: bool = converted %float.less.loc9, %.loc9_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -126,12 +173,12 @@ 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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc10_22: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_27: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %float.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_27) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %float.less.loc10 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc10_14.2: bool = converted %float.less.loc10, %.loc10_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %Less.ref.loc10: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc10_22: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_27: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.less.loc10: init bool = call %Less.ref.loc10(%.loc10_22, %.loc10_27) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_14.1: bool = value_of_initializer %float.less.loc10 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc10_14.2: bool = converted %float.less.loc10, %.loc10_14.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc10_14.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -145,12 +192,12 @@ 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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc11_22: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_27: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %float.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_27) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %float.less.loc11 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc11_14.2: bool = converted %float.less.loc11, %.loc11_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %Less.ref.loc11: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc11_22: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_27: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %float.less.loc11: init bool = call %Less.ref.loc11(%.loc11_22, %.loc11_27) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %float.less.loc11 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc11_14.2: bool = converted %float.less.loc11, %.loc11_14.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -164,16 +211,16 @@ 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: 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_34: f64 = float_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc12_20.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_20.2: f64 = converted %float.negate.loc12, %.loc12_20.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_34) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %float.less.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.2: bool = converted %float.less.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Less.ref.loc12: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc12_28: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_28) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_34: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc12_20.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_20.2: f64 = converted %float.negate.loc12, %.loc12_20.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.less.loc12: init bool = call %Less.ref.loc12(%.loc12_20.2, %.loc12_34) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %float.less.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_13.2: bool = converted %float.less.loc12, %.loc12_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -187,16 +234,16 @@ 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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_22: f64 = float_literal 0 [template = constants.%.8]
-// 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_21.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_21.2: f64 = converted %float.negate.loc13, %.loc13_21.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %float.less.loc13 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc13_14.2: bool = converted %float.less.loc13, %.loc13_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %Less.ref.loc13: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc13_22: f64 = float_literal 0 [template = constants.%.9]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc13_34: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_34) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_21.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_21.2: f64 = converted %float.negate.loc13, %.loc13_21.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.less.loc13: init bool = call %Less.ref.loc13(%.loc13_22, %.loc13_21.2) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %float.less.loc13 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc13_14.2: bool = converted %float.less.loc13, %.loc13_14.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:
@@ -214,7 +261,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref: Less = name_ref Less, file.%Less.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:   %float.less: init bool = call %Less.ref(%a.ref, %b.ref)

+ 103 - 56
toolchain/check/testdata/builtins/float/less_eq.carbon

@@ -27,25 +27,30 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_less_eq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: LessEq = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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]
-// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.7: f64 = float_literal 0 [template]
-// CHECK:STDOUT:   %.8: bool = bool_literal false [template]
-// CHECK:STDOUT:   %.9: f64 = float_literal -1 [template]
+// CHECK:STDOUT:   %struct.5: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.8: f64 = float_literal 0 [template]
+// CHECK:STDOUT:   %.9: bool = bool_literal false [template]
+// CHECK:STDOUT:   %.10: f64 = float_literal -1 [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.4: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +64,45 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_14: init type = call constants.%struct.1(%.loc2_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_14.2: type = value_of_initializer %float.make_type.loc2_14 [template = f64]
+// CHECK:STDOUT:     %.loc2_14.3: type = converted %float.make_type.loc2_14, %.loc2_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_11.1: f64 = param a
 // CHECK:STDOUT:     @LessEq.%a: f64 = bind_name a, %a.loc2_11.1
+// CHECK:STDOUT:     %.loc2_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_22: init type = call constants.%struct.1(%.loc2_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_22.2: type = value_of_initializer %float.make_type.loc2_22 [template = f64]
+// CHECK:STDOUT:     %.loc2_22.3: type = converted %float.make_type.loc2_22, %.loc2_22.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_19.1: f64 = param b
 // CHECK:STDOUT:     @LessEq.%b: f64 = bind_name b, %b.loc2_19.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_30.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_30.2: type = converted %bool.make_type.loc2, %.loc2_30.1 [template = bool]
 // CHECK:STDOUT:     @LessEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %.loc3_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_14: init type = call constants.%struct.1(%.loc3_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_14.2: type = value_of_initializer %float.make_type.loc3_14 [template = f64]
+// CHECK:STDOUT:     %.loc3_14.3: type = converted %float.make_type.loc3_14, %.loc3_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc3_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %.loc3_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc3_22: init type = call constants.%struct.1(%.loc3_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc3_22.2: type = value_of_initializer %float.make_type.loc3_22 [template = f64]
+// CHECK:STDOUT:     %.loc3_22.3: type = converted %float.make_type.loc3_22, %.loc3_22.2 [template = f64]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +110,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc16_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_19: init type = call constants.%struct.1(%.loc16_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_19.2: type = value_of_initializer %float.make_type.loc16_19 [template = f64]
+// CHECK:STDOUT:     %.loc16_19.3: type = converted %float.make_type.loc16_19, %.loc16_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc16_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %.loc16_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc16_27: init type = call constants.%struct.1(%.loc16_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc16_27.2: type = value_of_initializer %float.make_type.loc16_27 [template = f64]
+// CHECK:STDOUT:     %.loc16_27.3: type = converted %float.make_type.loc16_27, %.loc16_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc16_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +143,10 @@ fn RuntimeCall(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @LessEq(%a: f64, %b: f64) -> bool = "float.less_eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: f64) -> f64 = "float.negate";
@@ -107,12 +154,12 @@ 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: 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]
-// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %float.less_eq.loc9 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc9_13.2: bool = converted %float.less_eq.loc9, %.loc9_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %LessEq.ref.loc9: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_23: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_28: f64 = float_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %float.less_eq.loc9: init bool = call %LessEq.ref.loc9(%.loc9_23, %.loc9_28) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_13.1: bool = value_of_initializer %float.less_eq.loc9 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc9_13.2: bool = converted %float.less_eq.loc9, %.loc9_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc9_13.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -126,12 +173,12 @@ 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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc10_28: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %float.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_28) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %float.less_eq.loc10 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc10_13.2: bool = converted %float.less_eq.loc10, %.loc10_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %LessEq.ref.loc10: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc10_23: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc10_28: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.less_eq.loc10: init bool = call %LessEq.ref.loc10(%.loc10_23, %.loc10_28) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_13.1: bool = value_of_initializer %float.less_eq.loc10 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc10_13.2: bool = converted %float.less_eq.loc10, %.loc10_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc10_13.2 br !if.expr.then.loc10 else br !if.expr.else.loc10
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc10:
@@ -145,12 +192,12 @@ 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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %float.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %float.less_eq.loc11 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc11_14.2: bool = converted %float.less_eq.loc11, %.loc11_14.1 [template = constants.%.8]
+// CHECK:STDOUT:   %LessEq.ref.loc11: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc11_24: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc11_29: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %float.less_eq.loc11: init bool = call %LessEq.ref.loc11(%.loc11_24, %.loc11_29) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_14.1: bool = value_of_initializer %float.less_eq.loc11 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc11_14.2: bool = converted %float.less_eq.loc11, %.loc11_14.1 [template = constants.%.9]
 // CHECK:STDOUT:   if %.loc11_14.2 br !if.expr.then.loc11 else br !if.expr.else.loc11
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc11:
@@ -164,16 +211,16 @@ 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: 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_36: f64 = float_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc12_22.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc12_22.2: f64 = converted %float.negate.loc12, %.loc12_22.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_36) [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %float.less_eq.loc12 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc12_13.2: bool = converted %float.less_eq.loc12, %.loc12_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %LessEq.ref.loc12: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc12_30: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc12: init f64 = call %Negate.ref.loc12(%.loc12_30) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_36: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc12_22.1: f64 = value_of_initializer %float.negate.loc12 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc12_22.2: f64 = converted %float.negate.loc12, %.loc12_22.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.less_eq.loc12: init bool = call %LessEq.ref.loc12(%.loc12_22.2, %.loc12_36) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_13.1: bool = value_of_initializer %float.less_eq.loc12 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc12_13.2: bool = converted %float.less_eq.loc12, %.loc12_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc12_13.2 br !if.expr.then.loc12 else br !if.expr.else.loc12
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc12:
@@ -187,16 +234,16 @@ 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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.7]
-// 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.%.4]
-// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.9]
-// CHECK:STDOUT:   %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.9]
-// CHECK:STDOUT:   %float.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %float.less_eq.loc13 [template = constants.%.8]
-// CHECK:STDOUT:   %.loc13_14.2: bool = converted %float.less_eq.loc13, %.loc13_14.1 [template = constants.%.8]
+// CHECK:STDOUT:   %LessEq.ref.loc13: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc13_24: f64 = float_literal 0 [template = constants.%.8]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc13_36: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.negate.loc13: init f64 = call %Negate.ref.loc13(%.loc13_36) [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_23.1: f64 = value_of_initializer %float.negate.loc13 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc13_23.2: f64 = converted %float.negate.loc13, %.loc13_23.1 [template = constants.%.10]
+// CHECK:STDOUT:   %float.less_eq.loc13: init bool = call %LessEq.ref.loc13(%.loc13_24, %.loc13_23.2) [template = constants.%.9]
+// CHECK:STDOUT:   %.loc13_14.1: bool = value_of_initializer %float.less_eq.loc13 [template = constants.%.9]
+// CHECK:STDOUT:   %.loc13_14.2: bool = converted %float.less_eq.loc13, %.loc13_14.1 [template = constants.%.9]
 // CHECK:STDOUT:   if %.loc13_14.2 br !if.expr.then.loc13 else br !if.expr.else.loc13
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc13:
@@ -214,7 +261,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref: LessEq = name_ref LessEq, file.%LessEq.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:   %float.less_eq: init bool = call %LessEq.ref(%a.ref, %b.ref)

+ 38 - 14
toolchain/check/testdata/builtins/float/make_type.carbon

@@ -43,9 +43,11 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Float = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %struct.2: Float = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -54,13 +56,19 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:     .Float = %Float.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float.decl: Float = fn_decl @Float [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Float.decl: Float = fn_decl @Float [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_16.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc4_16.2: type = converted %int.make_type_32, %.loc4_16.1 [template = i32]
 // 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>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use_types.carbon
@@ -71,27 +79,33 @@ var dyn: Float(dyn_size);
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.2: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %GetFloat: type = fn_type @GetFloat [template]
-// CHECK:STDOUT:   %struct.2: GetFloat = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: GetFloat = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Float = %import_ref
+// CHECK:STDOUT:     .Float = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .f = %f
 // CHECK:STDOUT:     .GetFloat = %GetFloat.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Float = import_ref ir1, inst+5, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir1, inst+14, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, %import_ref.1 [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.decl: GetFloat = fn_decl @GetFloat [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %GetFloat.decl: GetFloat = fn_decl @GetFloat [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.2() [template = i32]
+// CHECK:STDOUT:     %.loc8_23.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc8_23.2: type = converted %int.make_type_32, %.loc8_23.1 [template = i32]
 // 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>
@@ -100,9 +114,11 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @GetFloat(%dyn_size: i32) -> type {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, file.%import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:   %Float.ref: Float = name_ref Float, file.%import_ref.1 [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
@@ -122,31 +138,37 @@ var dyn: Float(dyn_size);
 // 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:   %struct.1: Float = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.2: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 64 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Float = %import_ref
+// CHECK:STDOUT:     .Float = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .invalid_float = %invalid_float
 // CHECK:STDOUT:     .dyn_size = %dyn_size
 // CHECK:STDOUT:     .dyn = %dyn
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Float = import_ref ir1, inst+5, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir1, inst+14, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Float.ref.loc10: Float = name_ref Float, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %Float.ref.loc10: Float = name_ref Float, %import_ref.1 [template = constants.%struct.1]
 // 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>]
 // CHECK:STDOUT:   %invalid_float.var: ref <error> = var invalid_float
 // CHECK:STDOUT:   %invalid_float: ref <error> = bind_name invalid_float, %invalid_float.var
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.2() [template = i32]
+// CHECK:STDOUT:   %.loc12_15.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc12_15.2: type = converted %int.make_type_32, %.loc12_15.1 [template = i32]
 // 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: Float = name_ref Float, %import_ref [template = constants.%struct]
+// CHECK:STDOUT:   %Float.ref.loc16: Float = name_ref Float, %import_ref.1 [template = constants.%struct.1]
 // 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)
@@ -158,6 +180,8 @@ var dyn: Float(dyn_size);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc12: i32 = int_literal 64 [template = constants.%.3]

+ 183 - 31
toolchain/check/testdata/builtins/float/mul.carbon

@@ -49,14 +49,17 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- mul_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 0.5 [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -67,29 +70,66 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc2_11.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_11: init type = call constants.%struct.1(%.loc2_11.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_11.2: type = value_of_initializer %float.make_type.loc2_11 [template = f64]
+// CHECK:STDOUT:     %.loc2_11.3: type = converted %float.make_type.loc2_11, %.loc2_11.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Mul.%a: f64 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %.loc2_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_19: init type = call constants.%struct.1(%.loc2_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_19.2: type = value_of_initializer %float.make_type.loc2_19 [template = f64]
+// CHECK:STDOUT:     %.loc2_19.3: type = converted %float.make_type.loc2_19, %.loc2_19.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Mul.%b: f64 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %.loc2_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_27: init type = call constants.%struct.1(%.loc2_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_27.2: type = value_of_initializer %float.make_type.loc2_27 [template = f64]
+// CHECK:STDOUT:     %.loc2_27.3: type = converted %float.make_type.loc2_27, %.loc2_27.2 [template = f64]
 // CHECK:STDOUT:     @Mul.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc4_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_19: init type = call constants.%struct.1(%.loc4_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_19.2: type = value_of_initializer %float.make_type.loc4_19 [template = f64]
+// CHECK:STDOUT:     %.loc4_19.3: type = converted %float.make_type.loc4_19, %.loc4_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
+// CHECK:STDOUT:     %.loc4_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_27: init type = call constants.%struct.1(%.loc4_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_27.2: type = value_of_initializer %float.make_type.loc4_27 [template = f64]
+// CHECK:STDOUT:     %.loc4_27.3: type = converted %float.make_type.loc4_27, %.loc4_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
+// CHECK:STDOUT:     %.loc4_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_35: init type = call constants.%struct.1(%.loc4_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_35.2: type = value_of_initializer %float.make_type.loc4_35 [template = f64]
+// CHECK:STDOUT:     %.loc4_35.3: type = converted %float.make_type.loc4_35, %.loc4_35.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc8_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_8.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:   %.loc8_8.3: type = converted %float.make_type.loc8, %.loc8_8.2 [template = f64]
 // CHECK:STDOUT:   %x.var: ref f64 = var x
 // CHECK:STDOUT:   %x: ref f64 = bind_name x, %x.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mul(%a: f64, %b: f64) -> f64 = "float.mul";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.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:   %float.mul: init f64 = call %Mul.ref(%a.ref, %b.ref)
@@ -100,10 +140,10 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// 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:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.4]
+// CHECK:STDOUT:   %float.mul: init f64 = call %Mul.ref(%.loc8_18, %.loc8_23) [template = constants.%.5]
 // CHECK:STDOUT:   assign file.%x.var, %float.mul
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -111,21 +151,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: JustRight = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
-// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -140,68 +185,175 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc8_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_14: init type = call constants.%struct.1(%.loc8_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_14.2: type = value_of_initializer %float.make_type.loc8_14 [template = f64]
+// CHECK:STDOUT:     %.loc8_14.3: type = converted %float.make_type.loc8_14, %.loc8_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %.loc8_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_22: init type = call constants.%struct.1(%.loc8_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_22.2: type = value_of_initializer %float.make_type.loc8_22 [template = f64]
+// CHECK:STDOUT:     %.loc8_22.3: type = converted %float.make_type.loc8_22, %.loc8_22.2 [template = f64]
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc13_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_15: init type = call constants.%struct.1(%.loc13_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_15.2: type = value_of_initializer %float.make_type.loc13_15 [template = f64]
+// CHECK:STDOUT:     %.loc13_15.3: type = converted %float.make_type.loc13_15, %.loc13_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %.loc13_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_23: init type = call constants.%struct.1(%.loc13_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_23.2: type = value_of_initializer %float.make_type.loc13_23 [template = f64]
+// CHECK:STDOUT:     %.loc13_23.3: type = converted %float.make_type.loc13_23, %.loc13_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %.loc13_31.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_31: init type = call constants.%struct.1(%.loc13_31.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_31.2: type = value_of_initializer %float.make_type.loc13_31 [template = f64]
+// CHECK:STDOUT:     %.loc13_31.3: type = converted %float.make_type.loc13_31, %.loc13_31.2 [template = f64]
 // CHECK:STDOUT:     %c.loc13_28.1: f64 = param c
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %.loc13_39.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_39: init type = call constants.%struct.1(%.loc13_39.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_39.2: type = value_of_initializer %float.make_type.loc13_39 [template = f64]
+// CHECK:STDOUT:     %.loc13_39.3: type = converted %float.make_type.loc13_39, %.loc13_39.2 [template = f64]
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc17_21.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_21: init type = call constants.%struct.1(%.loc17_21.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_21.2: type = value_of_initializer %float.make_type.loc17_21 [template = f64]
+// CHECK:STDOUT:     %.loc17_21.3: type = converted %float.make_type.loc17_21, %.loc17_21.2 [template = f64]
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
+// CHECK:STDOUT:     %.loc17_29.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_29: init type = call constants.%struct.1(%.loc17_29.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_29.2: type = value_of_initializer %float.make_type.loc17_29 [template = f64]
+// CHECK:STDOUT:     %.loc17_29.3: type = converted %float.make_type.loc17_29, %.loc17_29.2 [template = f64]
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
+// CHECK:STDOUT:     %bool.make_type.loc17: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc17_37.1: type = value_of_initializer %bool.make_type.loc17 [template = bool]
+// CHECK:STDOUT:     %.loc17_37.2: type = converted %bool.make_type.loc17, %.loc17_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc18_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_17: init type = call constants.%struct.1(%.loc18_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_17.2: type = value_of_initializer %float.make_type.loc18_17 [template = f64]
+// CHECK:STDOUT:     %.loc18_17.3: type = converted %float.make_type.loc18_17, %.loc18_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
+// CHECK:STDOUT:     %.loc18_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_25: init type = call constants.%struct.1(%.loc18_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_25.2: type = value_of_initializer %float.make_type.loc18_25 [template = f64]
+// CHECK:STDOUT:     %.loc18_25.3: type = converted %float.make_type.loc18_25, %.loc18_25.2 [template = f64]
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
+// CHECK:STDOUT:     %.loc18_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_33: init type = call constants.%struct.1(%.loc18_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_33.2: type = value_of_initializer %float.make_type.loc18_33 [template = f64]
+// CHECK:STDOUT:     %.loc18_33.3: type = converted %float.make_type.loc18_33, %.loc18_33.2 [template = f64]
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %.loc20_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_25: init type = call constants.%struct.1(%.loc20_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_25.2: type = value_of_initializer %float.make_type.loc20_25 [template = f64]
+// CHECK:STDOUT:     %.loc20_25.3: type = converted %float.make_type.loc20_25, %.loc20_25.2 [template = f64]
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
+// CHECK:STDOUT:     %.loc20_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_33: init type = call constants.%struct.1(%.loc20_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_33.2: type = value_of_initializer %float.make_type.loc20_33 [template = f64]
+// CHECK:STDOUT:     %.loc20_33.3: type = converted %float.make_type.loc20_33, %.loc20_33.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %.loc24_26.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_26: init type = call constants.%struct.1(%.loc24_26.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_26.2: type = value_of_initializer %float.make_type.loc24_26 [template = f64]
+// CHECK:STDOUT:     %.loc24_26.3: type = converted %float.make_type.loc24_26, %.loc24_26.2 [template = f64]
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
+// CHECK:STDOUT:     %.loc24_34.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_34: init type = call constants.%struct.1(%.loc24_34.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_34.2: type = value_of_initializer %float.make_type.loc24_34 [template = f64]
+// CHECK:STDOUT:     %.loc24_34.3: type = converted %float.make_type.loc24_34, %.loc24_34.2 [template = f64]
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: f64 = bind_name b, %b.loc24_31.1
+// CHECK:STDOUT:     %.loc24_42.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_42: init type = call constants.%struct.1(%.loc24_42.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_42.2: type = value_of_initializer %float.make_type.loc24_42 [template = f64]
+// CHECK:STDOUT:     %.loc24_42.3: type = converted %float.make_type.loc24_42, %.loc24_42.2 [template = f64]
 // CHECK:STDOUT:     %c.loc24_39.1: f64 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
+// CHECK:STDOUT:     %.loc24_50.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_50: init type = call constants.%struct.1(%.loc24_50.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_50.2: type = value_of_initializer %float.make_type.loc24_50 [template = f64]
+// CHECK:STDOUT:     %.loc24_50.3: type = converted %float.make_type.loc24_50, %.loc24_50.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %.loc28_32.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_32: init type = call constants.%struct.1(%.loc28_32.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_32.2: type = value_of_initializer %float.make_type.loc28_32 [template = f64]
+// CHECK:STDOUT:     %.loc28_32.3: type = converted %float.make_type.loc28_32, %.loc28_32.2 [template = f64]
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
+// CHECK:STDOUT:     %.loc28_40.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_40: init type = call constants.%struct.1(%.loc28_40.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_40.2: type = value_of_initializer %float.make_type.loc28_40 [template = f64]
+// CHECK:STDOUT:     %.loc28_40.3: type = converted %float.make_type.loc28_40, %.loc28_40.2 [template = f64]
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: f64 = bind_name b, %b.loc28_37.1
+// CHECK:STDOUT:     %bool.make_type.loc28: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc28_48.1: type = value_of_initializer %bool.make_type.loc28 [template = bool]
+// CHECK:STDOUT:     %.loc28_48.2: type = converted %bool.make_type.loc28, %.loc28_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: f64) -> f64;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: f64, %b: f64, %c: f64) -> f64;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: f64, %b: f64) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: f64, %b: f64) -> f64 = "float.mul";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -211,7 +363,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: f64 = name_ref c, %c
@@ -223,7 +375,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)

+ 158 - 31
toolchain/check/testdata/builtins/float/negate.carbon

@@ -70,13 +70,16 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 1.5 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal -1.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -86,31 +89,63 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc2_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_14: init type = call constants.%struct.1(%.loc2_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_14.2: type = value_of_initializer %float.make_type.loc2_14 [template = f64]
+// CHECK:STDOUT:     %.loc2_14.3: type = converted %float.make_type.loc2_14, %.loc2_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_11.1: f64 = param a
 // CHECK:STDOUT:     @Negate.%a: f64 = bind_name a, %a.loc2_11.1
+// CHECK:STDOUT:     %.loc2_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_22: init type = call constants.%struct.1(%.loc2_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_22.2: type = value_of_initializer %float.make_type.loc2_22 [template = f64]
+// CHECK:STDOUT:     %.loc2_22.3: type = converted %float.make_type.loc2_22, %.loc2_22.2 [template = f64]
 // CHECK:STDOUT:     @Negate.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc4_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_19: init type = call constants.%struct.1(%.loc4_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_19.2: type = value_of_initializer %float.make_type.loc4_19 [template = f64]
+// CHECK:STDOUT:     %.loc4_19.3: type = converted %float.make_type.loc4_19, %.loc4_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
+// CHECK:STDOUT:     %.loc4_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_27: init type = call constants.%struct.1(%.loc4_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_27.2: type = value_of_initializer %float.make_type.loc4_27 [template = f64]
+// CHECK:STDOUT:     %.loc4_27.3: type = converted %float.make_type.loc4_27, %.loc4_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
+// CHECK:STDOUT:     %.loc4_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_35: init type = call constants.%struct.1(%.loc4_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_35.2: type = value_of_initializer %float.make_type.loc4_35 [template = f64]
+// CHECK:STDOUT:     %.loc4_35.3: type = converted %float.make_type.loc4_35, %.loc4_35.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %.loc8_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_8.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:   %.loc8_8.3: type = converted %float.make_type.loc8, %.loc8_8.2 [template = f64]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_21: f64 = float_literal 1.5 [template = constants.%.3]
+// CHECK:STDOUT:   %float.negate: init f64 = call %Negate.ref(%.loc8_21) [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_25.1: f64 = value_of_initializer %float.negate [template = constants.%.4]
+// CHECK:STDOUT:   %.loc8_25.2: f64 = converted %float.negate, %.loc8_25.1 [template = constants.%.4]
 // CHECK:STDOUT:   %a.loc8: f64 = bind_name a, %.loc8_25.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: f64) -> f64 = "float.negate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // 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
@@ -121,21 +156,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: JustRight = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
-// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -150,60 +190,147 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc8_16.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_16.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_16.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:     %.loc8_16.3: type = converted %float.make_type.loc8, %.loc8_16.2 [template = f64]
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc13_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_15: init type = call constants.%struct.1(%.loc13_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_15.2: type = value_of_initializer %float.make_type.loc13_15 [template = f64]
+// CHECK:STDOUT:     %.loc13_15.3: type = converted %float.make_type.loc13_15, %.loc13_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %.loc13_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_23: init type = call constants.%struct.1(%.loc13_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_23.2: type = value_of_initializer %float.make_type.loc13_23 [template = f64]
+// CHECK:STDOUT:     %.loc13_23.3: type = converted %float.make_type.loc13_23, %.loc13_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %.loc13_31.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_31: init type = call constants.%struct.1(%.loc13_31.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_31.2: type = value_of_initializer %float.make_type.loc13_31 [template = f64]
+// CHECK:STDOUT:     %.loc13_31.3: type = converted %float.make_type.loc13_31, %.loc13_31.2 [template = f64]
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc18_21.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18: init type = call constants.%struct.1(%.loc18_21.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_21.2: type = value_of_initializer %float.make_type.loc18 [template = f64]
+// CHECK:STDOUT:     %.loc18_21.3: type = converted %float.make_type.loc18, %.loc18_21.2 [template = f64]
 // CHECK:STDOUT:     %a.loc18_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc18_18.1
+// CHECK:STDOUT:     %bool.make_type.loc18: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %bool.make_type.loc18 [template = bool]
+// CHECK:STDOUT:     %.loc18_29.2: type = converted %bool.make_type.loc18, %.loc18_29.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc19_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc19_17: init type = call constants.%struct.1(%.loc19_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc19_17.2: type = value_of_initializer %float.make_type.loc19_17 [template = f64]
+// CHECK:STDOUT:     %.loc19_17.3: type = converted %float.make_type.loc19_17, %.loc19_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc19_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc19_14.1
+// CHECK:STDOUT:     %.loc19_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc19_25: init type = call constants.%struct.1(%.loc19_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc19_25.2: type = value_of_initializer %float.make_type.loc19_25 [template = f64]
+// CHECK:STDOUT:     %.loc19_25.3: type = converted %float.make_type.loc19_25, %.loc19_25.2 [template = f64]
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.9: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.10: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %.loc21_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc21_25: init type = call constants.%struct.1(%.loc21_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc21_25.2: type = value_of_initializer %float.make_type.loc21_25 [template = f64]
+// CHECK:STDOUT:     %.loc21_25.3: type = converted %float.make_type.loc21_25, %.loc21_25.2 [template = f64]
 // CHECK:STDOUT:     %a.loc21_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc21_22.1
+// CHECK:STDOUT:     %.loc21_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc21_33: init type = call constants.%struct.1(%.loc21_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc21_33.2: type = value_of_initializer %float.make_type.loc21_33 [template = f64]
+// CHECK:STDOUT:     %.loc21_33.3: type = converted %float.make_type.loc21_33, %.loc21_33.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.11: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.13: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %.loc32_26.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc32_26: init type = call constants.%struct.1(%.loc32_26.1) [template = f64]
+// CHECK:STDOUT:     %.loc32_26.2: type = value_of_initializer %float.make_type.loc32_26 [template = f64]
+// CHECK:STDOUT:     %.loc32_26.3: type = converted %float.make_type.loc32_26, %.loc32_26.2 [template = f64]
 // CHECK:STDOUT:     %a.loc32_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc32_23.1
+// CHECK:STDOUT:     %.loc32_34.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc32_34: init type = call constants.%struct.1(%.loc32_34.1) [template = f64]
+// CHECK:STDOUT:     %.loc32_34.2: type = value_of_initializer %float.make_type.loc32_34 [template = f64]
+// CHECK:STDOUT:     %.loc32_34.3: type = converted %float.make_type.loc32_34, %.loc32_34.2 [template = f64]
 // CHECK:STDOUT:     %b.loc32_31.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: f64 = bind_name b, %b.loc32_31.1
+// CHECK:STDOUT:     %.loc32_42.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc32_42: init type = call constants.%struct.1(%.loc32_42.1) [template = f64]
+// CHECK:STDOUT:     %.loc32_42.2: type = value_of_initializer %float.make_type.loc32_42 [template = f64]
+// CHECK:STDOUT:     %.loc32_42.3: type = converted %float.make_type.loc32_42, %.loc32_42.2 [template = f64]
 // CHECK:STDOUT:     %c.loc32_39.1: f64 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc32_39.1
+// CHECK:STDOUT:     %.loc32_50.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc32_50: init type = call constants.%struct.1(%.loc32_50.1) [template = f64]
+// CHECK:STDOUT:     %.loc32_50.2: type = value_of_initializer %float.make_type.loc32_50 [template = f64]
+// CHECK:STDOUT:     %.loc32_50.3: type = converted %float.make_type.loc32_50, %.loc32_50.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.15: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %.loc43_32.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc43_32: init type = call constants.%struct.1(%.loc43_32.1) [template = f64]
+// CHECK:STDOUT:     %.loc43_32.2: type = value_of_initializer %float.make_type.loc43_32 [template = f64]
+// CHECK:STDOUT:     %.loc43_32.3: type = converted %float.make_type.loc43_32, %.loc43_32.2 [template = f64]
 // CHECK:STDOUT:     %a.loc43_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc43_29.1
+// CHECK:STDOUT:     %.loc43_40.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc43_40: init type = call constants.%struct.1(%.loc43_40.1) [template = f64]
+// CHECK:STDOUT:     %.loc43_40.2: type = value_of_initializer %float.make_type.loc43_40 [template = f64]
+// CHECK:STDOUT:     %.loc43_40.3: type = converted %float.make_type.loc43_40, %.loc43_40.2 [template = f64]
 // CHECK:STDOUT:     %b.loc43_37.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: f64 = bind_name b, %b.loc43_37.1
+// CHECK:STDOUT:     %bool.make_type.loc43: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc43_48.1: type = value_of_initializer %bool.make_type.loc43 [template = bool]
+// CHECK:STDOUT:     %.loc43_48.2: type = converted %bool.make_type.loc43, %.loc43_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew() -> f64;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: f64, %b: f64) -> f64;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: f64) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: f64) -> f64 = "float.negate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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>]
@@ -213,7 +340,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: f64 = name_ref c, %c
@@ -225,7 +352,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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>]

+ 86 - 29
toolchain/check/testdata/builtins/float/neq.carbon

@@ -32,21 +32,26 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT: --- float_neq.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
 // 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:   %struct.3: Neq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
-// CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [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]
-// CHECK:STDOUT:   %.6: bool = bool_literal true [template]
-// CHECK:STDOUT:   %.7: bool = bool_literal false [template]
+// CHECK:STDOUT:   %struct.4: F = struct_value () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1 [template]
+// CHECK:STDOUT:   %.6: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.7: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.8: bool = bool_literal false [template]
 // CHECK:STDOUT:   %RuntimeCall: type = fn_type @RuntimeCall [template]
-// CHECK:STDOUT:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,16 +64,30 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc2_11.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_11: init type = call constants.%struct.1(%.loc2_11.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_11.2: type = value_of_initializer %float.make_type.loc2_11 [template = f64]
+// CHECK:STDOUT:     %.loc2_11.3: type = converted %float.make_type.loc2_11, %.loc2_11.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Neq.%a: f64 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %.loc2_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_19: init type = call constants.%struct.1(%.loc2_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_19.2: type = value_of_initializer %float.make_type.loc2_19 [template = f64]
+// CHECK:STDOUT:     %.loc2_19.3: type = converted %float.make_type.loc2_19, %.loc2_19.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Neq.%b: f64 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %bool.make_type.loc2, %.loc2_27.1 [template = bool]
 // CHECK:STDOUT:     @Neq.%return: ref bool = 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.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.4] {
 // 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
@@ -76,11 +95,25 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc12_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc12_19: init type = call constants.%struct.1(%.loc12_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc12_19.2: type = value_of_initializer %float.make_type.loc12_19 [template = f64]
+// CHECK:STDOUT:     %.loc12_19.3: type = converted %float.make_type.loc12_19, %.loc12_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc12_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc12_16.1
+// CHECK:STDOUT:     %.loc12_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc12_27: init type = call constants.%struct.1(%.loc12_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc12_27.2: type = value_of_initializer %float.make_type.loc12_27 [template = f64]
+// CHECK:STDOUT:     %.loc12_27.3: type = converted %float.make_type.loc12_27, %.loc12_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc12_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc12_24.1
+// CHECK:STDOUT:     %bool.make_type.loc12: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc12_35.1: type = value_of_initializer %bool.make_type.loc12 [template = bool]
+// CHECK:STDOUT:     %.loc12_35.2: type = converted %bool.make_type.loc12, %.loc12_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -95,17 +128,21 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Neq(%a: f64, %b: f64) -> bool = "float.neq";
 // CHECK:STDOUT:
 // 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: 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]
-// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %float.neq.loc8 [template = constants.%.6]
-// CHECK:STDOUT:   %.loc8_13.2: bool = converted %float.neq.loc8, %.loc8_13.1 [template = constants.%.6]
+// CHECK:STDOUT:   %Neq.ref.loc8: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc8_20: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc8_25: f64 = float_literal 2 [template = constants.%.6]
+// CHECK:STDOUT:   %float.neq.loc8: init bool = call %Neq.ref.loc8(%.loc8_20, %.loc8_25) [template = constants.%.7]
+// CHECK:STDOUT:   %.loc8_13.1: bool = value_of_initializer %float.neq.loc8 [template = constants.%.7]
+// CHECK:STDOUT:   %.loc8_13.2: bool = converted %float.neq.loc8, %.loc8_13.1 [template = constants.%.7]
 // CHECK:STDOUT:   if %.loc8_13.2 br !if.expr.then.loc8 else br !if.expr.else.loc8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc8:
@@ -119,12 +156,12 @@ 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: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
-// CHECK:STDOUT:   %.loc9_21: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %.loc9_26: f64 = float_literal 1 [template = constants.%.4]
-// CHECK:STDOUT:   %float.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.neq.loc9 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.neq.loc9, %.loc9_14.1 [template = constants.%.7]
+// CHECK:STDOUT:   %Neq.ref.loc9: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc9_21: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc9_26: f64 = float_literal 1 [template = constants.%.5]
+// CHECK:STDOUT:   %float.neq.loc9: init bool = call %Neq.ref.loc9(%.loc9_21, %.loc9_26) [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_14.1: bool = value_of_initializer %float.neq.loc9 [template = constants.%.8]
+// CHECK:STDOUT:   %.loc9_14.2: bool = converted %float.neq.loc9, %.loc9_14.1 [template = constants.%.8]
 // CHECK:STDOUT:   if %.loc9_14.2 br !if.expr.then.loc9 else br !if.expr.else.loc9
 // CHECK:STDOUT:
 // CHECK:STDOUT: !if.expr.then.loc9:
@@ -142,7 +179,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: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Neq.ref: Neq = name_ref Neq, file.%Neq.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:   %float.neq: init bool = call %Neq.ref(%a.ref, %b.ref)
@@ -154,9 +191,12 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [template]
 // CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
-// CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT:   %struct.2: WrongResult = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -165,14 +205,31 @@ fn WrongResult(a: f64, b: f64) -> f64 = "float.neq";
 // CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc7_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_19: init type = call constants.%struct.1(%.loc7_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_19.2: type = value_of_initializer %float.make_type.loc7_19 [template = f64]
+// CHECK:STDOUT:     %.loc7_19.3: type = converted %float.make_type.loc7_19, %.loc7_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc7_16.1: f64 = param a
 // CHECK:STDOUT:     @WrongResult.%a: f64 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %.loc7_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_27: init type = call constants.%struct.1(%.loc7_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_27.2: type = value_of_initializer %float.make_type.loc7_27 [template = f64]
+// CHECK:STDOUT:     %.loc7_27.3: type = converted %float.make_type.loc7_27, %.loc7_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc7_24.1: f64 = param b
 // CHECK:STDOUT:     @WrongResult.%b: f64 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %.loc7_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc7_35: init type = call constants.%struct.1(%.loc7_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc7_35.2: type = value_of_initializer %float.make_type.loc7_35 [template = f64]
+// CHECK:STDOUT:     %.loc7_35.3: type = converted %float.make_type.loc7_35, %.loc7_35.2 [template = f64]
 // CHECK:STDOUT:     @WrongResult.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @WrongResult(%a: f64, %b: f64) -> f64;
 // CHECK:STDOUT:

+ 183 - 31
toolchain/check/testdata/builtins/float/sub.carbon

@@ -49,14 +49,17 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- float_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
+// CHECK:STDOUT:   %.3: f64 = float_literal 2 [template]
+// CHECK:STDOUT:   %.4: f64 = float_literal 0.5 [template]
+// CHECK:STDOUT:   %.5: f64 = float_literal 1.5 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -67,29 +70,66 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc2_11.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_11: init type = call constants.%struct.1(%.loc2_11.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_11.2: type = value_of_initializer %float.make_type.loc2_11 [template = f64]
+// CHECK:STDOUT:     %.loc2_11.3: type = converted %float.make_type.loc2_11, %.loc2_11.2 [template = f64]
 // CHECK:STDOUT:     %a.loc2_8.1: f64 = param a
 // CHECK:STDOUT:     @Sub.%a: f64 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %.loc2_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_19: init type = call constants.%struct.1(%.loc2_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_19.2: type = value_of_initializer %float.make_type.loc2_19 [template = f64]
+// CHECK:STDOUT:     %.loc2_19.3: type = converted %float.make_type.loc2_19, %.loc2_19.2 [template = f64]
 // CHECK:STDOUT:     %b.loc2_16.1: f64 = param b
 // CHECK:STDOUT:     @Sub.%b: f64 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %.loc2_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc2_27: init type = call constants.%struct.1(%.loc2_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc2_27.2: type = value_of_initializer %float.make_type.loc2_27 [template = f64]
+// CHECK:STDOUT:     %.loc2_27.3: type = converted %float.make_type.loc2_27, %.loc2_27.2 [template = f64]
 // CHECK:STDOUT:     @Sub.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc4_19.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_19: init type = call constants.%struct.1(%.loc4_19.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_19.2: type = value_of_initializer %float.make_type.loc4_19 [template = f64]
+// CHECK:STDOUT:     %.loc4_19.3: type = converted %float.make_type.loc4_19, %.loc4_19.2 [template = f64]
 // CHECK:STDOUT:     %a.loc4_16.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: f64 = bind_name a, %a.loc4_16.1
+// CHECK:STDOUT:     %.loc4_27.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_27: init type = call constants.%struct.1(%.loc4_27.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_27.2: type = value_of_initializer %float.make_type.loc4_27 [template = f64]
+// CHECK:STDOUT:     %.loc4_27.3: type = converted %float.make_type.loc4_27, %.loc4_27.2 [template = f64]
 // CHECK:STDOUT:     %b.loc4_24.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: f64 = bind_name b, %b.loc4_24.1
+// CHECK:STDOUT:     %.loc4_35.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc4_35: init type = call constants.%struct.1(%.loc4_35.1) [template = f64]
+// CHECK:STDOUT:     %.loc4_35.2: type = value_of_initializer %float.make_type.loc4_35 [template = f64]
+// CHECK:STDOUT:     %.loc4_35.3: type = converted %float.make_type.loc4_35, %.loc4_35.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %.loc8_8.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %float.make_type.loc8: init type = call constants.%struct.1(%.loc8_8.1) [template = f64]
+// CHECK:STDOUT:   %.loc8_8.2: type = value_of_initializer %float.make_type.loc8 [template = f64]
+// CHECK:STDOUT:   %.loc8_8.3: type = converted %float.make_type.loc8, %.loc8_8.2 [template = f64]
 // CHECK:STDOUT:   %x.var: ref f64 = var x
 // CHECK:STDOUT:   %x: ref f64 = bind_name x, %x.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: f64, %b: f64) -> f64 = "float.sub";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: f64, %b: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.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:   %float.sub: init f64 = call %Sub.ref(%a.ref, %b.ref)
@@ -100,10 +140,10 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// 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:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %.loc8_18: f64 = float_literal 2 [template = constants.%.3]
+// CHECK:STDOUT:   %.loc8_23: f64 = float_literal 0.5 [template = constants.%.4]
+// CHECK:STDOUT:   %float.sub: init f64 = call %Sub.ref(%.loc8_18, %.loc8_23) [template = constants.%.5]
 // CHECK:STDOUT:   assign file.%x.var, %float.sub
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -111,21 +151,26 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: i32 = int_literal 64 [template]
+// CHECK:STDOUT:   %Float: type = fn_type @Float [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Float = struct_value () [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:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: JustRight = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooFew: type = fn_type @RuntimeCallTooFew [template]
-// CHECK:STDOUT:   %struct.5: RuntimeCallTooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -140,68 +185,175 @@ fn RuntimeCallBadReturnType(a: f64, b: f64) -> bool {
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %.loc8_14.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_14: init type = call constants.%struct.1(%.loc8_14.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_14.2: type = value_of_initializer %float.make_type.loc8_14 [template = f64]
+// CHECK:STDOUT:     %.loc8_14.3: type = converted %float.make_type.loc8_14, %.loc8_14.2 [template = f64]
 // CHECK:STDOUT:     %a.loc8_11.1: f64 = param a
 // CHECK:STDOUT:     @TooFew.%a: f64 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %.loc8_22.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc8_22: init type = call constants.%struct.1(%.loc8_22.1) [template = f64]
+// CHECK:STDOUT:     %.loc8_22.2: type = value_of_initializer %float.make_type.loc8_22 [template = f64]
+// CHECK:STDOUT:     %.loc8_22.3: type = converted %float.make_type.loc8_22, %.loc8_22.2 [template = f64]
 // CHECK:STDOUT:     @TooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %.loc13_15.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_15: init type = call constants.%struct.1(%.loc13_15.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_15.2: type = value_of_initializer %float.make_type.loc13_15 [template = f64]
+// CHECK:STDOUT:     %.loc13_15.3: type = converted %float.make_type.loc13_15, %.loc13_15.2 [template = f64]
 // CHECK:STDOUT:     %a.loc13_12.1: f64 = param a
 // CHECK:STDOUT:     @TooMany.%a: f64 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %.loc13_23.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_23: init type = call constants.%struct.1(%.loc13_23.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_23.2: type = value_of_initializer %float.make_type.loc13_23 [template = f64]
+// CHECK:STDOUT:     %.loc13_23.3: type = converted %float.make_type.loc13_23, %.loc13_23.2 [template = f64]
 // CHECK:STDOUT:     %b.loc13_20.1: f64 = param b
 // CHECK:STDOUT:     @TooMany.%b: f64 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %.loc13_31.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_31: init type = call constants.%struct.1(%.loc13_31.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_31.2: type = value_of_initializer %float.make_type.loc13_31 [template = f64]
+// CHECK:STDOUT:     %.loc13_31.3: type = converted %float.make_type.loc13_31, %.loc13_31.2 [template = f64]
 // CHECK:STDOUT:     %c.loc13_28.1: f64 = param c
 // CHECK:STDOUT:     @TooMany.%c: f64 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %.loc13_39.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc13_39: init type = call constants.%struct.1(%.loc13_39.1) [template = f64]
+// CHECK:STDOUT:     %.loc13_39.2: type = value_of_initializer %float.make_type.loc13_39 [template = f64]
+// CHECK:STDOUT:     %.loc13_39.3: type = converted %float.make_type.loc13_39, %.loc13_39.2 [template = f64]
 // CHECK:STDOUT:     @TooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %.loc17_21.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_21: init type = call constants.%struct.1(%.loc17_21.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_21.2: type = value_of_initializer %float.make_type.loc17_21 [template = f64]
+// CHECK:STDOUT:     %.loc17_21.3: type = converted %float.make_type.loc17_21, %.loc17_21.2 [template = f64]
 // CHECK:STDOUT:     %a.loc17_18.1: f64 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: f64 = bind_name a, %a.loc17_18.1
+// CHECK:STDOUT:     %.loc17_29.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc17_29: init type = call constants.%struct.1(%.loc17_29.1) [template = f64]
+// CHECK:STDOUT:     %.loc17_29.2: type = value_of_initializer %float.make_type.loc17_29 [template = f64]
+// CHECK:STDOUT:     %.loc17_29.3: type = converted %float.make_type.loc17_29, %.loc17_29.2 [template = f64]
 // CHECK:STDOUT:     %b.loc17_26.1: f64 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: f64 = bind_name b, %b.loc17_26.1
+// CHECK:STDOUT:     %bool.make_type.loc17: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc17_37.1: type = value_of_initializer %bool.make_type.loc17 [template = bool]
+// CHECK:STDOUT:     %.loc17_37.2: type = converted %bool.make_type.loc17, %.loc17_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %.loc18_17.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_17: init type = call constants.%struct.1(%.loc18_17.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_17.2: type = value_of_initializer %float.make_type.loc18_17 [template = f64]
+// CHECK:STDOUT:     %.loc18_17.3: type = converted %float.make_type.loc18_17, %.loc18_17.2 [template = f64]
 // CHECK:STDOUT:     %a.loc18_14.1: f64 = param a
 // CHECK:STDOUT:     @JustRight.%a: f64 = bind_name a, %a.loc18_14.1
+// CHECK:STDOUT:     %.loc18_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_25: init type = call constants.%struct.1(%.loc18_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_25.2: type = value_of_initializer %float.make_type.loc18_25 [template = f64]
+// CHECK:STDOUT:     %.loc18_25.3: type = converted %float.make_type.loc18_25, %.loc18_25.2 [template = f64]
 // CHECK:STDOUT:     %b.loc18_22.1: f64 = param b
 // CHECK:STDOUT:     @JustRight.%b: f64 = bind_name b, %b.loc18_22.1
+// CHECK:STDOUT:     %.loc18_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc18_33: init type = call constants.%struct.1(%.loc18_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc18_33.2: type = value_of_initializer %float.make_type.loc18_33 [template = f64]
+// CHECK:STDOUT:     %.loc18_33.3: type = converted %float.make_type.loc18_33, %.loc18_33.2 [template = f64]
 // CHECK:STDOUT:     @JustRight.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %.loc20_25.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_25: init type = call constants.%struct.1(%.loc20_25.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_25.2: type = value_of_initializer %float.make_type.loc20_25 [template = f64]
+// CHECK:STDOUT:     %.loc20_25.3: type = converted %float.make_type.loc20_25, %.loc20_25.2 [template = f64]
 // CHECK:STDOUT:     %a.loc20_22.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: f64 = bind_name a, %a.loc20_22.1
+// CHECK:STDOUT:     %.loc20_33.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc20_33: init type = call constants.%struct.1(%.loc20_33.1) [template = f64]
+// CHECK:STDOUT:     %.loc20_33.2: type = value_of_initializer %float.make_type.loc20_33 [template = f64]
+// CHECK:STDOUT:     %.loc20_33.3: type = converted %float.make_type.loc20_33, %.loc20_33.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %.loc24_26.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_26: init type = call constants.%struct.1(%.loc24_26.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_26.2: type = value_of_initializer %float.make_type.loc24_26 [template = f64]
+// CHECK:STDOUT:     %.loc24_26.3: type = converted %float.make_type.loc24_26, %.loc24_26.2 [template = f64]
 // CHECK:STDOUT:     %a.loc24_23.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: f64 = bind_name a, %a.loc24_23.1
+// CHECK:STDOUT:     %.loc24_34.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_34: init type = call constants.%struct.1(%.loc24_34.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_34.2: type = value_of_initializer %float.make_type.loc24_34 [template = f64]
+// CHECK:STDOUT:     %.loc24_34.3: type = converted %float.make_type.loc24_34, %.loc24_34.2 [template = f64]
 // CHECK:STDOUT:     %b.loc24_31.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: f64 = bind_name b, %b.loc24_31.1
+// CHECK:STDOUT:     %.loc24_42.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_42: init type = call constants.%struct.1(%.loc24_42.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_42.2: type = value_of_initializer %float.make_type.loc24_42 [template = f64]
+// CHECK:STDOUT:     %.loc24_42.3: type = converted %float.make_type.loc24_42, %.loc24_42.2 [template = f64]
 // CHECK:STDOUT:     %c.loc24_39.1: f64 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: f64 = bind_name c, %c.loc24_39.1
+// CHECK:STDOUT:     %.loc24_50.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc24_50: init type = call constants.%struct.1(%.loc24_50.1) [template = f64]
+// CHECK:STDOUT:     %.loc24_50.2: type = value_of_initializer %float.make_type.loc24_50 [template = f64]
+// CHECK:STDOUT:     %.loc24_50.3: type = converted %float.make_type.loc24_50, %.loc24_50.2 [template = f64]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref f64 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Float = import_ref ir3, inst+31, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %.loc28_32.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_32: init type = call constants.%struct.1(%.loc28_32.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_32.2: type = value_of_initializer %float.make_type.loc28_32 [template = f64]
+// CHECK:STDOUT:     %.loc28_32.3: type = converted %float.make_type.loc28_32, %.loc28_32.2 [template = f64]
 // CHECK:STDOUT:     %a.loc28_29.1: f64 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: f64 = bind_name a, %a.loc28_29.1
+// CHECK:STDOUT:     %.loc28_40.1: i32 = int_literal 64 [template = constants.%.1]
+// CHECK:STDOUT:     %float.make_type.loc28_40: init type = call constants.%struct.1(%.loc28_40.1) [template = f64]
+// CHECK:STDOUT:     %.loc28_40.2: type = value_of_initializer %float.make_type.loc28_40 [template = f64]
+// CHECK:STDOUT:     %.loc28_40.3: type = converted %float.make_type.loc28_40, %.loc28_40.2 [template = f64]
 // CHECK:STDOUT:     %b.loc28_37.1: f64 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: f64 = bind_name b, %b.loc28_37.1
+// CHECK:STDOUT:     %bool.make_type.loc28: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc28_48.1: type = value_of_initializer %bool.make_type.loc28 [template = bool]
+// CHECK:STDOUT:     %.loc28_48.2: type = converted %bool.make_type.loc28, %.loc28_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Float(%size: i32) -> type = "float.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: f64) -> f64;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: f64, %b: f64, %c: f64) -> f64;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: f64, %b: f64) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: f64, %b: f64) -> f64 = "float.sub";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: f64) -> f64 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -211,7 +363,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: f64 = name_ref c, %c
@@ -223,7 +375,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)

+ 43 - 7
toolchain/check/testdata/builtins/int/and.carbon

@@ -18,16 +18,18 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_and.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %And: type = fn_type @And [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: And = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -38,40 +40,74 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @And.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @And.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @And.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %And.ref: And = name_ref And, %And.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, %And.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 8 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @And(%a: i32, %b: i32) -> i32 = "int.and";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %And.ref: And = name_ref And, file.%And.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, file.%And.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:   %int.and: init i32 = call %And.ref(%a.ref, %b.ref)

+ 50 - 10
toolchain/check/testdata/builtins/int/complement.carbon

@@ -19,11 +19,13 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT: --- int_complement.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Complement: type = fn_type @Complement [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Complement = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Complement: type = fn_type @Complement [template]
+// CHECK:STDOUT:   %struct.2: Complement = struct_value () [template]
 // CHECK:STDOUT:   %And: type = fn_type @And [template]
-// CHECK:STDOUT:   %struct.2: And = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -31,7 +33,7 @@ fn RuntimeCall(a: i32) -> i32 {
 // 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:   %struct.4: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -43,49 +45,87 @@ fn RuntimeCall(a: i32) -> i32 {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Complement.decl: Complement = fn_decl @Complement [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Complement.decl: Complement = fn_decl @Complement [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_18.1: type = value_of_initializer %int.make_type_32.loc2_18 [template = i32]
+// CHECK:STDOUT:     %.loc2_18.2: type = converted %int.make_type_32.loc2_18, %.loc2_18.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_15.1: i32 = param a
 // CHECK:STDOUT:     @Complement.%a: i32 = bind_name a, %a.loc2_15.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_26.1: type = value_of_initializer %int.make_type_32.loc2_26 [template = i32]
+// CHECK:STDOUT:     %.loc2_26.2: type = converted %int.make_type_32.loc2_26, %.loc2_26.1 [template = i32]
 // CHECK:STDOUT:     @Complement.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %And.decl: And = fn_decl @And [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc3_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_11.1: type = value_of_initializer %int.make_type_32.loc3_11 [template = i32]
+// CHECK:STDOUT:     %.loc3_11.2: type = converted %int.make_type_32.loc3_11, %.loc3_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc3_8.1: i32 = param a
 // CHECK:STDOUT:     @And.%a: i32 = bind_name a, %a.loc3_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_19.1: type = value_of_initializer %int.make_type_32.loc3_19 [template = i32]
+// CHECK:STDOUT:     %.loc3_19.2: type = converted %int.make_type_32.loc3_19, %.loc3_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc3_16.1: i32 = param b
 // CHECK:STDOUT:     @And.%b: i32 = bind_name b, %b.loc3_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_27.1: type = value_of_initializer %int.make_type_32.loc3_27 [template = i32]
+// CHECK:STDOUT:     %.loc3_27.2: type = converted %int.make_type_32.loc3_27, %.loc3_27.1 [template = i32]
 // CHECK:STDOUT:     @And.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %And.ref: And = name_ref And, %And.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Complement.ref: Complement = name_ref Complement, %Complement.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_11.2: type = converted %int.make_type_32.loc5, %.loc5_11.1 [template = i32]
 // 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:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc6_18: i32 = int_literal 15584169 [template = constants.%.5]
+// CHECK:STDOUT:   %.loc6_13.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_13.2: type = converted %int.make_type_32.loc6, %.loc6_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc8_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_19.1: type = value_of_initializer %int.make_type_32.loc8_19 [template = i32]
+// CHECK:STDOUT:     %.loc8_19.2: type = converted %int.make_type_32.loc8_19, %.loc8_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc8_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc8_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc8_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_27.1: type = value_of_initializer %int.make_type_32.loc8_27 [template = i32]
+// CHECK:STDOUT:     %.loc8_27.2: type = converted %int.make_type_32.loc8_27, %.loc8_27.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Complement(%a: i32) -> i32 = "int.complement";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @And(%a: i32, %b: i32) -> i32 = "int.and";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Complement.ref: Complement = name_ref Complement, file.%Complement.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Complement.ref: Complement = name_ref Complement, file.%Complement.decl [template = constants.%struct.2]
 // 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

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

@@ -32,21 +32,25 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Eq = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %Eq: type = fn_type @Eq [template]
+// CHECK:STDOUT:   %struct.3: Eq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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:   %struct.5: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,16 +63,28 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Eq.decl: Eq = fn_decl @Eq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_10.1: type = value_of_initializer %int.make_type_32.loc2_10 [template = i32]
+// CHECK:STDOUT:     %.loc2_10.2: type = converted %int.make_type_32.loc2_10, %.loc2_10.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_7.1: i32 = param a
 // CHECK:STDOUT:     @Eq.%a: i32 = bind_name a, %a.loc2_7.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_18.1: type = value_of_initializer %int.make_type_32.loc2_18 [template = i32]
+// CHECK:STDOUT:     %.loc2_18.2: type = converted %int.make_type_32.loc2_18, %.loc2_18.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_15.1: i32 = param b
 // CHECK:STDOUT:     @Eq.%b: i32 = bind_name b, %b.loc2_15.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_26.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_26.2: type = converted %bool.make_type.loc2, %.loc2_26.1 [template = bool]
 // CHECK:STDOUT:     @Eq.%return: ref bool = 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.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.4] {
 // 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
@@ -76,11 +92,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc12_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_19.1: type = value_of_initializer %int.make_type_32.loc12_19 [template = i32]
+// CHECK:STDOUT:     %.loc12_19.2: type = converted %int.make_type_32.loc12_19, %.loc12_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc12_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc12_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc12_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_27.1: type = value_of_initializer %int.make_type_32.loc12_27 [template = i32]
+// CHECK:STDOUT:     %.loc12_27.2: type = converted %int.make_type_32.loc12_27, %.loc12_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc12_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc12_24.1
+// CHECK:STDOUT:     %bool.make_type.loc12: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc12_35.1: type = value_of_initializer %bool.make_type.loc12 [template = bool]
+// CHECK:STDOUT:     %.loc12_35.2: type = converted %bool.make_type.loc12, %.loc12_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -95,12 +123,16 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Eq(%a: i32, %b: i32) -> bool = "int.eq";
 // CHECK:STDOUT:
 // 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: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Eq.ref.loc8: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.3]
 // 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]
@@ -119,7 +151,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: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Eq.ref.loc9: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.3]
 // 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]
@@ -142,7 +174,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: Eq = name_ref Eq, file.%Eq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Eq.ref: Eq = name_ref Eq, file.%Eq.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:   %int.eq: init bool = call %Eq.ref(%a.ref, %b.ref)
@@ -154,9 +186,11 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: WrongResult = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %WrongResult: type = fn_type @WrongResult [template]
+// CHECK:STDOUT:   %struct.2: WrongResult = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -165,14 +199,28 @@ fn WrongResult(a: i32, b: i32) -> i32 = "int.eq";
 // CHECK:STDOUT:     .WrongResult = %WrongResult.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %WrongResult.decl: WrongResult = fn_decl @WrongResult [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @WrongResult.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @WrongResult.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @WrongResult.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @WrongResult(%a: i32, %b: i32) -> i32;
 // CHECK:STDOUT:

+ 57 - 17
toolchain/check/testdata/builtins/int/greater.carbon

@@ -27,16 +27,20 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Greater = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %Greater: type = fn_type @Greater [template]
+// CHECK:STDOUT:   %struct.3: Greater = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: 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]
@@ -45,7 +49,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // 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:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +63,41 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Greater.decl: Greater = fn_decl @Greater [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_15.1: type = value_of_initializer %int.make_type_32.loc2_15 [template = i32]
+// CHECK:STDOUT:     %.loc2_15.2: type = converted %int.make_type_32.loc2_15, %.loc2_15.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_12.1: i32 = param a
 // CHECK:STDOUT:     @Greater.%a: i32 = bind_name a, %a.loc2_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_23.1: type = value_of_initializer %int.make_type_32.loc2_23 [template = i32]
+// CHECK:STDOUT:     %.loc2_23.2: type = converted %int.make_type_32.loc2_23, %.loc2_23.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_20.1: i32 = param b
 // CHECK:STDOUT:     @Greater.%b: i32 = bind_name b, %b.loc2_20.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_31.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_31.2: type = converted %bool.make_type.loc2, %.loc2_31.1 [template = bool]
 // CHECK:STDOUT:     @Greater.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc3_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_14.1: type = value_of_initializer %int.make_type_32.loc3_14 [template = i32]
+// CHECK:STDOUT:     %.loc3_14.2: type = converted %int.make_type_32.loc3_14, %.loc3_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_22.1: type = value_of_initializer %int.make_type_32.loc3_22 [template = i32]
+// CHECK:STDOUT:     %.loc3_22.2: type = converted %int.make_type_32.loc3_22, %.loc3_22.1 [template = i32]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +105,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc16_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_19.1: type = value_of_initializer %int.make_type_32.loc16_19 [template = i32]
+// CHECK:STDOUT:     %.loc16_19.2: type = converted %int.make_type_32.loc16_19, %.loc16_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc16_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_27.1: type = value_of_initializer %int.make_type_32.loc16_27 [template = i32]
+// CHECK:STDOUT:     %.loc16_27.2: type = converted %int.make_type_32.loc16_27, %.loc16_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +136,10 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Greater(%a: i32, %b: i32) -> bool = "int.greater";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
@@ -107,7 +147,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref.loc9: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
 // 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]
@@ -126,7 +166,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref.loc10: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
 // 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]
@@ -145,7 +185,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref.loc11: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
 // 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]
@@ -164,8 +204,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: 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:   %Greater.ref.loc12: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -187,9 +227,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref.loc13: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -214,7 +254,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: Greater = name_ref Greater, file.%Greater.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Greater.ref: Greater = name_ref Greater, file.%Greater.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:   %int.greater: init bool = call %Greater.ref(%a.ref, %b.ref)

+ 57 - 17
toolchain/check/testdata/builtins/int/greater_eq.carbon

@@ -27,16 +27,20 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: GreaterEq = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %GreaterEq: type = fn_type @GreaterEq [template]
+// CHECK:STDOUT:   %struct.3: GreaterEq = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: 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]
@@ -45,7 +49,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // 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:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +63,41 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %GreaterEq.decl: GreaterEq = fn_decl @GreaterEq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_17.1: type = value_of_initializer %int.make_type_32.loc2_17 [template = i32]
+// CHECK:STDOUT:     %.loc2_17.2: type = converted %int.make_type_32.loc2_17, %.loc2_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_14.1: i32 = param a
 // CHECK:STDOUT:     @GreaterEq.%a: i32 = bind_name a, %a.loc2_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_25.1: type = value_of_initializer %int.make_type_32.loc2_25 [template = i32]
+// CHECK:STDOUT:     %.loc2_25.2: type = converted %int.make_type_32.loc2_25, %.loc2_25.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_22.1: i32 = param b
 // CHECK:STDOUT:     @GreaterEq.%b: i32 = bind_name b, %b.loc2_22.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_33.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_33.2: type = converted %bool.make_type.loc2, %.loc2_33.1 [template = bool]
 // CHECK:STDOUT:     @GreaterEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc3_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_14.1: type = value_of_initializer %int.make_type_32.loc3_14 [template = i32]
+// CHECK:STDOUT:     %.loc3_14.2: type = converted %int.make_type_32.loc3_14, %.loc3_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_22.1: type = value_of_initializer %int.make_type_32.loc3_22 [template = i32]
+// CHECK:STDOUT:     %.loc3_22.2: type = converted %int.make_type_32.loc3_22, %.loc3_22.1 [template = i32]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +105,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc16_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_19.1: type = value_of_initializer %int.make_type_32.loc16_19 [template = i32]
+// CHECK:STDOUT:     %.loc16_19.2: type = converted %int.make_type_32.loc16_19, %.loc16_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc16_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_27.1: type = value_of_initializer %int.make_type_32.loc16_27 [template = i32]
+// CHECK:STDOUT:     %.loc16_27.2: type = converted %int.make_type_32.loc16_27, %.loc16_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +136,10 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @GreaterEq(%a: i32, %b: i32) -> bool = "int.greater_eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
@@ -107,7 +147,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref.loc9: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
 // 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]
@@ -126,7 +166,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref.loc10: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
 // 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]
@@ -145,7 +185,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref.loc11: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
 // 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]
@@ -164,8 +204,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: 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:   %GreaterEq.ref.loc12: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -187,9 +227,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref.loc13: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc13_26: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -214,7 +254,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: GreaterEq = name_ref GreaterEq, file.%GreaterEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %GreaterEq.ref: GreaterEq = name_ref GreaterEq, file.%GreaterEq.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:   %int.greater_eq: init bool = call %GreaterEq.ref(%a.ref, %b.ref)

+ 113 - 21
toolchain/check/testdata/builtins/int/left_shift.carbon

@@ -62,16 +62,18 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT: --- int_left_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: LeftShift = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -82,40 +84,74 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_17.1: type = value_of_initializer %int.make_type_32.loc2_17 [template = i32]
+// CHECK:STDOUT:     %.loc2_17.2: type = converted %int.make_type_32.loc2_17, %.loc2_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_14.1: i32 = param a
 // CHECK:STDOUT:     @LeftShift.%a: i32 = bind_name a, %a.loc2_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_25.1: type = value_of_initializer %int.make_type_32.loc2_25 [template = i32]
+// CHECK:STDOUT:     %.loc2_25.2: type = converted %int.make_type_32.loc2_25, %.loc2_25.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_22.1: i32 = param b
 // CHECK:STDOUT:     @LeftShift.%b: i32 = bind_name b, %b.loc2_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_33.1: type = value_of_initializer %int.make_type_32.loc2_33 [template = i32]
+// CHECK:STDOUT:     %.loc2_33.2: type = converted %int.make_type_32.loc2_33, %.loc2_33.1 [template = i32]
 // CHECK:STDOUT:     @LeftShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 20 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @LeftShift(%a: i32, %b: i32) -> i32 = "int.left_shift";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, file.%LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LeftShift.ref: LeftShift = name_ref LeftShift, file.%LeftShift.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:   %int.left_shift: init i32 = call %LeftShift.ref(%a.ref, %b.ref)
@@ -127,11 +163,13 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT: --- fail_bad_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: LeftShift = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %LeftShift: type = fn_type @LeftShift [template]
+// CHECK:STDOUT:   %struct.2: LeftShift = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -149,70 +187,122 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %LeftShift.decl: LeftShift = fn_decl @LeftShift [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_17.1: type = value_of_initializer %int.make_type_32.loc4_17 [template = i32]
+// CHECK:STDOUT:     %.loc4_17.2: type = converted %int.make_type_32.loc4_17, %.loc4_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_14.1: i32 = param a
 // CHECK:STDOUT:     @LeftShift.%a: i32 = bind_name a, %a.loc4_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_25.1: type = value_of_initializer %int.make_type_32.loc4_25 [template = i32]
+// CHECK:STDOUT:     %.loc4_25.2: type = converted %int.make_type_32.loc4_25, %.loc4_25.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_22.1: i32 = param b
 // CHECK:STDOUT:     @LeftShift.%b: i32 = bind_name b, %b.loc4_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_33.1: type = value_of_initializer %int.make_type_32.loc4_33 [template = i32]
+// CHECK:STDOUT:     %.loc4_33.2: type = converted %int.make_type_32.loc4_33, %.loc4_33.1 [template = i32]
 // CHECK:STDOUT:     @LeftShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_14.1: type = value_of_initializer %int.make_type_32.loc5_14 [template = i32]
+// CHECK:STDOUT:     %.loc5_14.2: type = converted %int.make_type_32.loc5_14, %.loc5_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc5_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_22.1: type = value_of_initializer %int.make_type_32.loc5_22 [template = i32]
+// CHECK:STDOUT:     %.loc5_22.2: type = converted %int.make_type_32.loc5_22, %.loc5_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %LeftShift.ref.loc8: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_13.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_13.2: type = converted %int.make_type_32.loc8, %.loc8_13.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc8: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc13_13.1: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
+// CHECK:STDOUT:   %.loc13_13.2: type = converted %int.make_type_32.loc13, %.loc13_13.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc13: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc18_13.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
+// CHECK:STDOUT:   %.loc18_13.2: type = converted %int.make_type_32.loc18, %.loc18_13.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc18: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc21_17.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
+// CHECK:STDOUT:   %.loc21_17.2: type = converted %int.make_type_32.loc21, %.loc21_17.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc21: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc26_17.1: type = value_of_initializer %int.make_type_32.loc26 [template = i32]
+// CHECK:STDOUT:   %.loc26_17.2: type = converted %int.make_type_32.loc26, %.loc26_17.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc26: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc29: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc29_20.1: type = value_of_initializer %int.make_type_32.loc29 [template = i32]
+// CHECK:STDOUT:   %.loc29_20.2: type = converted %int.make_type_32.loc29, %.loc29_20.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc29: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc34_20.1: type = value_of_initializer %int.make_type_32.loc34 [template = i32]
+// CHECK:STDOUT:   %.loc34_20.2: type = converted %int.make_type_32.loc34, %.loc34_20.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc34: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc40: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc40_15.1: type = value_of_initializer %int.make_type_32.loc40 [template = i32]
+// CHECK:STDOUT:   %.loc40_15.2: type = converted %int.make_type_32.loc40, %.loc40_15.1 [template = i32]
+// CHECK:STDOUT:   %LeftShift.ref.loc40: LeftShift = name_ref LeftShift, %LeftShift.decl [template = constants.%struct.2]
 // 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:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
 // 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]
@@ -223,6 +313,8 @@ let negative: i32 = LeftShift(1, Negate(1));
 // CHECK:STDOUT:   %negative: i32 = bind_name negative, %.loc40_44.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @LeftShift(%a: i32, %b: i32) -> i32 = "int.left_shift";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";

+ 57 - 17
toolchain/check/testdata/builtins/int/less.carbon

@@ -27,16 +27,20 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Less = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %Less: type = fn_type @Less [template]
+// CHECK:STDOUT:   %struct.3: Less = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: 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]
@@ -45,7 +49,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // 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:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +63,41 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Less.decl: Less = fn_decl @Less [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_12.1: type = value_of_initializer %int.make_type_32.loc2_12 [template = i32]
+// CHECK:STDOUT:     %.loc2_12.2: type = converted %int.make_type_32.loc2_12, %.loc2_12.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_9.1: i32 = param a
 // CHECK:STDOUT:     @Less.%a: i32 = bind_name a, %a.loc2_9.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_20: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_20.1: type = value_of_initializer %int.make_type_32.loc2_20 [template = i32]
+// CHECK:STDOUT:     %.loc2_20.2: type = converted %int.make_type_32.loc2_20, %.loc2_20.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_17.1: i32 = param b
 // CHECK:STDOUT:     @Less.%b: i32 = bind_name b, %b.loc2_17.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_28.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_28.2: type = converted %bool.make_type.loc2, %.loc2_28.1 [template = bool]
 // CHECK:STDOUT:     @Less.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc3_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_14.1: type = value_of_initializer %int.make_type_32.loc3_14 [template = i32]
+// CHECK:STDOUT:     %.loc3_14.2: type = converted %int.make_type_32.loc3_14, %.loc3_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_22.1: type = value_of_initializer %int.make_type_32.loc3_22 [template = i32]
+// CHECK:STDOUT:     %.loc3_22.2: type = converted %int.make_type_32.loc3_22, %.loc3_22.1 [template = i32]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +105,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc16_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_19.1: type = value_of_initializer %int.make_type_32.loc16_19 [template = i32]
+// CHECK:STDOUT:     %.loc16_19.2: type = converted %int.make_type_32.loc16_19, %.loc16_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc16_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_27.1: type = value_of_initializer %int.make_type_32.loc16_27 [template = i32]
+// CHECK:STDOUT:     %.loc16_27.2: type = converted %int.make_type_32.loc16_27, %.loc16_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +136,10 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Less(%a: i32, %b: i32) -> bool = "int.less";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
@@ -107,7 +147,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref.loc9: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
 // 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]
@@ -126,7 +166,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref.loc10: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
 // 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]
@@ -145,7 +185,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref.loc11: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
 // 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]
@@ -164,8 +204,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: 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:   %Less.ref.loc12: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -187,9 +227,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref.loc13: Less = name_ref Less, file.%Less.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc13_22: i32 = int_literal 0 [template = constants.%.8]
-// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -214,7 +254,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: Less = name_ref Less, file.%Less.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Less.ref: Less = name_ref Less, file.%Less.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:   %int.less: init bool = call %Less.ref(%a.ref, %b.ref)

+ 57 - 17
toolchain/check/testdata/builtins/int/less_eq.carbon

@@ -27,16 +27,20 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: LessEq = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %LessEq: type = fn_type @LessEq [template]
+// CHECK:STDOUT:   %struct.3: LessEq = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: Negate = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: 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]
@@ -45,7 +49,7 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // 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:   %struct.6: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -59,21 +63,41 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %LessEq.decl: LessEq = fn_decl @LessEq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_14.1: type = value_of_initializer %int.make_type_32.loc2_14 [template = i32]
+// CHECK:STDOUT:     %.loc2_14.2: type = converted %int.make_type_32.loc2_14, %.loc2_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @LessEq.%a: i32 = bind_name a, %a.loc2_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_22.1: type = value_of_initializer %int.make_type_32.loc2_22 [template = i32]
+// CHECK:STDOUT:     %.loc2_22.2: type = converted %int.make_type_32.loc2_22, %.loc2_22.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_19.1: i32 = param b
 // CHECK:STDOUT:     @LessEq.%b: i32 = bind_name b, %b.loc2_19.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_30.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_30.2: type = converted %bool.make_type.loc2, %.loc2_30.1 [template = bool]
 // CHECK:STDOUT:     @LessEq.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc3_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_14.1: type = value_of_initializer %int.make_type_32.loc3_14 [template = i32]
+// CHECK:STDOUT:     %.loc3_14.2: type = converted %int.make_type_32.loc3_14, %.loc3_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc3_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc3_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc3_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc3_22.1: type = value_of_initializer %int.make_type_32.loc3_22 [template = i32]
+// CHECK:STDOUT:     %.loc3_22.2: type = converted %int.make_type_32.loc3_22, %.loc3_22.1 [template = i32]
 // 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.decl: F = fn_decl @F [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.5] {
 // 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,11 +105,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc16_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_19.1: type = value_of_initializer %int.make_type_32.loc16_19 [template = i32]
+// CHECK:STDOUT:     %.loc16_19.2: type = converted %int.make_type_32.loc16_19, %.loc16_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc16_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc16_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc16_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc16_27.1: type = value_of_initializer %int.make_type_32.loc16_27 [template = i32]
+// CHECK:STDOUT:     %.loc16_27.2: type = converted %int.make_type_32.loc16_27, %.loc16_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc16_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc16_24.1
+// CHECK:STDOUT:     %bool.make_type.loc16: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc16_35.1: type = value_of_initializer %bool.make_type.loc16 [template = bool]
+// CHECK:STDOUT:     %.loc16_35.2: type = converted %bool.make_type.loc16, %.loc16_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -100,6 +136,10 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @LessEq(%a: i32, %b: i32) -> bool = "int.less_eq";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
@@ -107,7 +147,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref.loc9: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
 // 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]
@@ -126,7 +166,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref.loc10: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
 // 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]
@@ -145,7 +185,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref.loc11: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
 // 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]
@@ -164,8 +204,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: 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:   %LessEq.ref.loc12: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -187,9 +227,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref.loc13: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc13_24: i32 = int_literal 0 [template = constants.%.7]
-// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc13: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.4]
 // 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]
@@ -214,7 +254,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: LessEq = name_ref LessEq, file.%LessEq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %LessEq.ref: LessEq = name_ref LessEq, file.%LessEq.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:   %int.less_eq: init bool = call %LessEq.ref(%a.ref, %b.ref)

+ 51 - 23
toolchain/check/testdata/builtins/int/make_type_signed.carbon

@@ -68,9 +68,11 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Int = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Int: type = fn_type @Int [template]
+// CHECK:STDOUT:   %struct.2: Int = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -79,13 +81,19 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     .Int = %Int.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Int.decl: Int = fn_decl @Int [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Int.decl: Int = fn_decl @Int [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32, %.loc4_11.1 [template = i32]
 // 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>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int(%n: i32) -> type = "int.make_type_signed";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use_types.carbon
@@ -102,31 +110,33 @@ var m: Int(1000000000);
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.4: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [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:   %struct.5: Symbolic = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Int = %import_ref
+// CHECK:STDOUT:     .Int = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:     .Symbolic = %Symbolic.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.1: Int = import_ref ir1, inst+14, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // 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:     %Int.ref.loc6_9: Int = name_ref Int, %import_ref.1 [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: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %Int.ref.loc6_21: Int = name_ref Int, %import_ref.1 [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]
@@ -134,31 +144,35 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     @F.%return: ref i64 = var <return slot>
 // CHECK:STDOUT:   }
 // 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:     %Int.ref.loc10_9: Int = name_ref Int, %import_ref.1 [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: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %Int.ref.loc10_21: Int = name_ref Int, %import_ref.1 [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.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %Symbolic.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.4() [template = i32]
+// CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // 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: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %Int.ref.loc14_25: Int = name_ref Int, %import_ref.1 [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.%.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: Int = name_ref Int, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %Int.ref.loc14_36: Int = name_ref Int, %import_ref.1 [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.%.6]
 // CHECK:STDOUT:     %.loc14_41.1: type = value_of_initializer %int.make_type_signed.loc14_39 [symbolic = constants.%.6]
@@ -181,6 +195,8 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Symbolic(%N: i32, %x: Core.Int(N)) -> Core.Int(N) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: Core.Int(N) = name_ref x, %x
@@ -202,7 +218,7 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+14, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %.loc10_12: i32 = int_literal 0 [template = constants.%.2]
@@ -218,31 +234,41 @@ var m: Int(1000000000);
 // CHECK:STDOUT: --- fail_negative_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %Int: type = fn_type @Int [template]
-// CHECK:STDOUT:   %struct.2: Int = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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:     .Int = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .n = %n.loc12
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.1: Int = import_ref ir1, inst+14, loaded [template = constants.%struct.3]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %n.loc6_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %Int.ref: Int = name_ref Int, %import_ref.1 [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -254,6 +280,8 @@ var m: Int(1000000000);
 // CHECK:STDOUT:   %n.loc12: ref <error> = bind_name n, %n.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%n: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Int(%n: i32) -> type = "int.make_type_signed";
@@ -273,7 +301,7 @@ var m: Int(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+5, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref: Int = import_ref ir1, inst+14, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Int.ref: Int = name_ref Int, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %.loc9_12: i32 = int_literal 1000000000 [template = constants.%.2]

+ 51 - 23
toolchain/check/testdata/builtins/int/make_type_unsigned.carbon

@@ -68,9 +68,11 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: UInt = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
+// CHECK:STDOUT:   %struct.2: UInt = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -79,13 +81,19 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     .UInt = %UInt.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %UInt.decl: UInt = fn_decl @UInt [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %UInt.decl: UInt = fn_decl @UInt [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc4_12.2: type = converted %int.make_type_32, %.loc4_12.1 [template = i32]
 // 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>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @UInt(%n: i32) -> type = "int.make_type_unsigned";
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- use_types.carbon
@@ -102,31 +110,33 @@ var m: UInt(1000000000);
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.4: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %N: i32 = bind_symbolic_name N 0 [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:   %struct.5: Symbolic = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .UInt = %import_ref
+// CHECK:STDOUT:     .UInt = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:     .G = %G.decl
 // CHECK:STDOUT:     .Symbolic = %Symbolic.decl
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.1: UInt = import_ref ir1, inst+14, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // 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:     %UInt.ref.loc6_9: UInt = name_ref UInt, %import_ref.1 [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: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %UInt.ref.loc6_22: UInt = name_ref UInt, %import_ref.1 [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]
@@ -134,31 +144,35 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     @F.%return: ref u64 = var <return slot>
 // CHECK:STDOUT:   }
 // 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:     %UInt.ref.loc10_9: UInt = name_ref UInt, %import_ref.1 [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: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %UInt.ref.loc10_22: UInt = name_ref UInt, %import_ref.1 [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.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %Symbolic.decl: Symbolic = fn_decl @Symbolic [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.4() [template = i32]
+// CHECK:STDOUT:     %.loc14_17.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc14_17.2: type = converted %int.make_type_32, %.loc14_17.1 [template = i32]
 // 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: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %UInt.ref.loc14_25: UInt = name_ref UInt, %import_ref.1 [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.%.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: UInt = name_ref UInt, %import_ref [template = constants.%struct.1]
+// CHECK:STDOUT:     %UInt.ref.loc14_37: UInt = name_ref UInt, %import_ref.1 [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.%.6]
 // CHECK:STDOUT:     %.loc14_43.1: type = value_of_initializer %int.make_type_unsigned.loc14_41 [symbolic = constants.%.6]
@@ -181,6 +195,8 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:   return %n.ref
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Symbolic(%N: i32, %x: Core.UInt(N)) -> Core.UInt(N) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %x.ref: Core.UInt(N) = name_ref x, %x
@@ -202,7 +218,7 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .n = %n
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+14, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %UInt.ref: UInt = name_ref UInt, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %.loc10_13: i32 = int_literal 0 [template = constants.%.2]
@@ -218,31 +234,41 @@ var m: UInt(1000000000);
 // CHECK:STDOUT: --- fail_negative_size.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %UInt: type = fn_type @UInt [template]
-// CHECK:STDOUT:   %struct.2: UInt = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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:     .UInt = %import_ref.1
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .n = %n.loc12
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.1: UInt = import_ref ir1, inst+14, loaded [template = constants.%struct.3]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir4, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %n.loc6_11.1: i32 = param n
 // CHECK:STDOUT:     @Negate.%n: i32 = bind_name n, %n.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %UInt.ref: UInt = name_ref UInt, %import_ref.1 [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -254,6 +280,8 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:   %n.loc12: ref <error> = bind_name n, %n.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%n: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @UInt(%n: i32) -> type = "int.make_type_unsigned";
@@ -273,7 +301,7 @@ var m: UInt(1000000000);
 // CHECK:STDOUT:     .Core = %Core
 // CHECK:STDOUT:     .m = %m
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+5, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref: UInt = import_ref ir1, inst+14, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %UInt.ref: UInt = name_ref UInt, %import_ref [template = constants.%struct]
 // CHECK:STDOUT:   %.loc9_13: i32 = int_literal 1000000000 [template = constants.%.2]

+ 42 - 10
toolchain/check/testdata/builtins/int/neq.carbon

@@ -23,21 +23,25 @@ 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:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Neq = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.2: Bool = struct_value () [template]
+// CHECK:STDOUT:   %Neq: type = fn_type @Neq [template]
+// CHECK:STDOUT:   %struct.3: Neq = struct_value () [template]
 // CHECK:STDOUT:   %True: type = class_type @True [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %False: type = class_type @False [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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:   %struct.5: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -50,16 +54,28 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %Neq.decl: Neq = fn_decl @Neq [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Neq.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Neq.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %bool.make_type.loc2: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %bool.make_type.loc2 [template = bool]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %bool.make_type.loc2, %.loc2_27.1 [template = bool]
 // CHECK:STDOUT:     @Neq.%return: ref bool = 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.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.4] {
 // 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
@@ -67,11 +83,23 @@ 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.2]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc12_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_19.1: type = value_of_initializer %int.make_type_32.loc12_19 [template = i32]
+// CHECK:STDOUT:     %.loc12_19.2: type = converted %int.make_type_32.loc12_19, %.loc12_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc12_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc12_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc12_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_27.1: type = value_of_initializer %int.make_type_32.loc12_27 [template = i32]
+// CHECK:STDOUT:     %.loc12_27.2: type = converted %int.make_type_32.loc12_27, %.loc12_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc12_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc12_24.1
+// CHECK:STDOUT:     %bool.make_type.loc12: init type = call constants.%struct.2() [template = bool]
+// CHECK:STDOUT:     %.loc12_35.1: type = value_of_initializer %bool.make_type.loc12 [template = bool]
+// CHECK:STDOUT:     %.loc12_35.2: type = converted %bool.make_type.loc12, %.loc12_35.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -86,12 +114,16 @@ fn RuntimeCall(a: i32, b: i32) -> bool {
 // CHECK:STDOUT:   .Self = constants.%False
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Neq(%a: i32, %b: i32) -> bool = "int.neq";
 // CHECK:STDOUT:
 // 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: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Neq.ref.loc8: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.3]
 // 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]
@@ -110,7 +142,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: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Neq.ref.loc9: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.3]
 // 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]
@@ -133,7 +165,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: Neq = name_ref Neq, file.%Neq.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Neq.ref: Neq = name_ref Neq, file.%Neq.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:   %int.neq: init bool = call %Neq.ref(%a.ref, %b.ref)

+ 43 - 7
toolchain/check/testdata/builtins/int/or.carbon

@@ -18,16 +18,18 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_or.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Or: type = fn_type @Or [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Or = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Or: type = fn_type @Or [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -38,40 +40,74 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Or.decl: Or = fn_decl @Or [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Or.decl: Or = fn_decl @Or [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_10.1: type = value_of_initializer %int.make_type_32.loc2_10 [template = i32]
+// CHECK:STDOUT:     %.loc2_10.2: type = converted %int.make_type_32.loc2_10, %.loc2_10.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_7.1: i32 = param a
 // CHECK:STDOUT:     @Or.%a: i32 = bind_name a, %a.loc2_7.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_18.1: type = value_of_initializer %int.make_type_32.loc2_18 [template = i32]
+// CHECK:STDOUT:     %.loc2_18.2: type = converted %int.make_type_32.loc2_18, %.loc2_18.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_15.1: i32 = param b
 // CHECK:STDOUT:     @Or.%b: i32 = bind_name b, %b.loc2_15.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_26.1: type = value_of_initializer %int.make_type_32.loc2_26 [template = i32]
+// CHECK:STDOUT:     %.loc2_26.2: type = converted %int.make_type_32.loc2_26, %.loc2_26.1 [template = i32]
 // CHECK:STDOUT:     @Or.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, %Or.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, %Or.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 14 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Or(%a: i32, %b: i32) -> i32 = "int.or";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, file.%Or.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Or.ref: Or = name_ref Or, file.%Or.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:   %int.or: init i32 = call %Or.ref(%a.ref, %b.ref)

+ 144 - 28
toolchain/check/testdata/builtins/int/right_shift.carbon

@@ -63,16 +63,18 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- int_right_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -83,40 +85,74 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_18.1: type = value_of_initializer %int.make_type_32.loc2_18 [template = i32]
+// CHECK:STDOUT:     %.loc2_18.2: type = converted %int.make_type_32.loc2_18, %.loc2_18.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc2_15.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_26.1: type = value_of_initializer %int.make_type_32.loc2_26 [template = i32]
+// CHECK:STDOUT:     %.loc2_26.2: type = converted %int.make_type_32.loc2_26, %.loc2_26.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc2_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_34.1: type = value_of_initializer %int.make_type_32.loc2_34 [template = i32]
+// CHECK:STDOUT:     %.loc2_34.2: type = converted %int.make_type_32.loc2_34, %.loc2_34.1 [template = i32]
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 5 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @RightShift(%a: i32, %b: i32) -> i32 = "int.right_shift";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, file.%RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %RightShift.ref: RightShift = name_ref RightShift, file.%RightShift.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:   %int.right_shift: init i32 = call %RightShift.ref(%a.ref, %b.ref)
@@ -128,11 +164,13 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- arith_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %struct.2: RightShift = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -155,21 +193,43 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:     .arr2 = %arr2
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_18.1: type = value_of_initializer %int.make_type_32.loc6_18 [template = i32]
+// CHECK:STDOUT:     %.loc6_18.2: type = converted %int.make_type_32.loc6_18, %.loc6_18.1 [template = i32]
 // CHECK:STDOUT:     %a.loc6_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc6_15.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_26.1: type = value_of_initializer %int.make_type_32.loc6_26 [template = i32]
+// CHECK:STDOUT:     %.loc6_26.2: type = converted %int.make_type_32.loc6_26, %.loc6_26.1 [template = i32]
 // CHECK:STDOUT:     %b.loc6_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc6_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_34.1: type = value_of_initializer %int.make_type_32.loc6_34 [template = i32]
+// CHECK:STDOUT:     %.loc6_34.2: type = converted %int.make_type_32.loc6_34, %.loc6_34.1 [template = i32]
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_14.1: type = value_of_initializer %int.make_type_32.loc7_14 [template = i32]
+// CHECK:STDOUT:     %.loc7_14.2: type = converted %int.make_type_32.loc7_14, %.loc7_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc7_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_22.1: type = value_of_initializer %int.make_type_32.loc7_22 [template = i32]
+// CHECK:STDOUT:     %.loc7_22.2: type = converted %int.make_type_32.loc7_22, %.loc7_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc10_17: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %RightShift.ref.loc10: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc10_35: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
 // 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]
@@ -179,18 +239,26 @@ let negative: i32 = RightShift(1, Negate(1));
 // 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_12.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_12.2: type = converted %int.make_type_32.loc10, %.loc10_12.1 [template = i32]
 // 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:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc11_19: i32 = int_literal 1 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc11_14.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_14.2: type = converted %int.make_type_32.loc11, %.loc11_14.1 [template = i32]
 // 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: 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:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc14_17: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %RightShift.ref.loc14: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc14_35: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
 // 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]
@@ -200,10 +268,16 @@ let negative: i32 = RightShift(1, Negate(1));
 // 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_12.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
+// CHECK:STDOUT:   %.loc14_12.2: type = converted %int.make_type_32.loc14, %.loc14_12.1 [template = i32]
 // 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:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc15_19: i32 = int_literal 3 [template = constants.%.10]
+// CHECK:STDOUT:   %.loc15_14.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
+// CHECK:STDOUT:   %.loc15_14.2: type = converted %int.make_type_32.loc15, %.loc15_14.1 [template = i32]
 // 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
@@ -211,6 +285,8 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %arr2_p: [i32; 3]* = bind_name arr2_p, %.loc15_25
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @RightShift(%a: i32, %b: i32) -> i32 = "int.right_shift";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
@@ -218,11 +294,13 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT: --- fail_bad_shift.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: RightShift = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %RightShift: type = fn_type @RightShift [template]
+// CHECK:STDOUT:   %struct.2: RightShift = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -238,42 +316,78 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RightShift.decl: RightShift = fn_decl @RightShift [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_18.1: type = value_of_initializer %int.make_type_32.loc4_18 [template = i32]
+// CHECK:STDOUT:     %.loc4_18.2: type = converted %int.make_type_32.loc4_18, %.loc4_18.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_15.1: i32 = param a
 // CHECK:STDOUT:     @RightShift.%a: i32 = bind_name a, %a.loc4_15.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_26.1: type = value_of_initializer %int.make_type_32.loc4_26 [template = i32]
+// CHECK:STDOUT:     %.loc4_26.2: type = converted %int.make_type_32.loc4_26, %.loc4_26.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_23.1: i32 = param b
 // CHECK:STDOUT:     @RightShift.%b: i32 = bind_name b, %b.loc4_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_34.1: type = value_of_initializer %int.make_type_32.loc4_34 [template = i32]
+// CHECK:STDOUT:     %.loc4_34.2: type = converted %int.make_type_32.loc4_34, %.loc4_34.1 [template = i32]
 // CHECK:STDOUT:     @RightShift.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_14.1: type = value_of_initializer %int.make_type_32.loc5_14 [template = i32]
+// CHECK:STDOUT:     %.loc5_14.2: type = converted %int.make_type_32.loc5_14, %.loc5_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc5_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_22.1: type = value_of_initializer %int.make_type_32.loc5_22 [template = i32]
+// CHECK:STDOUT:     %.loc5_22.2: type = converted %int.make_type_32.loc5_22, %.loc5_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RightShift.ref.loc8: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_13.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_13.2: type = converted %int.make_type_32.loc8, %.loc8_13.1 [template = i32]
+// CHECK:STDOUT:   %RightShift.ref.loc8: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
 // 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: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc13_13.1: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
+// CHECK:STDOUT:   %.loc13_13.2: type = converted %int.make_type_32.loc13, %.loc13_13.1 [template = i32]
+// CHECK:STDOUT:   %RightShift.ref.loc13: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
 // 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: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc18_13.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
+// CHECK:STDOUT:   %.loc18_13.2: type = converted %int.make_type_32.loc18, %.loc18_13.1 [template = i32]
+// CHECK:STDOUT:   %RightShift.ref.loc18: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
 // 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: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc24: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc24_15.1: type = value_of_initializer %int.make_type_32.loc24 [template = i32]
+// CHECK:STDOUT:   %.loc24_15.2: type = converted %int.make_type_32.loc24, %.loc24_15.1 [template = i32]
+// CHECK:STDOUT:   %RightShift.ref.loc24: RightShift = name_ref RightShift, %RightShift.decl [template = constants.%struct.2]
 // 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:   %Negate.ref: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.3]
 // 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]
@@ -284,6 +398,8 @@ let negative: i32 = RightShift(1, Negate(1));
 // CHECK:STDOUT:   %negative: i32 = bind_name negative, %.loc24_45.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @RightShift(%a: i32, %b: i32) -> i32 = "int.right_shift";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";

+ 196 - 34
toolchain/check/testdata/builtins/int/sadd.carbon

@@ -88,16 +88,18 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- int_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Add = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -108,40 +110,74 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: i32, %b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.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:   %int.sadd: init i32 = call %Add.ref(%a.ref, %b.ref)
@@ -153,24 +189,28 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: 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:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -189,94 +229,192 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc8_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_14.1: type = value_of_initializer %int.make_type_32.loc8_14 [template = i32]
+// CHECK:STDOUT:     %.loc8_14.2: type = converted %int.make_type_32.loc8_14, %.loc8_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc8_11.1: i32 = param a
 // CHECK:STDOUT:     @TooFew.%a: i32 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc8_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_22.1: type = value_of_initializer %int.make_type_32.loc8_22 [template = i32]
+// CHECK:STDOUT:     %.loc8_22.2: type = converted %int.make_type_32.loc8_22, %.loc8_22.1 [template = i32]
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc13_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_15.1: type = value_of_initializer %int.make_type_32.loc13_15 [template = i32]
+// CHECK:STDOUT:     %.loc13_15.2: type = converted %int.make_type_32.loc13_15, %.loc13_15.1 [template = i32]
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_23.1: type = value_of_initializer %int.make_type_32.loc13_23 [template = i32]
+// CHECK:STDOUT:     %.loc13_23.2: type = converted %int.make_type_32.loc13_23, %.loc13_23.1 [template = i32]
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_31: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_31.1: type = value_of_initializer %int.make_type_32.loc13_31 [template = i32]
+// CHECK:STDOUT:     %.loc13_31.2: type = converted %int.make_type_32.loc13_31, %.loc13_31.1 [template = i32]
 // CHECK:STDOUT:     %c.loc13_28.1: i32 = param c
 // CHECK:STDOUT:     @TooMany.%c: i32 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_39: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_39.1: type = value_of_initializer %int.make_type_32.loc13_39 [template = i32]
+// CHECK:STDOUT:     %.loc13_39.2: type = converted %int.make_type_32.loc13_39, %.loc13_39.1 [template = i32]
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc18_21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_21.1: type = value_of_initializer %int.make_type_32.loc18_21 [template = i32]
+// CHECK:STDOUT:     %.loc18_21.2: type = converted %int.make_type_32.loc18_21, %.loc18_21.1 [template = i32]
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
+// CHECK:STDOUT:     %int.make_type_32.loc18_29: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %int.make_type_32.loc18_29 [template = i32]
+// CHECK:STDOUT:     %.loc18_29.2: type = converted %int.make_type_32.loc18_29, %.loc18_29.1 [template = i32]
 // CHECK:STDOUT:     %b.loc18_26.1: i32 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: i32 = bind_name b, %b.loc18_26.1
+// CHECK:STDOUT:     %bool.make_type.loc18: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc18_37.1: type = value_of_initializer %bool.make_type.loc18 [template = bool]
+// CHECK:STDOUT:     %.loc18_37.2: type = converted %bool.make_type.loc18, %.loc18_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc19_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_17.1: type = value_of_initializer %int.make_type_32.loc19_17 [template = i32]
+// CHECK:STDOUT:     %.loc19_17.2: type = converted %int.make_type_32.loc19_17, %.loc19_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_25.1: type = value_of_initializer %int.make_type_32.loc19_25 [template = i32]
+// CHECK:STDOUT:     %.loc19_25.2: type = converted %int.make_type_32.loc19_25, %.loc19_25.1 [template = i32]
 // CHECK:STDOUT:     %b.loc19_22.1: i32 = param b
 // CHECK:STDOUT:     @JustRight.%b: i32 = bind_name b, %b.loc19_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_33.1: type = value_of_initializer %int.make_type_32.loc19_33 [template = i32]
+// CHECK:STDOUT:     %.loc19_33.2: type = converted %int.make_type_32.loc19_33, %.loc19_33.1 [template = i32]
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.2]
 // 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: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.14: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.3]
 // 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: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %import_ref.15: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.5]
 // 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: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %import_ref.16: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.6]
 // 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_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
+// CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // 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.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.17: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %int.make_type_32.loc46_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_25.1: type = value_of_initializer %int.make_type_32.loc46_25 [template = i32]
+// CHECK:STDOUT:     %.loc46_25.2: type = converted %int.make_type_32.loc46_25, %.loc46_25.1 [template = i32]
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc46_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_33.1: type = value_of_initializer %int.make_type_32.loc46_33 [template = i32]
+// CHECK:STDOUT:     %.loc46_33.2: type = converted %int.make_type_32.loc46_33, %.loc46_33.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.19: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.22: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %int.make_type_32.loc50_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc50_26.1: type = value_of_initializer %int.make_type_32.loc50_26 [template = i32]
+// CHECK:STDOUT:     %.loc50_26.2: type = converted %int.make_type_32.loc50_26, %.loc50_26.1 [template = i32]
 // CHECK:STDOUT:     %a.loc50_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc50_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc50_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc50_34.1: type = value_of_initializer %int.make_type_32.loc50_34 [template = i32]
+// CHECK:STDOUT:     %.loc50_34.2: type = converted %int.make_type_32.loc50_34, %.loc50_34.1 [template = i32]
 // CHECK:STDOUT:     %b.loc50_31.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: i32 = bind_name b, %b.loc50_31.1
+// CHECK:STDOUT:     %int.make_type_32.loc50_42: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc50_42.1: type = value_of_initializer %int.make_type_32.loc50_42 [template = i32]
+// CHECK:STDOUT:     %.loc50_42.2: type = converted %int.make_type_32.loc50_42, %.loc50_42.1 [template = i32]
 // CHECK:STDOUT:     %c.loc50_39.1: i32 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc50_39.1
+// CHECK:STDOUT:     %int.make_type_32.loc50_50: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc50_50.1: type = value_of_initializer %int.make_type_32.loc50_50 [template = i32]
+// CHECK:STDOUT:     %.loc50_50.2: type = converted %int.make_type_32.loc50_50, %.loc50_50.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.23: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.24: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.25: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %int.make_type_32.loc54_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc54_32.1: type = value_of_initializer %int.make_type_32.loc54_32 [template = i32]
+// CHECK:STDOUT:     %.loc54_32.2: type = converted %int.make_type_32.loc54_32, %.loc54_32.1 [template = i32]
 // CHECK:STDOUT:     %a.loc54_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc54_29.1
+// CHECK:STDOUT:     %int.make_type_32.loc54_40: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc54_40.1: type = value_of_initializer %int.make_type_32.loc54_40 [template = i32]
+// CHECK:STDOUT:     %.loc54_40.2: type = converted %int.make_type_32.loc54_40, %.loc54_40.1 [template = i32]
 // CHECK:STDOUT:     %b.loc54_37.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: i32 = bind_name b, %b.loc54_37.1
+// CHECK:STDOUT:     %bool.make_type.loc54: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc54_48.1: type = value_of_initializer %bool.make_type.loc54 [template = bool]
+// CHECK:STDOUT:     %.loc54_48.2: type = converted %bool.make_type.loc54, %.loc54_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: i32) -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: i32, %b: i32, %c: i32) -> i32;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: i32, %b: i32) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: i32, %b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -286,7 +424,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: i32 = name_ref c, %c
@@ -298,7 +436,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)
@@ -310,9 +448,11 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -325,21 +465,41 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref.loc6: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_8.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_8.2: type = converted %int.make_type_32.loc6, %.loc6_8.1 [template = i32]
+// CHECK:STDOUT:   %Add.ref.loc6: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_8.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_8.2: type = converted %int.make_type_32.loc10, %.loc10_8.1 [template = i32]
+// CHECK:STDOUT:   %Add.ref.loc10: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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]
@@ -348,5 +508,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %b.loc10: i32 = bind_name b, %.loc10_32.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: i32, %b: i32) -> i32 = "int.sadd";
 // CHECK:STDOUT:

+ 137 - 29
toolchain/check/testdata/builtins/int/sdiv.carbon

@@ -56,16 +56,18 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -76,40 +78,74 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.sdiv";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.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:   %int.sdiv: init i32 = call %Div.ref(%a.ref, %b.ref)
@@ -121,13 +157,15 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: Div = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: Sub = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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]
@@ -143,30 +181,66 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_8.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_8.2: type = converted %int.make_type_32.loc9, %.loc9_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -177,9 +251,13 @@ let b: i32 = Div(0, 0);
 // 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: 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:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc12: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -193,16 +271,20 @@ let b: i32 = Div(0, 0);
 // 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: 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:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc19_8.1: type = value_of_initializer %int.make_type_32.loc19 [template = i32]
+// CHECK:STDOUT:   %.loc19_8.2: type = converted %int.make_type_32.loc19, %.loc19_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc19: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc19: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc19_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc19_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -215,6 +297,8 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc19_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.sdiv";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.ssub";
@@ -224,9 +308,11 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: Div = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
@@ -237,21 +323,41 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_8.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_8.2: type = converted %int.make_type_32.loc10, %.loc10_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc15_8.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
+// CHECK:STDOUT:   %.loc15_8.2: type = converted %int.make_type_32.loc15, %.loc15_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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>]
@@ -260,5 +366,7 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %b.loc15: i32 = bind_name b, %.loc15_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.sdiv";
 // CHECK:STDOUT:

+ 137 - 29
toolchain/check/testdata/builtins/int/smod.carbon

@@ -59,16 +59,18 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -79,40 +81,74 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.smod";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.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:   %int.smod: init i32 = call %Mod.ref(%a.ref, %b.ref)
@@ -124,13 +160,15 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: Mod = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: Sub = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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]
@@ -147,30 +185,66 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_8.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_8.2: type = converted %int.make_type_32.loc9, %.loc9_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc9: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -181,9 +255,13 @@ let b: i32 = Mod(0, 0);
 // 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: 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:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -197,16 +275,20 @@ let b: i32 = Mod(0, 0);
 // 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: 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:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc20: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc20_8.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
+// CHECK:STDOUT:   %.loc20_8.2: type = converted %int.make_type_32.loc20, %.loc20_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc20: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc20: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc20_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc20_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -219,6 +301,8 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc20_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.smod";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.ssub";
@@ -228,9 +312,11 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: Mod = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
@@ -241,21 +327,41 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_8.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
+// CHECK:STDOUT:   %.loc17_8.2: type = converted %int.make_type_32.loc17, %.loc17_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc17: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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>]
@@ -264,5 +370,7 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %b.loc17: i32 = bind_name b, %.loc17_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.smod";
 // CHECK:STDOUT:

+ 72 - 12
toolchain/check/testdata/builtins/int/smul.carbon

@@ -30,16 +30,18 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- int_mul.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mul = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -50,40 +52,74 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mul(%a: i32, %b: i32) -> i32 = "int.smul";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.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:   %int.smul: init i32 = call %Mul.ref(%a.ref, %b.ref)
@@ -95,9 +131,11 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Mul = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -111,21 +149,41 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_8.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_8.2: type = converted %int.make_type_32.loc6, %.loc6_8.1 [template = i32]
+// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_8.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_8.2: type = converted %int.make_type_32.loc10, %.loc10_8.1 [template = i32]
+// CHECK:STDOUT:   %Mul.ref.loc10: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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]
@@ -134,5 +192,7 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %b.loc10: i32 = bind_name b, %.loc10_34.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mul(%a: i32, %b: i32) -> i32 = "int.smul";
 // CHECK:STDOUT:

+ 195 - 41
toolchain/check/testdata/builtins/int/snegate.carbon

@@ -115,9 +115,11 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 123 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal -123 [template]
 // CHECK:STDOUT:   %.4: type = array_type %.2, i32 [template]
@@ -125,7 +127,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -136,47 +138,81 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_14.1: type = value_of_initializer %int.make_type_32.loc2_14 [template = i32]
+// CHECK:STDOUT:     %.loc2_14.2: type = converted %int.make_type_32.loc2_14, %.loc2_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc2_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_22.1: type = value_of_initializer %int.make_type_32.loc2_22 [template = i32]
+// CHECK:STDOUT:     %.loc2_22.2: type = converted %int.make_type_32.loc2_22, %.loc2_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc4_16: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc4_23: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc7: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc9_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_19.1: type = value_of_initializer %int.make_type_32.loc9_19 [template = i32]
+// CHECK:STDOUT:     %.loc9_19.2: type = converted %int.make_type_32.loc9_19, %.loc9_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc9_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc9_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc9_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_27.1: type = value_of_initializer %int.make_type_32.loc9_27 [template = i32]
+// CHECK:STDOUT:     %.loc9_27.2: type = converted %int.make_type_32.loc9_27, %.loc9_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc9_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc9_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc9_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_35.1: type = value_of_initializer %int.make_type_32.loc9_35 [template = i32]
+// CHECK:STDOUT:     %.loc9_35.2: type = converted %int.make_type_32.loc9_35, %.loc9_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // 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
@@ -187,23 +223,27 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: 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:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -222,82 +262,164 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_16.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:     %.loc8_16.2: type = converted %int.make_type_32.loc8, %.loc8_16.1 [template = i32]
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc13_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_15.1: type = value_of_initializer %int.make_type_32.loc13_15 [template = i32]
+// CHECK:STDOUT:     %.loc13_15.2: type = converted %int.make_type_32.loc13_15, %.loc13_15.1 [template = i32]
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_23.1: type = value_of_initializer %int.make_type_32.loc13_23 [template = i32]
+// CHECK:STDOUT:     %.loc13_23.2: type = converted %int.make_type_32.loc13_23, %.loc13_23.1 [template = i32]
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_31: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_31.1: type = value_of_initializer %int.make_type_32.loc13_31 [template = i32]
+// CHECK:STDOUT:     %.loc13_31.2: type = converted %int.make_type_32.loc13_31, %.loc13_31.1 [template = i32]
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_21.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
+// CHECK:STDOUT:     %.loc18_21.2: type = converted %int.make_type_32.loc18, %.loc18_21.1 [template = i32]
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
+// CHECK:STDOUT:     %bool.make_type.loc18: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %bool.make_type.loc18 [template = bool]
+// CHECK:STDOUT:     %.loc18_29.2: type = converted %bool.make_type.loc18, %.loc18_29.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc19_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_17.1: type = value_of_initializer %int.make_type_32.loc19_17 [template = i32]
+// CHECK:STDOUT:     %.loc19_17.2: type = converted %int.make_type_32.loc19_17, %.loc19_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_25.1: type = value_of_initializer %int.make_type_32.loc19_25 [template = i32]
+// CHECK:STDOUT:     %.loc19_25.2: type = converted %int.make_type_32.loc19_25, %.loc19_25.1 [template = i32]
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.2]
 // 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: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.3]
 // 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: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.5]
 // 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: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.6]
 // 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_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
+// CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // 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.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %int.make_type_32.loc46_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_25.1: type = value_of_initializer %int.make_type_32.loc46_25 [template = i32]
+// CHECK:STDOUT:     %.loc46_25.2: type = converted %int.make_type_32.loc46_25, %.loc46_25.1 [template = i32]
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc46_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_33.1: type = value_of_initializer %int.make_type_32.loc46_33 [template = i32]
+// CHECK:STDOUT:     %.loc46_33.2: type = converted %int.make_type_32.loc46_33, %.loc46_33.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %int.make_type_32.loc57_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_26.1: type = value_of_initializer %int.make_type_32.loc57_26 [template = i32]
+// CHECK:STDOUT:     %.loc57_26.2: type = converted %int.make_type_32.loc57_26, %.loc57_26.1 [template = i32]
 // CHECK:STDOUT:     %a.loc57_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc57_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_34.1: type = value_of_initializer %int.make_type_32.loc57_34 [template = i32]
+// CHECK:STDOUT:     %.loc57_34.2: type = converted %int.make_type_32.loc57_34, %.loc57_34.1 [template = i32]
 // CHECK:STDOUT:     %b.loc57_31.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: i32 = bind_name b, %b.loc57_31.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_42: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_42.1: type = value_of_initializer %int.make_type_32.loc57_42 [template = i32]
+// CHECK:STDOUT:     %.loc57_42.2: type = converted %int.make_type_32.loc57_42, %.loc57_42.1 [template = i32]
 // CHECK:STDOUT:     %c.loc57_39.1: i32 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc57_39.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_50: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_50.1: type = value_of_initializer %int.make_type_32.loc57_50 [template = i32]
+// CHECK:STDOUT:     %.loc57_50.2: type = converted %int.make_type_32.loc57_50, %.loc57_50.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %int.make_type_32.loc68_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc68_32.1: type = value_of_initializer %int.make_type_32.loc68_32 [template = i32]
+// CHECK:STDOUT:     %.loc68_32.2: type = converted %int.make_type_32.loc68_32, %.loc68_32.1 [template = i32]
 // CHECK:STDOUT:     %a.loc68_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc68_29.1
+// CHECK:STDOUT:     %int.make_type_32.loc68_40: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc68_40.1: type = value_of_initializer %int.make_type_32.loc68_40 [template = i32]
+// CHECK:STDOUT:     %.loc68_40.2: type = converted %int.make_type_32.loc68_40, %.loc68_40.1 [template = i32]
 // CHECK:STDOUT:     %b.loc68_37.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: i32 = bind_name b, %b.loc68_37.1
+// CHECK:STDOUT:     %bool.make_type.loc68: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc68_48.1: type = value_of_initializer %bool.make_type.loc68 [template = bool]
+// CHECK:STDOUT:     %.loc68_48.2: type = converted %bool.make_type.loc68, %.loc68_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew() -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: i32, %b: i32) -> i32;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: i32) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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>]
@@ -307,7 +429,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: i32 = name_ref c, %c
@@ -319,7 +441,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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>]
@@ -331,11 +453,13 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -349,20 +473,44 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_14.1: type = value_of_initializer %int.make_type_32.loc4_14 [template = i32]
+// CHECK:STDOUT:     %.loc4_14.2: type = converted %int.make_type_32.loc4_14, %.loc4_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc4_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_22.1: type = value_of_initializer %int.make_type_32.loc4_22 [template = i32]
+// CHECK:STDOUT:     %.loc4_22.2: type = converted %int.make_type_32.loc4_22, %.loc4_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc8_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc8_21: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -371,9 +519,13 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // 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: 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:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc14_8.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
+// CHECK:STDOUT:   %.loc14_8.2: type = converted %int.make_type_32.loc14, %.loc14_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc14_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc14_25: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -388,6 +540,8 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %b.loc14: i32 = bind_name b, %.loc14_48.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.snegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.ssub";

+ 79 - 15
toolchain/check/testdata/builtins/int/ssub.carbon

@@ -31,16 +31,18 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- int_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -51,40 +53,74 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.ssub";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.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:   %int.ssub: init i32 = call %Sub.ref(%a.ref, %b.ref)
@@ -96,9 +132,11 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- fail_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 0 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 2147483647 [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal -2147483647 [template]
@@ -113,22 +151,42 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_8.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_8.2: type = converted %int.make_type_32.loc6, %.loc6_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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: 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc7_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc7_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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]
@@ -139,8 +197,12 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // 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: 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc11_8.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_8.2: type = converted %int.make_type_32.loc11, %.loc11_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc11_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc11_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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]
@@ -153,5 +215,7 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc11_40.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.ssub";
 // CHECK:STDOUT:

+ 196 - 34
toolchain/check/testdata/builtins/int/uadd.carbon

@@ -85,16 +85,18 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- int_add.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Add = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -105,40 +107,74 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 3 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: i32, %b: i32) -> i32 = "int.uadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.ref: Add = name_ref Add, file.%Add.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:   %int.uadd: init i32 = call %Add.ref(%a.ref, %b.ref)
@@ -150,24 +186,28 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: 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:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -186,94 +226,192 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc8_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_14.1: type = value_of_initializer %int.make_type_32.loc8_14 [template = i32]
+// CHECK:STDOUT:     %.loc8_14.2: type = converted %int.make_type_32.loc8_14, %.loc8_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc8_11.1: i32 = param a
 // CHECK:STDOUT:     @TooFew.%a: i32 = bind_name a, %a.loc8_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc8_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_22.1: type = value_of_initializer %int.make_type_32.loc8_22 [template = i32]
+// CHECK:STDOUT:     %.loc8_22.2: type = converted %int.make_type_32.loc8_22, %.loc8_22.1 [template = i32]
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc13_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_15.1: type = value_of_initializer %int.make_type_32.loc13_15 [template = i32]
+// CHECK:STDOUT:     %.loc13_15.2: type = converted %int.make_type_32.loc13_15, %.loc13_15.1 [template = i32]
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_23.1: type = value_of_initializer %int.make_type_32.loc13_23 [template = i32]
+// CHECK:STDOUT:     %.loc13_23.2: type = converted %int.make_type_32.loc13_23, %.loc13_23.1 [template = i32]
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_31: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_31.1: type = value_of_initializer %int.make_type_32.loc13_31 [template = i32]
+// CHECK:STDOUT:     %.loc13_31.2: type = converted %int.make_type_32.loc13_31, %.loc13_31.1 [template = i32]
 // CHECK:STDOUT:     %c.loc13_28.1: i32 = param c
 // CHECK:STDOUT:     @TooMany.%c: i32 = bind_name c, %c.loc13_28.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_39: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_39.1: type = value_of_initializer %int.make_type_32.loc13_39 [template = i32]
+// CHECK:STDOUT:     %.loc13_39.2: type = converted %int.make_type_32.loc13_39, %.loc13_39.1 [template = i32]
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc18_21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_21.1: type = value_of_initializer %int.make_type_32.loc18_21 [template = i32]
+// CHECK:STDOUT:     %.loc18_21.2: type = converted %int.make_type_32.loc18_21, %.loc18_21.1 [template = i32]
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
+// CHECK:STDOUT:     %int.make_type_32.loc18_29: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %int.make_type_32.loc18_29 [template = i32]
+// CHECK:STDOUT:     %.loc18_29.2: type = converted %int.make_type_32.loc18_29, %.loc18_29.1 [template = i32]
 // CHECK:STDOUT:     %b.loc18_26.1: i32 = param b
 // CHECK:STDOUT:     @BadReturnType.%b: i32 = bind_name b, %b.loc18_26.1
+// CHECK:STDOUT:     %bool.make_type.loc18: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc18_37.1: type = value_of_initializer %bool.make_type.loc18 [template = bool]
+// CHECK:STDOUT:     %.loc18_37.2: type = converted %bool.make_type.loc18, %.loc18_37.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc19_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_17.1: type = value_of_initializer %int.make_type_32.loc19_17 [template = i32]
+// CHECK:STDOUT:     %.loc19_17.2: type = converted %int.make_type_32.loc19_17, %.loc19_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_25.1: type = value_of_initializer %int.make_type_32.loc19_25 [template = i32]
+// CHECK:STDOUT:     %.loc19_25.2: type = converted %int.make_type_32.loc19_25, %.loc19_25.1 [template = i32]
 // CHECK:STDOUT:     %b.loc19_22.1: i32 = param b
 // CHECK:STDOUT:     @JustRight.%b: i32 = bind_name b, %b.loc19_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_33.1: type = value_of_initializer %int.make_type_32.loc19_33 [template = i32]
+// CHECK:STDOUT:     %.loc19_33.2: type = converted %int.make_type_32.loc19_33, %.loc19_33.1 [template = i32]
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.2]
 // 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: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.14: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.3]
 // 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: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %import_ref.15: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.5]
 // 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: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %import_ref.16: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc43: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.6]
 // 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_16.1: type = value_of_initializer %int.make_type_32.loc43 [template = i32]
+// CHECK:STDOUT:   %.loc43_16.2: type = converted %int.make_type_32.loc43, %.loc43_16.1 [template = i32]
 // 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.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.17: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %int.make_type_32.loc45_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc45_25.1: type = value_of_initializer %int.make_type_32.loc45_25 [template = i32]
+// CHECK:STDOUT:     %.loc45_25.2: type = converted %int.make_type_32.loc45_25, %.loc45_25.1 [template = i32]
 // CHECK:STDOUT:     %a.loc45_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc45_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc45_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc45_33.1: type = value_of_initializer %int.make_type_32.loc45_33 [template = i32]
+// CHECK:STDOUT:     %.loc45_33.2: type = converted %int.make_type_32.loc45_33, %.loc45_33.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.19: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.22: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %int.make_type_32.loc49_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc49_26.1: type = value_of_initializer %int.make_type_32.loc49_26 [template = i32]
+// CHECK:STDOUT:     %.loc49_26.2: type = converted %int.make_type_32.loc49_26, %.loc49_26.1 [template = i32]
 // CHECK:STDOUT:     %a.loc49_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc49_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc49_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc49_34.1: type = value_of_initializer %int.make_type_32.loc49_34 [template = i32]
+// CHECK:STDOUT:     %.loc49_34.2: type = converted %int.make_type_32.loc49_34, %.loc49_34.1 [template = i32]
 // CHECK:STDOUT:     %b.loc49_31.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: i32 = bind_name b, %b.loc49_31.1
+// CHECK:STDOUT:     %int.make_type_32.loc49_42: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc49_42.1: type = value_of_initializer %int.make_type_32.loc49_42 [template = i32]
+// CHECK:STDOUT:     %.loc49_42.2: type = converted %int.make_type_32.loc49_42, %.loc49_42.1 [template = i32]
 // CHECK:STDOUT:     %c.loc49_39.1: i32 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc49_39.1
+// CHECK:STDOUT:     %int.make_type_32.loc49_50: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc49_50.1: type = value_of_initializer %int.make_type_32.loc49_50 [template = i32]
+// CHECK:STDOUT:     %.loc49_50.2: type = converted %int.make_type_32.loc49_50, %.loc49_50.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.23: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.24: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.25: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %int.make_type_32.loc53_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc53_32.1: type = value_of_initializer %int.make_type_32.loc53_32 [template = i32]
+// CHECK:STDOUT:     %.loc53_32.2: type = converted %int.make_type_32.loc53_32, %.loc53_32.1 [template = i32]
 // CHECK:STDOUT:     %a.loc53_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc53_29.1
+// CHECK:STDOUT:     %int.make_type_32.loc53_40: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc53_40.1: type = value_of_initializer %int.make_type_32.loc53_40 [template = i32]
+// CHECK:STDOUT:     %.loc53_40.2: type = converted %int.make_type_32.loc53_40, %.loc53_40.1 [template = i32]
 // CHECK:STDOUT:     %b.loc53_37.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: i32 = bind_name b, %b.loc53_37.1
+// CHECK:STDOUT:     %bool.make_type.loc53: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc53_48.1: type = value_of_initializer %bool.make_type.loc53 [template = bool]
+// CHECK:STDOUT:     %.loc53_48.2: type = converted %bool.make_type.loc53, %.loc53_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew(%a: i32) -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: i32, %b: i32, %c: i32) -> i32;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: i32, %b: i32) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: i32, %b: i32) -> i32 = "int.uadd";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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
@@ -283,7 +421,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: i32 = name_ref c, %c
@@ -295,7 +433,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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)
@@ -307,9 +445,11 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Add = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Add: type = fn_type @Add [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -322,21 +462,41 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:     .Add = %Add.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Add.decl: Add = fn_decl @Add [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Add.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Add.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Add.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Add.ref.loc7: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Add.ref.loc7: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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: Add = name_ref Add, %Add.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
+// CHECK:STDOUT:   %Add.ref.loc8: Add = name_ref Add, %Add.decl [template = constants.%struct.2]
 // 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]
@@ -345,5 +505,7 @@ let b: i32 = Add(0x7FFFFFFF, 1);
 // CHECK:STDOUT:   %b.loc8: i32 = bind_name b, %.loc8_32.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Add(%a: i32, %b: i32) -> i32 = "int.uadd";
 // CHECK:STDOUT:

+ 137 - 29
toolchain/check/testdata/builtins/int/udiv.carbon

@@ -52,16 +52,18 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -72,40 +74,74 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.udiv";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.ref: Div = name_ref Div, file.%Div.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:   %int.udiv: init i32 = call %Div.ref(%a.ref, %b.ref)
@@ -117,13 +153,15 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: Div = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: Sub = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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]
@@ -140,30 +178,66 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_8.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_8.2: type = converted %int.make_type_32.loc9, %.loc9_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc9: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -174,9 +248,13 @@ let b: i32 = Div(0, 0);
 // 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: 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:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc12: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -190,16 +268,20 @@ let b: i32 = Div(0, 0);
 // 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: 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:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc15_8.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
+// CHECK:STDOUT:   %.loc15_8.2: type = converted %int.make_type_32.loc15, %.loc15_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc15: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc15_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc15_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -212,6 +294,8 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.udiv";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.usub";
@@ -221,9 +305,11 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Div = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Div: type = fn_type @Div [template]
+// CHECK:STDOUT:   %struct.2: Div = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
@@ -234,21 +320,41 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:     .Div = %Div.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Div.decl: Div = fn_decl @Div [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Div.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Div.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Div.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_8.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_8.2: type = converted %int.make_type_32.loc10, %.loc10_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc10: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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: Div = name_ref Div, %Div.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc15_8.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
+// CHECK:STDOUT:   %.loc15_8.2: type = converted %int.make_type_32.loc15, %.loc15_8.1 [template = i32]
+// CHECK:STDOUT:   %Div.ref.loc15: Div = name_ref Div, %Div.decl [template = constants.%struct.2]
 // 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>]
@@ -257,5 +363,7 @@ let b: i32 = Div(0, 0);
 // CHECK:STDOUT:   %b.loc15: i32 = bind_name b, %.loc15_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Div(%a: i32, %b: i32) -> i32 = "int.udiv";
 // CHECK:STDOUT:

+ 137 - 29
toolchain/check/testdata/builtins/int/umod.carbon

@@ -54,16 +54,18 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- int_div.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -74,40 +76,74 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 2 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.umod";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.ref: Mod = name_ref Mod, file.%Mod.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:   %int.umod: init i32 = call %Mod.ref(%a.ref, %b.ref)
@@ -119,13 +155,15 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: Mod = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: Sub = struct_value () [template]
 // CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
-// CHECK:STDOUT:   %struct.3: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: 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]
@@ -142,30 +180,66 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc6_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_14.1: type = value_of_initializer %int.make_type_32.loc6_14 [template = i32]
+// CHECK:STDOUT:     %.loc6_14.2: type = converted %int.make_type_32.loc6_14, %.loc6_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc6_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc6_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc6_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc6_22.1: type = value_of_initializer %int.make_type_32.loc6_22 [template = i32]
+// CHECK:STDOUT:     %.loc6_22.2: type = converted %int.make_type_32.loc6_22, %.loc6_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_8.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_8.2: type = converted %int.make_type_32.loc9, %.loc9_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc9: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc9_18: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc9_39: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -176,9 +250,13 @@ let b: i32 = Mod(0, 0);
 // 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: 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:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc12: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc12: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -192,16 +270,20 @@ let b: i32 = Mod(0, 0);
 // 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: 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:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc15_8.1: type = value_of_initializer %int.make_type_32.loc15 [template = i32]
+// CHECK:STDOUT:   %.loc15_8.2: type = converted %int.make_type_32.loc15, %.loc15_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc15: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc15: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc15_22: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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:   %Negate.ref.loc15_47: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.4]
 // 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]
@@ -214,6 +296,8 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc15_57.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.umod";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.usub";
@@ -223,9 +307,11 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT: --- fail_div_by_zero.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Mod = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mod: type = fn_type @Mod [template]
+// CHECK:STDOUT:   %struct.2: Mod = struct_value () [template]
 // CHECK:STDOUT:   %.2: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
@@ -236,21 +322,41 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:     .Mod = %Mod.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mod.decl: Mod = fn_decl @Mod [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mod.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mod.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mod.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc12: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_8.1: type = value_of_initializer %int.make_type_32.loc12 [template = i32]
+// CHECK:STDOUT:   %.loc12_8.2: type = converted %int.make_type_32.loc12, %.loc12_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc12: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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: Mod = name_ref Mod, %Mod.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_8.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
+// CHECK:STDOUT:   %.loc17_8.2: type = converted %int.make_type_32.loc17, %.loc17_8.1 [template = i32]
+// CHECK:STDOUT:   %Mod.ref.loc17: Mod = name_ref Mod, %Mod.decl [template = constants.%struct.2]
 // 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>]
@@ -259,5 +365,7 @@ let b: i32 = Mod(0, 0);
 // CHECK:STDOUT:   %b.loc17: i32 = bind_name b, %.loc17_23.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mod(%a: i32, %b: i32) -> i32 = "int.umod";
 // CHECK:STDOUT:

+ 72 - 12
toolchain/check/testdata/builtins/int/umul.carbon

@@ -27,16 +27,18 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- int_mul.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Mul = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -47,40 +49,74 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mul(%a: i32, %b: i32) -> i32 = "int.umul";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.ref: Mul = name_ref Mul, file.%Mul.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:   %int.umul: init i32 = call %Mul.ref(%a.ref, %b.ref)
@@ -92,9 +128,11 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Mul = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Mul: type = fn_type @Mul [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -108,21 +146,41 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:     .Mul = %Mul.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Mul.decl: Mul = fn_decl @Mul [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Mul.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Mul.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Mul.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_8.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_8.2: type = converted %int.make_type_32.loc6, %.loc6_8.1 [template = i32]
+// CHECK:STDOUT:   %Mul.ref.loc6: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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: Mul = name_ref Mul, %Mul.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Mul.ref.loc7: Mul = name_ref Mul, %Mul.decl [template = constants.%struct.2]
 // 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]
@@ -131,5 +189,7 @@ let b: i32 = Mul(0x8000, 0x10000);
 // CHECK:STDOUT:   %b.loc7: i32 = bind_name b, %.loc7_34.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Mul(%a: i32, %b: i32) -> i32 = "int.umul";
 // CHECK:STDOUT:

+ 195 - 41
toolchain/check/testdata/builtins/int/unegate.carbon

@@ -111,9 +111,11 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 123 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal -123 [template]
 // CHECK:STDOUT:   %.4: type = array_type %.2, i32 [template]
@@ -121,7 +123,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -132,47 +134,81 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_14.1: type = value_of_initializer %int.make_type_32.loc2_14 [template = i32]
+// CHECK:STDOUT:     %.loc2_14.2: type = converted %int.make_type_32.loc2_14, %.loc2_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc2_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_22.1: type = value_of_initializer %int.make_type_32.loc2_22 [template = i32]
+// CHECK:STDOUT:     %.loc2_22.2: type = converted %int.make_type_32.loc2_22, %.loc2_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc4_16: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc4_23: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 123 [template = constants.%.2]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc7: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc9_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_19.1: type = value_of_initializer %int.make_type_32.loc9_19 [template = i32]
+// CHECK:STDOUT:     %.loc9_19.2: type = converted %int.make_type_32.loc9_19, %.loc9_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc9_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc9_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc9_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_27.1: type = value_of_initializer %int.make_type_32.loc9_27 [template = i32]
+// CHECK:STDOUT:     %.loc9_27.2: type = converted %int.make_type_32.loc9_27, %.loc9_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc9_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc9_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc9_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_35.1: type = value_of_initializer %int.make_type_32.loc9_35 [template = i32]
+// CHECK:STDOUT:     %.loc9_35.2: type = converted %int.make_type_32.loc9_35, %.loc9_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.unegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.ref: Negate = name_ref Negate, file.%Negate.decl [template = constants.%struct.2]
 // 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
@@ -183,23 +219,27 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- fail_bad_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: TooFew = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %TooFew: type = fn_type @TooFew [template]
+// CHECK:STDOUT:   %struct.2: TooFew = struct_value () [template]
 // CHECK:STDOUT:   %TooMany: type = fn_type @TooMany [template]
-// CHECK:STDOUT:   %struct.2: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: TooMany = struct_value () [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %struct.4: Bool = struct_value () [template]
 // CHECK:STDOUT:   %BadReturnType: type = fn_type @BadReturnType [template]
-// CHECK:STDOUT:   %struct.3: BadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: BadReturnType = struct_value () [template]
 // CHECK:STDOUT:   %JustRight: type = fn_type @JustRight [template]
-// CHECK:STDOUT:   %struct.4: JustRight = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: 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:   %struct.7: RuntimeCallTooFew = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallTooMany: type = fn_type @RuntimeCallTooMany [template]
-// CHECK:STDOUT:   %struct.6: RuntimeCallTooMany = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: RuntimeCallTooMany = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCallBadReturnType: type = fn_type @RuntimeCallBadReturnType [template]
-// CHECK:STDOUT:   %struct.7: RuntimeCallBadReturnType = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: RuntimeCallBadReturnType = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -218,82 +258,164 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .RuntimeCallBadReturnType = %RuntimeCallBadReturnType.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.decl: TooFew = fn_decl @TooFew [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_16.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:     %.loc8_16.2: type = converted %int.make_type_32.loc8, %.loc8_16.1 [template = i32]
 // CHECK:STDOUT:     @TooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooMany.decl: TooMany = fn_decl @TooMany [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc13_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_15.1: type = value_of_initializer %int.make_type_32.loc13_15 [template = i32]
+// CHECK:STDOUT:     %.loc13_15.2: type = converted %int.make_type_32.loc13_15, %.loc13_15.1 [template = i32]
 // CHECK:STDOUT:     %a.loc13_12.1: i32 = param a
 // CHECK:STDOUT:     @TooMany.%a: i32 = bind_name a, %a.loc13_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_23.1: type = value_of_initializer %int.make_type_32.loc13_23 [template = i32]
+// CHECK:STDOUT:     %.loc13_23.2: type = converted %int.make_type_32.loc13_23, %.loc13_23.1 [template = i32]
 // CHECK:STDOUT:     %b.loc13_20.1: i32 = param b
 // CHECK:STDOUT:     @TooMany.%b: i32 = bind_name b, %b.loc13_20.1
+// CHECK:STDOUT:     %int.make_type_32.loc13_31: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_31.1: type = value_of_initializer %int.make_type_32.loc13_31 [template = i32]
+// CHECK:STDOUT:     %.loc13_31.2: type = converted %int.make_type_32.loc13_31, %.loc13_31.1 [template = i32]
 // CHECK:STDOUT:     @TooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %BadReturnType.decl: BadReturnType = fn_decl @BadReturnType [template = constants.%struct.5] {
+// CHECK:STDOUT:     %int.make_type_32.loc18: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_21.1: type = value_of_initializer %int.make_type_32.loc18 [template = i32]
+// CHECK:STDOUT:     %.loc18_21.2: type = converted %int.make_type_32.loc18, %.loc18_21.1 [template = i32]
 // CHECK:STDOUT:     %a.loc18_18.1: i32 = param a
 // CHECK:STDOUT:     @BadReturnType.%a: i32 = bind_name a, %a.loc18_18.1
+// CHECK:STDOUT:     %bool.make_type.loc18: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %bool.make_type.loc18 [template = bool]
+// CHECK:STDOUT:     %.loc18_29.2: type = converted %bool.make_type.loc18, %.loc18_29.1 [template = bool]
 // CHECK:STDOUT:     @BadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %JustRight.decl: JustRight = fn_decl @JustRight [template = constants.%struct.6] {
+// CHECK:STDOUT:     %int.make_type_32.loc19_17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_17.1: type = value_of_initializer %int.make_type_32.loc19_17 [template = i32]
+// CHECK:STDOUT:     %.loc19_17.2: type = converted %int.make_type_32.loc19_17, %.loc19_17.1 [template = i32]
 // CHECK:STDOUT:     %a.loc19_14.1: i32 = param a
 // CHECK:STDOUT:     @JustRight.%a: i32 = bind_name a, %a.loc19_14.1
+// CHECK:STDOUT:     %int.make_type_32.loc19_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc19_25.1: type = value_of_initializer %int.make_type_32.loc19_25 [template = i32]
+// CHECK:STDOUT:     %.loc19_25.2: type = converted %int.make_type_32.loc19_25, %.loc19_25.1 [template = i32]
 // CHECK:STDOUT:     @JustRight.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, %TooFew.decl [template = constants.%struct.2]
 // 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: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, %TooMany.decl [template = constants.%struct.3]
 // 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: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, %BadReturnType.decl [template = constants.%struct.5]
 // 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: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.4]
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc44: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %JustRight.ref: JustRight = name_ref JustRight, %JustRight.decl [template = constants.%struct.6]
 // 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_16.1: type = value_of_initializer %int.make_type_32.loc44 [template = i32]
+// CHECK:STDOUT:   %.loc44_16.2: type = converted %int.make_type_32.loc44, %.loc44_16.1 [template = i32]
 // 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.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.14: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooFew.decl: RuntimeCallTooFew = fn_decl @RuntimeCallTooFew [template = constants.%struct.7] {
+// CHECK:STDOUT:     %int.make_type_32.loc46_25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_25.1: type = value_of_initializer %int.make_type_32.loc46_25 [template = i32]
+// CHECK:STDOUT:     %.loc46_25.2: type = converted %int.make_type_32.loc46_25, %.loc46_25.1 [template = i32]
 // CHECK:STDOUT:     %a.loc46_22.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooFew.%a: i32 = bind_name a, %a.loc46_22.1
+// CHECK:STDOUT:     %int.make_type_32.loc46_33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc46_33.1: type = value_of_initializer %int.make_type_32.loc46_33 [template = i32]
+// CHECK:STDOUT:     %.loc46_33.2: type = converted %int.make_type_32.loc46_33, %.loc46_33.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooFew.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.15: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.16: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.17: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.18: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCallTooMany.decl: RuntimeCallTooMany = fn_decl @RuntimeCallTooMany [template = constants.%struct.8] {
+// CHECK:STDOUT:     %int.make_type_32.loc57_26: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_26.1: type = value_of_initializer %int.make_type_32.loc57_26 [template = i32]
+// CHECK:STDOUT:     %.loc57_26.2: type = converted %int.make_type_32.loc57_26, %.loc57_26.1 [template = i32]
 // CHECK:STDOUT:     %a.loc57_23.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallTooMany.%a: i32 = bind_name a, %a.loc57_23.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_34: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_34.1: type = value_of_initializer %int.make_type_32.loc57_34 [template = i32]
+// CHECK:STDOUT:     %.loc57_34.2: type = converted %int.make_type_32.loc57_34, %.loc57_34.1 [template = i32]
 // CHECK:STDOUT:     %b.loc57_31.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallTooMany.%b: i32 = bind_name b, %b.loc57_31.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_42: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_42.1: type = value_of_initializer %int.make_type_32.loc57_42 [template = i32]
+// CHECK:STDOUT:     %.loc57_42.2: type = converted %int.make_type_32.loc57_42, %.loc57_42.1 [template = i32]
 // CHECK:STDOUT:     %c.loc57_39.1: i32 = param c
 // CHECK:STDOUT:     @RuntimeCallTooMany.%c: i32 = bind_name c, %c.loc57_39.1
+// CHECK:STDOUT:     %int.make_type_32.loc57_50: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc57_50.1: type = value_of_initializer %int.make_type_32.loc57_50 [template = i32]
+// CHECK:STDOUT:     %.loc57_50.2: type = converted %int.make_type_32.loc57_50, %.loc57_50.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCallTooMany.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.19: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.20: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.21: Bool = import_ref ir7, inst+2, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: RuntimeCallBadReturnType = fn_decl @RuntimeCallBadReturnType [template = constants.%struct.9] {
+// CHECK:STDOUT:     %int.make_type_32.loc68_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc68_32.1: type = value_of_initializer %int.make_type_32.loc68_32 [template = i32]
+// CHECK:STDOUT:     %.loc68_32.2: type = converted %int.make_type_32.loc68_32, %.loc68_32.1 [template = i32]
 // CHECK:STDOUT:     %a.loc68_29.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%a: i32 = bind_name a, %a.loc68_29.1
+// CHECK:STDOUT:     %int.make_type_32.loc68_40: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc68_40.1: type = value_of_initializer %int.make_type_32.loc68_40 [template = i32]
+// CHECK:STDOUT:     %.loc68_40.2: type = converted %int.make_type_32.loc68_40, %.loc68_40.1 [template = i32]
 // CHECK:STDOUT:     %b.loc68_37.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%b: i32 = bind_name b, %b.loc68_37.1
+// CHECK:STDOUT:     %bool.make_type.loc68: init type = call constants.%struct.4() [template = bool]
+// CHECK:STDOUT:     %.loc68_48.1: type = value_of_initializer %bool.make_type.loc68 [template = bool]
+// CHECK:STDOUT:     %.loc68_48.2: type = converted %bool.make_type.loc68, %.loc68_48.1 [template = bool]
 // CHECK:STDOUT:     @RuntimeCallBadReturnType.%return: ref bool = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooFew() -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @TooMany(%a: i32, %b: i32) -> i32;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @BadReturnType(%a: i32) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @JustRight(%a: i32) -> i32 = "int.unegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCallTooFew(%a: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %TooFew.ref: TooFew = name_ref TooFew, file.%TooFew.decl [template = constants.%struct.2]
 // 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>]
@@ -303,7 +425,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: TooMany = name_ref TooMany, file.%TooMany.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %TooMany.ref: TooMany = name_ref TooMany, file.%TooMany.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:   %c.ref: i32 = name_ref c, %c
@@ -315,7 +437,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: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %BadReturnType.ref: BadReturnType = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%struct.5]
 // 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>]
@@ -327,11 +449,13 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Negate = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Negate: type = fn_type @Negate [template]
+// CHECK:STDOUT:   %struct.2: Negate = struct_value () [template]
 // CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
-// CHECK:STDOUT:   %struct.2: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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]
@@ -345,20 +469,44 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Negate.decl: Negate = fn_decl @Negate [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_14.1: type = value_of_initializer %int.make_type_32.loc4_14 [template = i32]
+// CHECK:STDOUT:     %.loc4_14.2: type = converted %int.make_type_32.loc4_14, %.loc4_14.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_11.1: i32 = param a
 // CHECK:STDOUT:     @Negate.%a: i32 = bind_name a, %a.loc4_11.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_22: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_22.1: type = value_of_initializer %int.make_type_32.loc4_22 [template = i32]
+// CHECK:STDOUT:     %.loc4_22.2: type = converted %int.make_type_32.loc4_22, %.loc4_22.1 [template = i32]
 // CHECK:STDOUT:     @Negate.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc5_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_11.1: type = value_of_initializer %int.make_type_32.loc5_11 [template = i32]
+// CHECK:STDOUT:     %.loc5_11.2: type = converted %int.make_type_32.loc5_11, %.loc5_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc5_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc5_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5_19 [template = i32]
+// CHECK:STDOUT:     %.loc5_19.2: type = converted %int.make_type_32.loc5_19, %.loc5_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc5_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc5_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc5_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc5_27.1: type = value_of_initializer %int.make_type_32.loc5_27 [template = i32]
+// CHECK:STDOUT:     %.loc5_27.2: type = converted %int.make_type_32.loc5_27, %.loc5_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc8_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Negate.ref.loc8_21: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -367,9 +515,13 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // 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: 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:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc11_8.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:   %.loc11_8.2: type = converted %int.make_type_32.loc11, %.loc11_8.1 [template = i32]
+// CHECK:STDOUT:   %Negate.ref.loc11_14: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.3]
+// CHECK:STDOUT:   %Negate.ref.loc11_25: Negate = name_ref Negate, %Negate.decl [template = constants.%struct.2]
 // 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]
@@ -384,6 +536,8 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %b.loc11: i32 = bind_name b, %.loc11_48.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Negate(%a: i32) -> i32 = "int.unegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.usub";

+ 79 - 15
toolchain/check/testdata/builtins/int/usub.carbon

@@ -28,16 +28,18 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- int_sub.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -48,40 +50,74 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.usub";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.ref: Sub = name_ref Sub, file.%Sub.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:   %int.usub: init i32 = call %Sub.ref(%a.ref, %b.ref)
@@ -93,9 +129,11 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT: --- overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Sub: type = fn_type @Sub [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: Sub = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = 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 0 [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 2147483647 [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal -2147483647 [template]
@@ -110,22 +148,42 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:     .Sub = %Sub.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Sub.decl: Sub = fn_decl @Sub [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc4_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_11.1: type = value_of_initializer %int.make_type_32.loc4_11 [template = i32]
+// CHECK:STDOUT:     %.loc4_11.2: type = converted %int.make_type_32.loc4_11, %.loc4_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc4_8.1: i32 = param a
 // CHECK:STDOUT:     @Sub.%a: i32 = bind_name a, %a.loc4_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_19.1: type = value_of_initializer %int.make_type_32.loc4_19 [template = i32]
+// CHECK:STDOUT:     %.loc4_19.2: type = converted %int.make_type_32.loc4_19, %.loc4_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc4_16.1: i32 = param b
 // CHECK:STDOUT:     @Sub.%b: i32 = bind_name b, %b.loc4_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc4_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc4_27.1: type = value_of_initializer %int.make_type_32.loc4_27 [template = i32]
+// CHECK:STDOUT:     %.loc4_27.2: type = converted %int.make_type_32.loc4_27, %.loc4_27.1 [template = i32]
 // CHECK:STDOUT:     @Sub.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_8.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_8.2: type = converted %int.make_type_32.loc6, %.loc6_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc6: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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: 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_8.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_8.2: type = converted %int.make_type_32.loc7, %.loc7_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc7_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc7_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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]
@@ -136,8 +194,12 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // 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: 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:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_8.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_8.2: type = converted %int.make_type_32.loc8, %.loc8_8.1 [template = i32]
+// CHECK:STDOUT:   %Sub.ref.loc8_14: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %Sub.ref.loc8_18: Sub = name_ref Sub, %Sub.decl [template = constants.%struct.2]
 // 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]
@@ -150,5 +212,7 @@ let c: i32 = Sub(Sub(0, 0x7FFFFFFF), 2);
 // CHECK:STDOUT:   %c: i32 = bind_name c, %.loc8_40.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Sub(%a: i32, %b: i32) -> i32 = "int.usub";
 // CHECK:STDOUT:

+ 43 - 7
toolchain/check/testdata/builtins/int/xor.carbon

@@ -18,16 +18,18 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT: --- int_xor.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %Xor: type = fn_type @Xor [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: Xor = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %Xor: type = fn_type @Xor [template]
+// CHECK:STDOUT:   %struct.2: 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:   %struct.3: RuntimeCall = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -38,40 +40,74 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 // CHECK:STDOUT:     .RuntimeCall = %RuntimeCall.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %Xor.decl: Xor = fn_decl @Xor [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Xor.decl: Xor = fn_decl @Xor [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc2_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_11.1: type = value_of_initializer %int.make_type_32.loc2_11 [template = i32]
+// CHECK:STDOUT:     %.loc2_11.2: type = converted %int.make_type_32.loc2_11, %.loc2_11.1 [template = i32]
 // CHECK:STDOUT:     %a.loc2_8.1: i32 = param a
 // CHECK:STDOUT:     @Xor.%a: i32 = bind_name a, %a.loc2_8.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_19.1: type = value_of_initializer %int.make_type_32.loc2_19 [template = i32]
+// CHECK:STDOUT:     %.loc2_19.2: type = converted %int.make_type_32.loc2_19, %.loc2_19.1 [template = i32]
 // CHECK:STDOUT:     %b.loc2_16.1: i32 = param b
 // CHECK:STDOUT:     @Xor.%b: i32 = bind_name b, %b.loc2_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc2_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc2_27.1: type = value_of_initializer %int.make_type_32.loc2_27 [template = i32]
+// CHECK:STDOUT:     %.loc2_27.2: type = converted %int.make_type_32.loc2_27, %.loc2_27.1 [template = i32]
 // CHECK:STDOUT:     @Xor.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, %Xor.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc4: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, %Xor.decl [template = constants.%struct.2]
 // 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_11.1: type = value_of_initializer %int.make_type_32.loc4 [template = i32]
+// CHECK:STDOUT:   %.loc4_11.2: type = converted %int.make_type_32.loc4, %.loc4_11.1 [template = i32]
 // 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:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
 // CHECK:STDOUT:   %.loc5_18: i32 = int_literal 6 [template = constants.%.4]
+// CHECK:STDOUT:   %.loc5_13.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_13.2: type = converted %int.make_type_32.loc5, %.loc5_13.1 [template = i32]
 // 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.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %RuntimeCall.decl: RuntimeCall = fn_decl @RuntimeCall [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc7_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_19.1: type = value_of_initializer %int.make_type_32.loc7_19 [template = i32]
+// CHECK:STDOUT:     %.loc7_19.2: type = converted %int.make_type_32.loc7_19, %.loc7_19.1 [template = i32]
 // CHECK:STDOUT:     %a.loc7_16.1: i32 = param a
 // CHECK:STDOUT:     @RuntimeCall.%a: i32 = bind_name a, %a.loc7_16.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_27.1: type = value_of_initializer %int.make_type_32.loc7_27 [template = i32]
+// CHECK:STDOUT:     %.loc7_27.2: type = converted %int.make_type_32.loc7_27, %.loc7_27.1 [template = i32]
 // CHECK:STDOUT:     %b.loc7_24.1: i32 = param b
 // CHECK:STDOUT:     @RuntimeCall.%b: i32 = bind_name b, %b.loc7_24.1
+// CHECK:STDOUT:     %int.make_type_32.loc7_35: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc7_35.1: type = value_of_initializer %int.make_type_32.loc7_35 [template = i32]
+// CHECK:STDOUT:     %.loc7_35.2: type = converted %int.make_type_32.loc7_35, %.loc7_35.1 [template = i32]
 // CHECK:STDOUT:     @RuntimeCall.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Xor(%a: i32, %b: i32) -> i32 = "int.xor";
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @RuntimeCall(%a: i32, %b: i32) -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, file.%Xor.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %Xor.ref: Xor = name_ref Xor, file.%Xor.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:   %int.xor: init i32 = call %Xor.ref(%a.ref, %b.ref)

+ 29 - 8
toolchain/check/testdata/class/adapt.carbon

@@ -45,10 +45,13 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type SomeClass, i32 [template]
+// CHECK:STDOUT:   %.3: 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:   %.4: type = ptr_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %StructAdapter: type = class_type @StructAdapter [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -61,18 +64,28 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %SomeClass.decl: type = class_decl @SomeClass [template = constants.%SomeClass] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %SomeClassAdapter.decl: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
 // CHECK:STDOUT:   %StructAdapter.decl: type = class_decl @StructAdapter [template = constants.%StructAdapter] {}
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClass {
-// CHECK:STDOUT:   %.loc5: <unbound element of class SomeClass> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc6: <unbound element of class SomeClass> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32.loc5, %.loc5_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc5_8: <unbound element of class SomeClass> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc6_8: <unbound element of class SomeClass> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%SomeClass
-// CHECK:STDOUT:   .a = %.loc5
-// CHECK:STDOUT:   .b = %.loc6
+// CHECK:STDOUT:   .a = %.loc5_8
+// CHECK:STDOUT:   .b = %.loc6_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClassAdapter {
@@ -84,13 +97,21 @@ fn F(a: AdaptNotExtend) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @StructAdapter {
-// CHECK:STDOUT:   %.loc14: type = struct_type {.a: i32, .b: i32} [template = constants.%.2]
+// CHECK:STDOUT:   %int.make_type_32.loc14_14: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc14_14.1: type = value_of_initializer %int.make_type_32.loc14_14 [template = i32]
+// CHECK:STDOUT:   %.loc14_14.2: type = converted %int.make_type_32.loc14_14, %.loc14_14.1 [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc14_23: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc14_23.1: type = value_of_initializer %int.make_type_32.loc14_23 [template = i32]
+// CHECK:STDOUT:   %.loc14_23.2: type = converted %int.make_type_32.loc14_23, %.loc14_23.1 [template = i32]
+// CHECK:STDOUT:   %.loc14_26: type = struct_type {.a: i32, .b: i32} [template = constants.%.3]
 // CHECK:STDOUT:   adapt_decl {.a: i32, .b: i32}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%StructAdapter
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_not_extend.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {

+ 45 - 25
toolchain/check/testdata/class/base.carbon

@@ -26,28 +26,30 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Base, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.b: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.b: i32} [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.b: i32} [template]
-// 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:   %.4: type = ptr_type {.b: i32} [template]
+// CHECK:STDOUT:   %.5: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.base: Base, .d: 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:   %struct.2: 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:   %struct.3: Base = struct_value (%.11) [template]
+// CHECK:STDOUT:   %struct.4: Derived = struct_value (%struct.3, %.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:   %struct.5: Access = struct_value () [template]
 // CHECK:STDOUT:   %.16: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -61,41 +63,59 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.2] {
 // 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.decl: Access = fn_decl @Access [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct.5] {
 // 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.%.15 [template = constants.%.15]
+// CHECK:STDOUT:     %int.make_type_32.loc21_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %int.make_type_32.loc21_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc21_35.1: (type, type) = tuple_literal (%int.make_type_32.loc21_27, %int.make_type_32.loc21_32)
+// CHECK:STDOUT:     %.loc21_35.2: type = value_of_initializer %int.make_type_32.loc21_27 [template = i32]
+// CHECK:STDOUT:     %.loc21_35.3: type = converted %int.make_type_32.loc21_27, %.loc21_35.2 [template = i32]
+// CHECK:STDOUT:     %.loc21_35.4: type = value_of_initializer %int.make_type_32.loc21_32 [template = i32]
+// CHECK:STDOUT:     %.loc21_35.5: type = converted %int.make_type_32.loc21_32, %.loc21_35.4 [template = i32]
+// CHECK:STDOUT:     %.loc21_35.6: type = converted %.loc21_35.1, constants.%.15 [template = constants.%.15]
 // CHECK:STDOUT:     @Access.%return: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl b, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Base> = field_decl b, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .b = %.loc8
+// CHECK:STDOUT:   .b = %.loc8_8
 // 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:   %.loc14: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc14_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc14_10.2: type = converted %int.make_type_32, %.loc14_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc14_8: <unbound element of class Derived> = field_decl d, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
-// CHECK:STDOUT:   .d = %.loc14
+// CHECK:STDOUT:   .d = %.loc14_8
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4 [template = constants.%.11]
@@ -105,26 +125,26 @@ fn Access(d: Derived) -> (i32, i32) {
 // 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.%.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_26.4: init Base = class_init (%.loc18_26.3), %.loc18_35.2 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc18_35.3: init Base = converted %.loc18_26.1, %.loc18_26.4 [template = constants.%struct.3]
 // 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.%.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:   %.loc18_35.6: init Derived = class_init (%.loc18_35.3, %.loc18_35.5), %return [template = constants.%struct.4]
+// CHECK:STDOUT:   %.loc18_36: init Derived = converted %.loc18_35.1, %.loc18_35.6 [template = constants.%struct.4]
 // CHECK:STDOUT:   return %.loc18_36 to %return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Access(%d: Derived) -> %return: (i32, i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %d.ref.loc22_11: Derived = name_ref d, %d
-// CHECK:STDOUT:   %d.ref.loc22_12: <unbound element of class Derived> = name_ref d, @Derived.%.loc14 [template = @Derived.%.loc14]
+// CHECK:STDOUT:   %d.ref.loc22_12: <unbound element of class Derived> = name_ref d, @Derived.%.loc14_8 [template = @Derived.%.loc14_8]
 // CHECK:STDOUT:   %.loc22_12.1: ref i32 = class_element_access %d.ref.loc22_11, element1
 // CHECK:STDOUT:   %.loc22_12.2: i32 = bind_value %.loc22_12.1
 // CHECK:STDOUT:   %d.ref.loc22_16: Derived = name_ref d, %d
 // CHECK:STDOUT:   %base.ref: <unbound element of class Derived> = name_ref base, @Derived.%.loc12 [template = @Derived.%.loc12]
 // CHECK:STDOUT:   %.loc22_17.1: ref Base = class_element_access %d.ref.loc22_16, element0
 // CHECK:STDOUT:   %.loc22_17.2: Base = bind_value %.loc22_17.1
-// CHECK:STDOUT:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc8 [template = @Base.%.loc8]
+// CHECK:STDOUT:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc8_8 [template = @Base.%.loc8_8]
 // CHECK:STDOUT:   %.loc22_22.1: ref i32 = class_element_access %.loc22_17.2, element0
 // CHECK:STDOUT:   %.loc22_22.2: i32 = bind_value %.loc22_22.1
 // CHECK:STDOUT:   %.loc22_24.1: (i32, i32) = tuple_literal (%.loc22_12.2, %.loc22_22.2)

+ 52 - 24
toolchain/check/testdata/class/base_field.carbon

@@ -25,18 +25,20 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Base, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32, .b: i32, .c: i32} [template]
-// 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 = ptr_type Derived [template]
-// CHECK:STDOUT:   %.8: type = ptr_type i32 [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.5: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.base: Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.8: type = ptr_type Derived [template]
+// CHECK:STDOUT:   %.9: type = ptr_type 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:   %struct.2: 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]
@@ -51,48 +53,74 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct.2] {
 // 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:     %.loc20_21: type = ptr_type Derived [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc20_11.1: Derived* = param p
 // CHECK:STDOUT:     @Access.%p: Derived* = bind_name p, %p.loc20_11.1
-// CHECK:STDOUT:     %.loc20_30: type = ptr_type i32 [template = constants.%.8]
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc20_30.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc20_30.2: type = converted %int.make_type_32, %.loc20_30.1 [template = i32]
+// CHECK:STDOUT:     %.loc20_30.3: type = ptr_type i32 [template = constants.%.9]
 // CHECK:STDOUT:     @Access.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc9: <unbound element of class Base> = field_decl b, element1 [template]
-// CHECK:STDOUT:   %.loc10: <unbound element of class Base> = field_decl c, element2 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32.loc8, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_10.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %int.make_type_32.loc9, %.loc9_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc9_8: <unbound element of class Base> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_10.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_10.2: type = converted %int.make_type_32.loc10, %.loc10_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc10_8: <unbound element of class Base> = field_decl c, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .a = %.loc8
-// CHECK:STDOUT:   .b = %.loc9
-// CHECK:STDOUT:   .c = %.loc10
+// CHECK:STDOUT:   .a = %.loc8_8
+// CHECK:STDOUT:   .b = %.loc9_8
+// CHECK:STDOUT:   .c = %.loc10_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc14: <unbound element of class Derived> = base_decl Base, element0 [template]
-// CHECK:STDOUT:   %.loc16: <unbound element of class Derived> = field_decl d, element1 [template]
-// CHECK:STDOUT:   %.loc17: <unbound element of class Derived> = field_decl e, element2 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc16: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc16_10.1: type = value_of_initializer %int.make_type_32.loc16 [template = i32]
+// CHECK:STDOUT:   %.loc16_10.2: type = converted %int.make_type_32.loc16, %.loc16_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc16_8: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_10.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
+// CHECK:STDOUT:   %.loc17_10.2: type = converted %int.make_type_32.loc17, %.loc17_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc17_8: <unbound element of class Derived> = field_decl e, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc14
-// CHECK:STDOUT:   .d = %.loc16
-// CHECK:STDOUT:   .e = %.loc17
+// CHECK:STDOUT:   .d = %.loc16_8
+// CHECK:STDOUT:   .e = %.loc17_8
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Access(%p: Derived*) -> i32* {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Derived* = name_ref p, %p
 // CHECK:STDOUT:   %.loc21_12: ref Derived = deref %p.ref
-// CHECK:STDOUT:   %c.ref: <unbound element of class Base> = name_ref c, @Base.%.loc10 [template = @Base.%.loc10]
+// CHECK:STDOUT:   %c.ref: <unbound element of class Base> = name_ref c, @Base.%.loc10_8 [template = @Base.%.loc10_8]
 // CHECK:STDOUT:   %.loc21_15.1: ref Base = class_element_access %.loc21_12, element0
 // CHECK:STDOUT:   %.loc21_15.2: ref Base = converted %.loc21_12, %.loc21_15.1
 // CHECK:STDOUT:   %.loc21_15.3: ref i32 = class_element_access %.loc21_15.2, element2

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

@@ -26,11 +26,13 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.3: type = ptr_type Base [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:   %struct.2: 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]
@@ -39,7 +41,7 @@ fn Call(p: Derived*) {
 // 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:   %struct.3: 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: }
@@ -53,15 +55,16 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // 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:     %.loc13_26: type = ptr_type Base [template = constants.%.3]
 // CHECK:STDOUT:     %self.loc13_16.1: Base* = param self
 // CHECK:STDOUT:     @F.%self: Base* = bind_name self, %self.loc13_16.1
 // 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.decl: Call = fn_decl @Call [template = constants.%struct.2] {
+// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Derived.ref: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // CHECK:STDOUT:     %.loc21: type = ptr_type Derived [template = constants.%.9]
 // CHECK:STDOUT:     %p.loc21_9.1: Derived* = param p
@@ -70,10 +73,13 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // 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:     %.loc10_23: type = ptr_type Base [template = constants.%.3]
 // CHECK:STDOUT:     %self.loc10_13.1: Base* = param self
 // CHECK:STDOUT:     %self.loc10_13.3: Base* = bind_name self, %self.loc10_13.1
 // CHECK:STDOUT:     %.loc10_8: Base* = addr_pattern %self.loc10_13.3
@@ -81,7 +87,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .a = %.loc8
+// CHECK:STDOUT:   .a = %.loc8_8
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -95,11 +101,13 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F[addr %self: Base*]() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %self.ref: Base* = name_ref self, %self
 // 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:   %a.ref: <unbound element of class Base> = name_ref a, @Base.%.loc8_8 [template = @Base.%.loc8_8]
 // CHECK:STDOUT:   %.loc14_10: ref i32 = class_element_access %.loc14_4, element0
 // CHECK:STDOUT:   %.loc14_15: i32 = int_literal 1 [template = constants.%.6]
 // CHECK:STDOUT:   assign %.loc14_10, %.loc14_15
@@ -110,7 +118,7 @@ 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: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.2]
 // 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

+ 51 - 23
toolchain/check/testdata/class/base_method_qualified.carbon

@@ -39,30 +39,32 @@ 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:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %F.1: type = fn_type @F.1 [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %G.1: type = fn_type @G.1 [template]
-// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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:   %struct.4: F = struct_value () [template]
 // CHECK:STDOUT:   %G.2: type = fn_type @G.2 [template]
-// CHECK:STDOUT:   %struct.4: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: 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:   %struct.6: 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:   %struct.7: CallIndirect = struct_value () [template]
 // CHECK:STDOUT:   %PassDerivedToBase: type = fn_type @PassDerivedToBase [template]
-// CHECK:STDOUT:   %struct.7: PassDerivedToBase = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: PassDerivedToBase = struct_value () [template]
 // CHECK:STDOUT:   %PassDerivedToBaseIndirect: type = fn_type @PassDerivedToBaseIndirect [template]
-// CHECK:STDOUT:   %struct.8: PassDerivedToBaseIndirect = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: PassDerivedToBaseIndirect = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -78,31 +80,49 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // 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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Derived.decl.loc14: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Call.decl: Call = fn_decl @Call [template = constants.%struct.6] {
 // 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:     %int.make_type_32.loc21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc21_24.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
+// CHECK:STDOUT:     %.loc21_24.2: type = converted %int.make_type_32.loc21, %.loc21_24.1 [template = i32]
 // CHECK:STDOUT:     @Call.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %CallIndirect.decl: CallIndirect = fn_decl @CallIndirect [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %CallIndirect.decl: CallIndirect = fn_decl @CallIndirect [template = constants.%struct.7] {
 // 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:     %.loc25_27: 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:     %int.make_type_32.loc25: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc25_33.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
+// CHECK:STDOUT:     %.loc25_33.2: type = converted %int.make_type_32.loc25, %.loc25_33.1 [template = i32]
 // CHECK:STDOUT:     @CallIndirect.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %PassDerivedToBase.decl: PassDerivedToBase = fn_decl @PassDerivedToBase [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %PassDerivedToBase.decl: PassDerivedToBase = fn_decl @PassDerivedToBase [template = constants.%struct.8] {
 // 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:     %int.make_type_32.loc29: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc29_37.1: type = value_of_initializer %int.make_type_32.loc29 [template = i32]
+// CHECK:STDOUT:     %.loc29_37.2: type = converted %int.make_type_32.loc29, %.loc29_37.1 [template = i32]
 // CHECK:STDOUT:     @PassDerivedToBase.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %PassDerivedToBaseIndirect.decl: PassDerivedToBaseIndirect = fn_decl @PassDerivedToBaseIndirect [template = constants.%struct.8] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %PassDerivedToBaseIndirect.decl: PassDerivedToBaseIndirect = fn_decl @PassDerivedToBaseIndirect [template = constants.%struct.9] {
 // 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:     %.loc33_40: type = ptr_type Derived [template = constants.%.8]
 // CHECK:STDOUT:     %p.loc33_30.1: Derived* = param p
 // CHECK:STDOUT:     @PassDerivedToBaseIndirect.%p: Derived* = bind_name p, %p.loc33_30.1
+// CHECK:STDOUT:     %int.make_type_32.loc33: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc33_46.1: type = value_of_initializer %int.make_type_32.loc33 [template = i32]
+// CHECK:STDOUT:     %.loc33_46.2: type = converted %int.make_type_32.loc33, %.loc33_46.1 [template = i32]
 // CHECK:STDOUT:     @PassDerivedToBaseIndirect.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -110,12 +130,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.decl: F = fn_decl @F.2 [template = constants.%struct.3] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.2 [template = constants.%struct.4] {
 // 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.decl: G = fn_decl @G.2 [template = constants.%struct.4] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G.2 [template = constants.%struct.5] {
 // 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
@@ -130,16 +150,22 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.1] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F.1 [template = constants.%struct.2] {
 // 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:     %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc10_25.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:     %.loc10_25.2: type = converted %int.make_type_32.loc10, %.loc10_25.1 [template = i32]
 // CHECK:STDOUT:     %return.var.loc10: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G.1 [template = constants.%struct.2] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G.1 [template = constants.%struct.3] {
 // 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
+// CHECK:STDOUT:     %int.make_type_32.loc11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc11_28.1: type = value_of_initializer %int.make_type_32.loc11 [template = i32]
+// CHECK:STDOUT:     %.loc11_28.2: type = converted %int.make_type_32.loc11, %.loc11_28.1 [template = i32]
 // CHECK:STDOUT:     %return.var.loc11: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
@@ -149,6 +175,8 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 {
 // CHECK:STDOUT:   .G = %G.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1[@Base.%self.loc10_8.2: Base]() -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G.1[@Base.%self.loc11_8.2: Derived]() -> i32;
@@ -161,7 +189,7 @@ 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: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.2]
 // 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
@@ -176,7 +204,7 @@ 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: F = name_ref F, @Base.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Base.%F.decl [template = constants.%struct.2]
 // 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
@@ -192,7 +220,7 @@ 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: G = name_ref G, @Base.%G.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %G.ref: G = name_ref G, @Base.%G.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc30_11: <bound method> = bound_method %a.ref, %G.ref
 // CHECK:STDOUT:   %G.call: init i32 = call %.loc30_11(%a.ref)
 // CHECK:STDOUT:   %.loc30_22.1: i32 = value_of_initializer %G.call
@@ -204,7 +232,7 @@ 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: G = name_ref G, @Base.%G.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %G.ref: G = name_ref G, @Base.%G.decl [template = constants.%struct.3]
 // 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

+ 47 - 11
toolchain/check/testdata/class/basic.carbon

@@ -26,15 +26,17 @@ fn Run() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
-// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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:   %struct.4: Run = struct_value () [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 4 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -46,36 +48,70 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc17_15: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc17_15.1: type = value_of_initializer %int.make_type_32.loc17_15 [template = i32]
+// CHECK:STDOUT:     %.loc17_15.2: type = converted %int.make_type_32.loc17_15, %.loc17_15.1 [template = i32]
 // CHECK:STDOUT:     %n.loc17_12.1: i32 = param n
 // CHECK:STDOUT:     @G.%n: i32 = bind_name n, %n.loc17_12.1
+// CHECK:STDOUT:     %int.make_type_32.loc17_23: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc17_23.1: type = value_of_initializer %int.make_type_32.loc17_23 [template = i32]
+// CHECK:STDOUT:     %.loc17_23.2: type = converted %int.make_type_32.loc17_23, %.loc17_23.1 [template = i32]
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Run.decl: Run = fn_decl @Run [template = constants.%struct.4] {
+// CHECK:STDOUT:     %int.make_type_32.loc21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc21_13.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
+// CHECK:STDOUT:     %.loc21_13.2: type = converted %int.make_type_32.loc21, %.loc21_13.1 [template = i32]
 // CHECK:STDOUT:     @Run.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc8_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_11.1: type = value_of_initializer %int.make_type_32.loc8_11 [template = i32]
+// CHECK:STDOUT:     %.loc8_11.2: type = converted %int.make_type_32.loc8_11, %.loc8_11.1 [template = i32]
 // 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:     %int.make_type_32.loc8_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_19.1: type = value_of_initializer %int.make_type_32.loc8_19 [template = i32]
+// CHECK:STDOUT:     %.loc8_19.2: type = converted %int.make_type_32.loc8_19, %.loc8_19.1 [template = i32]
 // CHECK:STDOUT:     %return.var.loc8: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32.loc12_11: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_11.1: type = value_of_initializer %int.make_type_32.loc12_11 [template = i32]
+// CHECK:STDOUT:     %.loc12_11.2: type = converted %int.make_type_32.loc12_11, %.loc12_11.1 [template = i32]
 // 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:     %int.make_type_32.loc12_19: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc12_19.1: type = value_of_initializer %int.make_type_32.loc12_19 [template = i32]
+// CHECK:STDOUT:     %.loc12_19.2: type = converted %int.make_type_32.loc12_19, %.loc12_19.1 [template = i32]
 // CHECK:STDOUT:     %return.var.loc12: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc14: <unbound element of class Class> = field_decl k, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc14: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc14_10.1: type = value_of_initializer %int.make_type_32.loc14 [template = i32]
+// CHECK:STDOUT:   %.loc14_10.2: type = converted %int.make_type_32.loc14, %.loc14_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc14_8: <unbound element of class Class> = field_decl k, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   .G = %G.decl
-// CHECK:STDOUT:   .k = %.loc14
+// CHECK:STDOUT:   .k = %.loc14_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(@Class.%n.loc8_8.2: i32) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: i32 = name_ref n, @Class.%n.loc8_8.2
@@ -91,7 +127,7 @@ 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: F = name_ref F, @Class.%F.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.ref: F = name_ref F, @Class.%F.decl [template = constants.%struct.2]
 // 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

+ 18 - 6
toolchain/check/testdata/class/complete_in_member_fn.carbon

@@ -14,9 +14,11 @@ class C {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [template]
-// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: 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]
@@ -29,27 +31,37 @@ class C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // 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
+// CHECK:STDOUT:     %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_17.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:     %.loc8_17.2: type = converted %int.make_type_32.loc8, %.loc8_17.1 [template = i32]
 // CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %.loc10: <unbound element of class C> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_10.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_10.2: type = converted %int.make_type_32.loc10, %.loc10_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc10_8: <unbound element of class C> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .F = %F.decl
-// CHECK:STDOUT:   .a = %.loc10
+// CHECK:STDOUT:   .a = %.loc10_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(@C.%c.loc8_8.2: C) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %c.ref: C = name_ref c, @C.%c.loc8_8.2
-// CHECK:STDOUT:   %a.ref: <unbound element of class C> = name_ref a, @C.%.loc10 [template = @C.%.loc10]
+// CHECK:STDOUT:   %a.ref: <unbound element of class C> = name_ref a, @C.%.loc10_8 [template = @C.%.loc10_8]
 // CHECK:STDOUT:   %.loc8_31.1: ref i32 = class_element_access %c.ref, element0
 // CHECK:STDOUT:   %.loc8_31.2: i32 = bind_value %.loc8_31.1
 // CHECK:STDOUT:   return %.loc8_31.2

+ 71 - 31
toolchain/check/testdata/class/compound_field.carbon

@@ -37,27 +37,29 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Base, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32, .b: i32, .c: i32} [template]
-// 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:   %.4: type = ptr_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.5: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.base: Base, .d: i32, .e: 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:   %struct.2: 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:   %struct.3: 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:   %struct.4: AccessDerivedIndirect = struct_value () [template]
 // CHECK:STDOUT:   %AccessBaseIndirect: type = fn_type @AccessBaseIndirect [template]
-// CHECK:STDOUT:   %struct.4: AccessBaseIndirect = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: AccessBaseIndirect = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -72,68 +74,106 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %AccessDerived.decl: AccessDerived = fn_decl @AccessDerived [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessDerived.decl: AccessDerived = fn_decl @AccessDerived [template = constants.%struct.2] {
 // 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:     %int.make_type_32.loc20: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc20_33.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
+// CHECK:STDOUT:     %.loc20_33.2: type = converted %int.make_type_32.loc20, %.loc20_33.1 [template = i32]
 // CHECK:STDOUT:     @AccessDerived.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessBase.decl: AccessBase = fn_decl @AccessBase [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessBase.decl: AccessBase = fn_decl @AccessBase [template = constants.%struct.3] {
 // 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:     %int.make_type_32.loc24: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc24_30.1: type = value_of_initializer %int.make_type_32.loc24 [template = i32]
+// CHECK:STDOUT:     %.loc24_30.2: type = converted %int.make_type_32.loc24, %.loc24_30.1 [template = i32]
 // CHECK:STDOUT:     @AccessBase.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessDerivedIndirect.decl: AccessDerivedIndirect = fn_decl @AccessDerivedIndirect [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessDerivedIndirect.decl: AccessDerivedIndirect = fn_decl @AccessDerivedIndirect [template = constants.%struct.4] {
 // CHECK:STDOUT:     %Derived.ref.loc28: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // 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.%.12]
+// CHECK:STDOUT:     %int.make_type_32.loc28: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc28_45.1: type = value_of_initializer %int.make_type_32.loc28 [template = i32]
+// CHECK:STDOUT:     %.loc28_45.2: type = converted %int.make_type_32.loc28, %.loc28_45.1 [template = i32]
+// CHECK:STDOUT:     %.loc28_45.3: type = ptr_type i32 [template = constants.%.12]
 // CHECK:STDOUT:     @AccessDerivedIndirect.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessBaseIndirect.decl: AccessBaseIndirect = fn_decl @AccessBaseIndirect [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessBaseIndirect.decl: AccessBaseIndirect = fn_decl @AccessBaseIndirect [template = constants.%struct.5] {
 // CHECK:STDOUT:     %Derived.ref.loc32: type = name_ref Derived, %Derived.decl [template = constants.%Derived]
 // 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.%.12]
+// CHECK:STDOUT:     %int.make_type_32.loc32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc32_42.1: type = value_of_initializer %int.make_type_32.loc32 [template = i32]
+// CHECK:STDOUT:     %.loc32_42.2: type = converted %int.make_type_32.loc32, %.loc32_42.1 [template = i32]
+// CHECK:STDOUT:     %.loc32_42.3: type = ptr_type i32 [template = constants.%.12]
 // CHECK:STDOUT:     @AccessBaseIndirect.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc9: <unbound element of class Base> = field_decl b, element1 [template]
-// CHECK:STDOUT:   %.loc10: <unbound element of class Base> = field_decl c, element2 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32.loc8, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_10.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %int.make_type_32.loc9, %.loc9_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc9_8: <unbound element of class Base> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc10: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc10_10.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32]
+// CHECK:STDOUT:   %.loc10_10.2: type = converted %int.make_type_32.loc10, %.loc10_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc10_8: <unbound element of class Base> = field_decl c, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
-// CHECK:STDOUT:   .a = %.loc8
-// CHECK:STDOUT:   .b = %.loc9
-// CHECK:STDOUT:   .c = %.loc10
+// CHECK:STDOUT:   .a = %.loc8_8
+// CHECK:STDOUT:   .b = %.loc9_8
+// CHECK:STDOUT:   .c = %.loc10_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc14: <unbound element of class Derived> = base_decl Base, element0 [template]
-// CHECK:STDOUT:   %.loc16: <unbound element of class Derived> = field_decl d, element1 [template]
-// CHECK:STDOUT:   %.loc17: <unbound element of class Derived> = field_decl e, element2 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc16: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc16_10.1: type = value_of_initializer %int.make_type_32.loc16 [template = i32]
+// CHECK:STDOUT:   %.loc16_10.2: type = converted %int.make_type_32.loc16, %.loc16_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc16_8: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc17: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_10.1: type = value_of_initializer %int.make_type_32.loc17 [template = i32]
+// CHECK:STDOUT:   %.loc17_10.2: type = converted %int.make_type_32.loc17, %.loc17_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc17_8: <unbound element of class Derived> = field_decl e, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc14
-// CHECK:STDOUT:   .d = %.loc16
-// CHECK:STDOUT:   .e = %.loc17
+// CHECK:STDOUT:   .d = %.loc16_8
+// CHECK:STDOUT:   .e = %.loc17_8
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @AccessDerived(%d: Derived) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %d.ref.loc21_10: Derived = name_ref d, %d
 // CHECK:STDOUT:   %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:   %d.ref.loc21_20: <unbound element of class Derived> = name_ref d, @Derived.%.loc16 [template = @Derived.%.loc16]
+// CHECK:STDOUT:   %d.ref.loc21_20: <unbound element of class Derived> = name_ref d, @Derived.%.loc16_8 [template = @Derived.%.loc16_8]
 // CHECK:STDOUT:   %.loc21_11.1: ref i32 = class_element_access %d.ref.loc21_10, element1
 // CHECK:STDOUT:   %.loc21_11.2: i32 = bind_value %.loc21_11.1
 // CHECK:STDOUT:   return %.loc21_11.2
@@ -143,7 +183,7 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %d.ref: Derived = name_ref d, %d
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
-// CHECK:STDOUT:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc9 [template = @Base.%.loc9]
+// CHECK:STDOUT:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc9_8 [template = @Base.%.loc9_8]
 // CHECK:STDOUT:   %.loc25_11.1: ref Base = class_element_access %d.ref, element0
 // CHECK:STDOUT:   %.loc25_11.2: ref Base = converted %d.ref, %.loc25_11.1
 // CHECK:STDOUT:   %.loc25_11.3: ref i32 = class_element_access %.loc25_11.2, element1
@@ -155,7 +195,7 @@ fn AccessBaseIndirect(p: Derived*) -> i32* {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Derived* = name_ref p, %p
 // CHECK:STDOUT:   %Derived.ref: type = name_ref Derived, file.%Derived.decl [template = constants.%Derived]
-// CHECK:STDOUT:   %d.ref: <unbound element of class Derived> = name_ref d, @Derived.%.loc16 [template = @Derived.%.loc16]
+// CHECK:STDOUT:   %d.ref: <unbound element of class Derived> = name_ref d, @Derived.%.loc16_8 [template = @Derived.%.loc16_8]
 // CHECK:STDOUT:   %.loc29_12.1: ref Derived = deref %p.ref
 // CHECK:STDOUT:   %.loc29_12.2: ref i32 = class_element_access %.loc29_12.1, element1
 // CHECK:STDOUT:   %.loc29_10: i32* = addr_of %.loc29_12.2
@@ -166,7 +206,7 @@ fn AccessBaseIndirect(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:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc9 [template = @Base.%.loc9]
+// CHECK:STDOUT:   %b.ref: <unbound element of class Base> = name_ref b, @Base.%.loc9_8 [template = @Base.%.loc9_8]
 // CHECK:STDOUT:   %.loc33_12.1: ref Derived = deref %p.ref
 // CHECK:STDOUT:   %.loc33_12.2: ref Base = class_element_access %.loc33_12.1, element0
 // CHECK:STDOUT:   %.loc33_12.3: ref Base = converted %.loc33_12.1, %.loc33_12.2

+ 9 - 9
toolchain/check/testdata/class/cross_package_import.carbon

@@ -184,8 +184,8 @@ var c: Other.C = {};
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir7, inst+2, loaded [template = constants.%C]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir7, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir8, inst+2, loaded [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir8, inst+3, unloaded
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref C = var c
 // CHECK:STDOUT:   %c: ref C = bind_name c, %c.var
@@ -221,7 +221,7 @@ var c: Other.C = {};
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref: type = import_ref ir7, inst+2, loaded [template = constants.%C]
+// CHECK:STDOUT:   %import_ref: type = import_ref ir8, inst+2, loaded [template = constants.%C]
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref <error> = var c
 // CHECK:STDOUT:   %c: ref <error> = bind_name c, %c.var
@@ -255,9 +255,9 @@ var c: Other.C = {};
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir7, inst+2, loaded [template = constants.%C]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir7, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir8, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir8, inst+2, loaded [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir8, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir9, inst+2, unloaded
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref C = var c
 // CHECK:STDOUT:   %c: ref C = bind_name c, %c.var
@@ -296,9 +296,9 @@ var c: Other.C = {};
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir7, inst+2, loaded [template = constants.%C]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir7, inst+3, unloaded
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir8, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir8, inst+2, loaded [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir8, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir9, inst+2, unloaded
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref C = var c
 // CHECK:STDOUT:   %c: ref C = bind_name c, %c.var

+ 62 - 46
toolchain/check/testdata/class/derived_to_base.carbon

@@ -38,47 +38,49 @@ fn ConvertInit() {
 // CHECK:STDOUT:
 // 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 {.a: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %B: type = class_type @B [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32} [template]
-// CHECK:STDOUT:   %.4: type = unbound_element_type B, A [template]
-// CHECK:STDOUT:   %.5: type = unbound_element_type B, i32 [template]
-// CHECK:STDOUT:   %.6: type = struct_type {.base: A, .b: i32} [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.5: type = unbound_element_type B, A [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type B, i32 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.base: A, .b: i32} [template]
 // CHECK:STDOUT:   %C: type = class_type @C [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: {.a: i32}*, .b: i32} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type {.base: {.a: i32}*, .b: i32} [template]
-// CHECK:STDOUT:   %.9: type = ptr_type {.base: A, .b: i32} [template]
-// CHECK:STDOUT:   %.10: type = unbound_element_type C, B [template]
-// CHECK:STDOUT:   %.11: type = unbound_element_type C, i32 [template]
-// 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:   %.8: type = struct_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.10: type = ptr_type {.base: A, .b: i32} [template]
+// CHECK:STDOUT:   %.11: type = unbound_element_type C, B [template]
+// CHECK:STDOUT:   %.12: type = unbound_element_type C, i32 [template]
+// CHECK:STDOUT:   %.13: type = struct_type {.base: B, .c: i32} [template]
+// CHECK:STDOUT:   %.14: type = ptr_type C [template]
+// CHECK:STDOUT:   %.15: type = ptr_type B [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:   %struct.2: 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:   %struct.3: ConvertBToA = struct_value () [template]
 // CHECK:STDOUT:   %ConvertCToA: type = fn_type @ConvertCToA [template]
-// CHECK:STDOUT:   %struct.3: ConvertCToA = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: ConvertCToA = struct_value () [template]
 // CHECK:STDOUT:   %ConvertValue: type = fn_type @ConvertValue [template]
-// CHECK:STDOUT:   %struct.4: ConvertValue = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: ConvertValue = struct_value () [template]
 // CHECK:STDOUT:   %ConvertRef: type = fn_type @ConvertRef [template]
-// CHECK:STDOUT:   %struct.5: ConvertRef = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: ConvertRef = struct_value () [template]
 // CHECK:STDOUT:   %ConvertInit: type = fn_type @ConvertInit [template]
-// CHECK:STDOUT:   %struct.6: ConvertInit = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: 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:   %struct.8: A = struct_value (%.20) [template]
+// CHECK:STDOUT:   %struct.9: B = struct_value (%struct.8, %.21) [template]
+// CHECK:STDOUT:   %struct.10: C = struct_value (%struct.9, %.23) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -96,84 +98,98 @@ fn ConvertInit() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %ConvertCToB.decl: ConvertCToB = fn_decl @ConvertCToB [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %ConvertCToB.decl: ConvertCToB = fn_decl @ConvertCToB [template = constants.%struct.2] {
 // 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:     %.loc21_20: type = ptr_type C [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc21_16.1: C* = param p
 // CHECK:STDOUT:     @ConvertCToB.%p: C* = bind_name p, %p.loc21_16.1
 // CHECK:STDOUT:     %B.ref.loc21: type = name_ref B, %B.decl [template = constants.%B]
-// CHECK:STDOUT:     %.loc21_27: type = ptr_type B [template = constants.%.14]
+// CHECK:STDOUT:     %.loc21_27: type = ptr_type B [template = constants.%.15]
 // CHECK:STDOUT:     @ConvertCToB.%return: ref B* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertBToA.decl: ConvertBToA = fn_decl @ConvertBToA [template = constants.%struct.2] {
+// CHECK:STDOUT:   %ConvertBToA.decl: ConvertBToA = fn_decl @ConvertBToA [template = constants.%struct.3] {
 // 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:     %.loc22_20: type = ptr_type B [template = constants.%.15]
 // 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.%.19]
 // CHECK:STDOUT:     @ConvertBToA.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertCToA.decl: ConvertCToA = fn_decl @ConvertCToA [template = constants.%struct.3] {
+// CHECK:STDOUT:   %ConvertCToA.decl: ConvertCToA = fn_decl @ConvertCToA [template = constants.%struct.4] {
 // 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:     %.loc23_20: type = ptr_type C [template = constants.%.14]
 // 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.%.19]
 // CHECK:STDOUT:     @ConvertCToA.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertValue.decl: ConvertValue = fn_decl @ConvertValue [template = constants.%struct.4] {
+// CHECK:STDOUT:   %ConvertValue.decl: ConvertValue = fn_decl @ConvertValue [template = constants.%struct.5] {
 // 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.decl: ConvertRef = fn_decl @ConvertRef [template = constants.%struct.5] {
+// CHECK:STDOUT:   %ConvertRef.decl: ConvertRef = fn_decl @ConvertRef [template = constants.%struct.6] {
 // 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:     %.loc29_19: type = ptr_type C [template = constants.%.14]
 // 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.%.19]
 // CHECK:STDOUT:     @ConvertRef.%return: ref A* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ConvertInit.decl: ConvertInit = fn_decl @ConvertInit [template = constants.%struct.6] {}
+// CHECK:STDOUT:   %ConvertInit.decl: ConvertInit = fn_decl @ConvertInit [template = constants.%struct.7] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %.loc8: <unbound element of class A> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class A> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .a = %.loc8
+// CHECK:STDOUT:   .a = %.loc8_8
 // 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:   %.loc13: <unbound element of class B> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc13_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc13_10.2: type = converted %int.make_type_32, %.loc13_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc13_8: <unbound element of class B> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .base = %.loc12
-// CHECK:STDOUT:   .b = %.loc13
+// CHECK:STDOUT:   .b = %.loc13_8
 // 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:   %.loc18: <unbound element of class C> = field_decl c, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc18_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc18_10.2: type = converted %int.make_type_32, %.loc18_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc18_8: <unbound element of class C> = field_decl c, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc17
-// CHECK:STDOUT:   .c = %.loc18
+// CHECK:STDOUT:   .c = %.loc18_8
 // CHECK:STDOUT:   extend name_scope3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @ConvertCToB(%p: C*) -> B* {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: C* = name_ref p, %p
@@ -244,15 +260,15 @@ fn ConvertInit() {
 // 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.%.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_39.4: init A = class_init (%.loc34_39.3), %.loc34_48.2 [template = constants.%struct.8]
+// CHECK:STDOUT:   %.loc34_48.3: init A = converted %.loc34_39.1, %.loc34_39.4 [template = constants.%struct.8]
 // 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.%.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_48.6: init B = class_init (%.loc34_48.3, %.loc34_48.5), %.loc34_57.3 [template = constants.%struct.9]
+// CHECK:STDOUT:   %.loc34_57.4: init B = converted %.loc34_48.1, %.loc34_48.6 [template = constants.%struct.9]
 // 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.%.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.7: init C = class_init (%.loc34_57.4, %.loc34_57.6), %.loc34_57.2 [template = constants.%struct.10]
 // 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

+ 71 - 30
toolchain/check/testdata/class/extend_adapt.carbon

@@ -91,18 +91,20 @@ class StructAdapter {
 // CHECK:STDOUT: constants {
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type SomeClass, i32 [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:   %struct.2: StaticMemberFunction = struct_value () [template]
 // CHECK:STDOUT:   %AdapterMethod: type = fn_type @AdapterMethod [template]
-// CHECK:STDOUT:   %struct.2: AdapterMethod = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: 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:   %struct.4: TestStaticMemberFunction = struct_value () [template]
 // CHECK:STDOUT:   %TestAdapterMethod: type = fn_type @TestAdapterMethod [template]
-// CHECK:STDOUT:   %struct.4: TestAdapterMethod = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: TestAdapterMethod = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -116,13 +118,15 @@ class StructAdapter {
 // 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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %SomeClassAdapter.decl.loc15: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
-// CHECK:STDOUT:   %TestStaticMemberFunction.decl: TestStaticMemberFunction = fn_decl @TestStaticMemberFunction [template = constants.%struct.3] {
+// CHECK:STDOUT:   %TestStaticMemberFunction.decl: TestStaticMemberFunction = fn_decl @TestStaticMemberFunction [template = constants.%struct.4] {
 // 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.decl: TestAdapterMethod = fn_decl @TestAdapterMethod [template = constants.%struct.4] {
+// CHECK:STDOUT:   %TestAdapterMethod.decl: TestAdapterMethod = fn_decl @TestAdapterMethod [template = constants.%struct.5] {
 // 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
@@ -139,10 +143,16 @@ class StructAdapter {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // 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.decl: StaticMemberFunction = fn_decl @StaticMemberFunction [template = constants.%struct.1] {}
-// CHECK:STDOUT:   %AdapterMethod.decl: AdapterMethod = fn_decl @AdapterMethod [template = constants.%struct.2] {
+// CHECK:STDOUT:   %int.make_type_32.loc7: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc7_10.1: type = value_of_initializer %int.make_type_32.loc7 [template = i32]
+// CHECK:STDOUT:   %.loc7_10.2: type = converted %int.make_type_32.loc7, %.loc7_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc7_8: <unbound element of class SomeClass> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32.loc8, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class SomeClass> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %StaticMemberFunction.decl: StaticMemberFunction = fn_decl @StaticMemberFunction [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %AdapterMethod.decl: AdapterMethod = fn_decl @AdapterMethod [template = constants.%struct.3] {
 // 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
@@ -150,12 +160,14 @@ class StructAdapter {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%SomeClass
-// CHECK:STDOUT:   .a = %.loc7
-// CHECK:STDOUT:   .b = %.loc8
+// CHECK:STDOUT:   .a = %.loc7_8
+// CHECK:STDOUT:   .b = %.loc8_8
 // CHECK:STDOUT:   .StaticMemberFunction = %StaticMemberFunction.decl
 // CHECK:STDOUT:   .AdapterMethod = %AdapterMethod.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @StaticMemberFunction();
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @AdapterMethod[@SomeClass.%self.loc12_20.2: SomeClassAdapter]();
@@ -163,7 +175,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: StaticMemberFunction = name_ref StaticMemberFunction, @SomeClass.%StaticMemberFunction.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %StaticMemberFunction.ref: StaticMemberFunction = name_ref StaticMemberFunction, @SomeClass.%StaticMemberFunction.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %StaticMemberFunction.call: init () = call %StaticMemberFunction.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -171,7 +183,7 @@ class StructAdapter {
 // CHECK:STDOUT: fn @TestAdapterMethod(%a: SomeClassAdapter) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: SomeClassAdapter = name_ref a, %a
-// CHECK:STDOUT:   %AdapterMethod.ref: AdapterMethod = name_ref AdapterMethod, @SomeClass.%AdapterMethod.decl [template = constants.%struct.2]
+// CHECK:STDOUT:   %AdapterMethod.ref: AdapterMethod = name_ref AdapterMethod, @SomeClass.%AdapterMethod.decl [template = constants.%struct.3]
 // CHECK:STDOUT:   %.loc24: <bound method> = bound_method %a.ref, %AdapterMethod.ref
 // CHECK:STDOUT:   %AdapterMethod.call: init () = call %.loc24(%a.ref)
 // CHECK:STDOUT:   return
@@ -244,13 +256,15 @@ class StructAdapter {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type SomeClass, i32 [template]
+// CHECK:STDOUT:   %.3: 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:   %.4: 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:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -262,23 +276,35 @@ class StructAdapter {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %SomeClass.decl: type = class_decl @SomeClass [template = constants.%SomeClass] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %SomeClassAdapter.decl: type = class_decl @SomeClassAdapter [template = constants.%SomeClassAdapter] {}
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
 // 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
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_30.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc13_30.2: type = converted %int.make_type_32, %.loc13_30.1 [template = i32]
 // CHECK:STDOUT:     @F.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClass {
-// CHECK:STDOUT:   %.loc5: <unbound element of class SomeClass> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc6: <unbound element of class SomeClass> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc5: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc5_10.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32]
+// CHECK:STDOUT:   %.loc5_10.2: type = converted %int.make_type_32.loc5, %.loc5_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc5_8: <unbound element of class SomeClass> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc6: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc6_10.1: type = value_of_initializer %int.make_type_32.loc6 [template = i32]
+// CHECK:STDOUT:   %.loc6_10.2: type = converted %int.make_type_32.loc6, %.loc6_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc6_8: <unbound element of class SomeClass> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%SomeClass
-// CHECK:STDOUT:   .a = %.loc5
-// CHECK:STDOUT:   .b = %.loc6
+// CHECK:STDOUT:   .a = %.loc5_8
+// CHECK:STDOUT:   .b = %.loc6_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @SomeClassAdapter {
@@ -290,10 +316,12 @@ class StructAdapter {
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%a: SomeClassAdapter) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: SomeClassAdapter = name_ref a, %a
-// CHECK:STDOUT:   %b.ref: <unbound element of class SomeClass> = name_ref b, @SomeClass.%.loc6 [template = @SomeClass.%.loc6]
+// CHECK:STDOUT:   %b.ref: <unbound element of class SomeClass> = name_ref b, @SomeClass.%.loc6_8 [template = @SomeClass.%.loc6_8]
 // CHECK:STDOUT:   %.loc18: i32 = class_element_access <error>, element1 [template = <error>]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
@@ -302,8 +330,11 @@ class StructAdapter {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %StructAdapter: type = class_type @StructAdapter [template]
-// CHECK:STDOUT:   %.1: type = struct_type {.a: i32, .b: i32} [template]
-// CHECK:STDOUT:   %.2: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -313,10 +344,18 @@ class StructAdapter {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %StructAdapter.decl: type = class_decl @StructAdapter [template = constants.%StructAdapter] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @StructAdapter {
-// CHECK:STDOUT:   %.loc8: type = struct_type {.a: i32, .b: i32} [template = constants.%.1]
+// CHECK:STDOUT:   %int.make_type_32.loc8_21: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_21.1: type = value_of_initializer %int.make_type_32.loc8_21 [template = i32]
+// CHECK:STDOUT:   %.loc8_21.2: type = converted %int.make_type_32.loc8_21, %.loc8_21.1 [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc8_30: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_30.1: type = value_of_initializer %int.make_type_32.loc8_30 [template = i32]
+// CHECK:STDOUT:   %.loc8_30.2: type = converted %int.make_type_32.loc8_30, %.loc8_30.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_33: type = struct_type {.a: i32, .b: i32} [template = constants.%.2]
 // CHECK:STDOUT:   adapt_decl {.a: i32, .b: i32}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -324,3 +363,5 @@ class StructAdapter {
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 39 - 19
toolchain/check/testdata/class/fail_abstract.carbon

@@ -30,16 +30,18 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Abstract: type = class_type @Abstract [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Abstract, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Abstract, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
-// CHECK:STDOUT:   %.3: type = ptr_type {.a: i32} [template]
-// 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:   %.4: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.5: type = unbound_element_type Derived, Abstract [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.7: type = struct_type {.base: Abstract, .d: 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:   %struct.2: 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]
@@ -49,7 +51,7 @@ fn Access(d: Derived) -> (i32, i32) {
 // 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:   %struct.3: Access = struct_value () [template]
 // CHECK:STDOUT:   %.16: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -63,41 +65,59 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Abstract.decl: type = class_decl @Abstract [template = constants.%Abstract] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Derived.decl: type = class_decl @Derived [template = constants.%Derived] {}
-// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Make.decl: Make = fn_decl @Make [template = constants.%struct.2] {
 // 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.decl: Access = fn_decl @Access [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %Access.decl: Access = fn_decl @Access [template = constants.%struct.3] {
 // 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.%.15 [template = constants.%.15]
+// CHECK:STDOUT:     %int.make_type_32.loc25_27: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %int.make_type_32.loc25_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc25_35.1: (type, type) = tuple_literal (%int.make_type_32.loc25_27, %int.make_type_32.loc25_32)
+// CHECK:STDOUT:     %.loc25_35.2: type = value_of_initializer %int.make_type_32.loc25_27 [template = i32]
+// CHECK:STDOUT:     %.loc25_35.3: type = converted %int.make_type_32.loc25_27, %.loc25_35.2 [template = i32]
+// CHECK:STDOUT:     %.loc25_35.4: type = value_of_initializer %int.make_type_32.loc25_32 [template = i32]
+// CHECK:STDOUT:     %.loc25_35.5: type = converted %int.make_type_32.loc25_32, %.loc25_35.4 [template = i32]
+// CHECK:STDOUT:     %.loc25_35.6: type = converted %.loc25_35.1, constants.%.15 [template = constants.%.15]
 // CHECK:STDOUT:     @Access.%return: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Abstract {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Abstract> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Abstract> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Abstract
-// CHECK:STDOUT:   .a = %.loc8
+// CHECK:STDOUT:   .a = %.loc8_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
 // CHECK:STDOUT:   %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [template = constants.%Abstract]
 // CHECK:STDOUT:   %.loc12: <unbound element of class Derived> = base_decl Abstract, element0 [template]
-// CHECK:STDOUT:   %.loc14: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc14_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc14_10.2: type = converted %int.make_type_32, %.loc14_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc14_8: <unbound element of class Derived> = field_decl d, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
-// CHECK:STDOUT:   .d = %.loc14
+// CHECK:STDOUT:   .d = %.loc14_8
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1 [template = constants.%.11]
@@ -110,14 +130,14 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT: fn @Access(%d: Derived) -> %return: (i32, i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %d.ref.loc26_11: Derived = name_ref d, %d
-// CHECK:STDOUT:   %d.ref.loc26_12: <unbound element of class Derived> = name_ref d, @Derived.%.loc14 [template = @Derived.%.loc14]
+// CHECK:STDOUT:   %d.ref.loc26_12: <unbound element of class Derived> = name_ref d, @Derived.%.loc14_8 [template = @Derived.%.loc14_8]
 // CHECK:STDOUT:   %.loc26_12.1: ref i32 = class_element_access %d.ref.loc26_11, element1
 // CHECK:STDOUT:   %.loc26_12.2: i32 = bind_value %.loc26_12.1
 // CHECK:STDOUT:   %d.ref.loc26_16: Derived = name_ref d, %d
 // CHECK:STDOUT:   %base.ref: <unbound element of class Derived> = name_ref base, @Derived.%.loc12 [template = @Derived.%.loc12]
 // CHECK:STDOUT:   %.loc26_17.1: ref Abstract = class_element_access %d.ref.loc26_16, element0
 // CHECK:STDOUT:   %.loc26_17.2: Abstract = bind_value %.loc26_17.1
-// CHECK:STDOUT:   %a.ref: <unbound element of class Abstract> = name_ref a, @Abstract.%.loc8 [template = @Abstract.%.loc8]
+// CHECK:STDOUT:   %a.ref: <unbound element of class Abstract> = name_ref a, @Abstract.%.loc8_8 [template = @Abstract.%.loc8_8]
 // CHECK:STDOUT:   %.loc26_22.1: ref i32 = class_element_access %.loc26_17.2, element0
 // CHECK:STDOUT:   %.loc26_22.2: i32 = bind_value %.loc26_22.1
 // CHECK:STDOUT:   %.loc26_24.1: (i32, i32) = tuple_literal (%.loc26_12.2, %.loc26_22.2)

+ 57 - 12
toolchain/check/testdata/class/fail_adapt_with_subobjects.carbon

@@ -76,7 +76,9 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %AdaptWithBase: type = class_type @AdaptWithBase [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type AdaptWithBase, Base [template]
 // CHECK:STDOUT: }
@@ -90,6 +92,7 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %AdaptWithBase.decl: type = class_decl @AdaptWithBase [template = constants.%AdaptWithBase] {}
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
@@ -98,6 +101,9 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @AdaptWithBase {
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc10_12.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc10_12.2: type = converted %int.make_type_32, %.loc10_12.1 [template = i32]
 // CHECK:STDOUT:   adapt_decl i32
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc15: <unbound element of class AdaptWithBase> = base_decl Base, element0 [template]
@@ -108,13 +114,18 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_adapt_with_fields.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %AdaptWithField: type = class_type @AdaptWithField [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type AdaptWithField, i32 [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type AdaptWithField, i32 [template]
 // CHECK:STDOUT:   %AdaptWithFields: type = class_type @AdaptWithFields [template]
-// CHECK:STDOUT:   %.2: type = unbound_element_type AdaptWithFields, i32 [template]
+// CHECK:STDOUT:   %.3: type = unbound_element_type AdaptWithFields, i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -125,31 +136,57 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %AdaptWithField.decl: type = class_decl @AdaptWithField [template = constants.%AdaptWithField] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT:   %AdaptWithFields.decl: type = class_decl @AdaptWithFields [template = constants.%AdaptWithFields] {}
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @AdaptWithField {
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_12.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_12.2: type = converted %int.make_type_32.loc8, %.loc8_12.1 [template = i32]
 // CHECK:STDOUT:   adapt_decl i32
-// CHECK:STDOUT:   %.loc13: <unbound element of class AdaptWithField> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc13_10.1: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
+// CHECK:STDOUT:   %.loc13_10.2: type = converted %int.make_type_32.loc13, %.loc13_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc13_8: <unbound element of class AdaptWithField> = field_decl n, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%AdaptWithField
-// CHECK:STDOUT:   .n = %.loc13
+// CHECK:STDOUT:   .n = %.loc13_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @AdaptWithFields {
+// CHECK:STDOUT:   %int.make_type_32.loc20: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc20_12.1: type = value_of_initializer %int.make_type_32.loc20 [template = i32]
+// CHECK:STDOUT:   %.loc20_12.2: type = converted %int.make_type_32.loc20, %.loc20_12.1 [template = i32]
 // CHECK:STDOUT:   adapt_decl i32
-// CHECK:STDOUT:   %.loc25: <unbound element of class AdaptWithFields> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc26: <unbound element of class AdaptWithFields> = field_decl b, element1 [template]
-// CHECK:STDOUT:   %.loc27: <unbound element of class AdaptWithFields> = field_decl c, element2 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc25_10.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
+// CHECK:STDOUT:   %.loc25_10.2: type = converted %int.make_type_32.loc25, %.loc25_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc25_8: <unbound element of class AdaptWithFields> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc26: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc26_10.1: type = value_of_initializer %int.make_type_32.loc26 [template = i32]
+// CHECK:STDOUT:   %.loc26_10.2: type = converted %int.make_type_32.loc26, %.loc26_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc26_8: <unbound element of class AdaptWithFields> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc27: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc27_10.1: type = value_of_initializer %int.make_type_32.loc27 [template = i32]
+// CHECK:STDOUT:   %.loc27_10.2: type = converted %int.make_type_32.loc27, %.loc27_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc27_8: <unbound element of class AdaptWithFields> = field_decl c, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%AdaptWithFields
-// CHECK:STDOUT:   .a = %.loc25
-// CHECK:STDOUT:   .b = %.loc26
-// CHECK:STDOUT:   .c = %.loc27
+// CHECK:STDOUT:   .a = %.loc25_8
+// CHECK:STDOUT:   .b = %.loc26_8
+// CHECK:STDOUT:   .c = %.loc27_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_adapt_with_base_and_fields.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -159,6 +196,8 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   %.2: type = tuple_type () [template]
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = unbound_element_type AdaptWithBaseAndFields, Base [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = unbound_element_type AdaptWithBaseAndFields, i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -171,6 +210,7 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %AdaptWithBaseAndFields.decl: type = class_decl @AdaptWithBaseAndFields [template = constants.%AdaptWithBaseAndFields] {}
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
@@ -181,7 +221,10 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT: class @AdaptWithBaseAndFields {
 // CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base.decl [template = constants.%Base]
 // CHECK:STDOUT:   %.loc7: <unbound element of class AdaptWithBaseAndFields> = base_decl Base, element0 [template]
-// CHECK:STDOUT:   %.loc8: <unbound element of class AdaptWithBaseAndFields> = field_decl n, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class AdaptWithBaseAndFields> = field_decl n, element1 [template]
 // CHECK:STDOUT:   %.loc15_10: {} = struct_literal ()
 // CHECK:STDOUT:   %.loc15_11: type = converted %.loc15_10, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   adapt_decl {}
@@ -189,7 +232,9 @@ class AdaptWithBaseAndFields {
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%AdaptWithBaseAndFields
 // CHECK:STDOUT:   .base = %.loc7
-// CHECK:STDOUT:   .n = %.loc8
+// CHECK:STDOUT:   .n = %.loc8_8
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 108 - 44
toolchain/check/testdata/class/fail_base_bad_type.carbon

@@ -134,25 +134,27 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
 // CHECK:STDOUT:   %Final: type = class_type @Final [template]
-// CHECK:STDOUT:   %.2: type = unbound_element_type Final, i32 [template]
-// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.3: type = unbound_element_type Final, i32 [template]
+// CHECK:STDOUT:   %.4: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %DeriveFromError: type = class_type @DeriveFromError [template]
-// CHECK:STDOUT:   %.4: type = ptr_type DeriveFromError [template]
+// CHECK:STDOUT:   %.5: 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:   %struct.2: AccessMemberWithInvalidBaseError = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromNonType: type = class_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:   %struct.3: AccessMemberWithInvalidBasNonType = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromi32: type = class_type @DeriveFromi32 [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:   %struct.4: ConvertToBadBasei32 = struct_value () [template]
 // CHECK:STDOUT:   %AccessMemberWithInvalidBasei32: type = fn_type @AccessMemberWithInvalidBasei32 [template]
-// CHECK:STDOUT:   %struct.4: AccessMemberWithInvalidBasei32 = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: AccessMemberWithInvalidBasei32 = struct_value () [template]
 // CHECK:STDOUT:   %DeriveFromTuple: type = class_type @DeriveFromTuple [template]
 // CHECK:STDOUT:   %.10: type = tuple_type (type) [template]
 // CHECK:STDOUT:   %.11: type = tuple_type (Base) [template]
@@ -161,25 +163,25 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // 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:   %struct.6: ConvertToBadBaseTuple = struct_value () [template]
 // CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple: type = fn_type @AccessMemberWithInvalidBaseTuple [template]
-// CHECK:STDOUT:   %struct.6: AccessMemberWithInvalidBaseTuple = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: 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:   %struct.8: ConvertToBadBaseStruct = struct_value () [template]
 // CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct: type = fn_type @AccessMemberWithInvalidBaseStruct [template]
-// CHECK:STDOUT:   %struct.8: AccessMemberWithInvalidBaseStruct = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: 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:   %struct.10: ConvertToBadBaseIncomplete = struct_value () [template]
 // CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete: type = fn_type @AccessMemberWithInvalidBaseIncomplete [template]
-// CHECK:STDOUT:   %struct.10: AccessMemberWithInvalidBaseIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.11: 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]
@@ -187,13 +189,13 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // 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:   %struct.12: 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:   %struct.13: 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:   %struct.14: AccessMemberWithInvalidBaseFinal_NoMember = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -226,40 +228,58 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // 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:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %DeriveFromError.decl: type = class_decl @DeriveFromError [template = constants.%DeriveFromError] {}
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError.decl: AccessMemberWithInvalidBaseError = fn_decl @AccessMemberWithInvalidBaseError [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError.decl: AccessMemberWithInvalidBaseError = fn_decl @AccessMemberWithInvalidBaseError [template = constants.%struct.2] {
 // 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:     %.loc21_55: type = ptr_type DeriveFromError [template = constants.%.5]
 // CHECK:STDOUT:     %p.loc21_37.1: DeriveFromError* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseError.%p: DeriveFromError* = bind_name p, %p.loc21_37.1
+// CHECK:STDOUT:     %int.make_type_32.loc21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc21_61.1: type = value_of_initializer %int.make_type_32.loc21 [template = i32]
+// CHECK:STDOUT:     %.loc21_61.2: type = converted %int.make_type_32.loc21, %.loc21_61.1 [template = 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.decl: AccessMemberWithInvalidBasNonType = fn_decl @AccessMemberWithInvalidBasNonType [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType.decl: AccessMemberWithInvalidBasNonType = fn_decl @AccessMemberWithInvalidBasNonType [template = constants.%struct.3] {
 // CHECK:STDOUT:     %DeriveFromNonType.ref: type = name_ref DeriveFromNonType, %DeriveFromNonType.decl [template = constants.%DeriveFromNonType]
-// CHECK:STDOUT:     %.loc31: type = ptr_type DeriveFromNonType [template = constants.%.7]
+// CHECK:STDOUT:     %.loc31_58: 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:     %int.make_type_32.loc31: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc31_64.1: type = value_of_initializer %int.make_type_32.loc31 [template = i32]
+// CHECK:STDOUT:     %.loc31_64.2: type = converted %int.make_type_32.loc31, %.loc31_64.1 [template = i32]
 // 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.decl: ConvertToBadBasei32 = fn_decl @ConvertToBadBasei32 [template = constants.%struct.3] {
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.5: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %ConvertToBadBasei32.decl: ConvertToBadBasei32 = fn_decl @ConvertToBadBasei32 [template = constants.%struct.4] {
 // CHECK:STDOUT:     %DeriveFromi32.ref.loc47: type = name_ref DeriveFromi32, %DeriveFromi32.decl [template = constants.%DeriveFromi32]
 // 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.%.9]
+// CHECK:STDOUT:     %int.make_type_32.loc47: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc47_49.1: type = value_of_initializer %int.make_type_32.loc47 [template = i32]
+// CHECK:STDOUT:     %.loc47_49.2: type = converted %int.make_type_32.loc47, %.loc47_49.1 [template = i32]
+// CHECK:STDOUT:     %.loc47_49.3: type = ptr_type i32 [template = constants.%.9]
 // CHECK:STDOUT:     @ConvertToBadBasei32.%return: ref i32* = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32.decl: AccessMemberWithInvalidBasei32 = fn_decl @AccessMemberWithInvalidBasei32 [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.6: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32.decl: AccessMemberWithInvalidBasei32 = fn_decl @AccessMemberWithInvalidBasei32 [template = constants.%struct.5] {
 // CHECK:STDOUT:     %DeriveFromi32.ref.loc49: type = name_ref DeriveFromi32, %DeriveFromi32.decl [template = constants.%DeriveFromi32]
-// CHECK:STDOUT:     %.loc49: type = ptr_type DeriveFromi32 [template = constants.%.8]
+// CHECK:STDOUT:     %.loc49_51: 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:     %int.make_type_32.loc49: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc49_57.1: type = value_of_initializer %int.make_type_32.loc49 [template = i32]
+// CHECK:STDOUT:     %.loc49_57.2: type = converted %int.make_type_32.loc49, %.loc49_57.1 [template = i32]
 // 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.decl: ConvertToBadBaseTuple = fn_decl @ConvertToBadBaseTuple [template = constants.%struct.5] {
+// CHECK:STDOUT:   %ConvertToBadBaseTuple.decl: ConvertToBadBaseTuple = fn_decl @ConvertToBadBaseTuple [template = constants.%struct.6] {
 // 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
@@ -270,33 +290,51 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // 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.decl: AccessMemberWithInvalidBaseTuple = fn_decl @AccessMemberWithInvalidBaseTuple [template = constants.%struct.6] {
+// CHECK:STDOUT:   %import_ref.7: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple.decl: AccessMemberWithInvalidBaseTuple = fn_decl @AccessMemberWithInvalidBaseTuple [template = constants.%struct.7] {
 // 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:     %.loc65_55: type = ptr_type DeriveFromTuple [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc65_37.1: DeriveFromTuple* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseTuple.%p: DeriveFromTuple* = bind_name p, %p.loc65_37.1
+// CHECK:STDOUT:     %int.make_type_32.loc65: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc65_61.1: type = value_of_initializer %int.make_type_32.loc65 [template = i32]
+// CHECK:STDOUT:     %.loc65_61.2: type = converted %int.make_type_32.loc65, %.loc65_61.1 [template = 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.decl: ConvertToBadBaseStruct = fn_decl @ConvertToBadBaseStruct [template = constants.%struct.7] {
+// CHECK:STDOUT:   %import_ref.8: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.9: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.10: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.11: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %ConvertToBadBaseStruct.decl: ConvertToBadBaseStruct = fn_decl @ConvertToBadBaseStruct [template = constants.%struct.8] {
 // 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
 // CHECK:STDOUT:     @ConvertToBadBaseStruct.%p: DeriveFromStruct* = bind_name p, %p.loc81_27.1
+// CHECK:STDOUT:     %int.make_type_32.loc81_57: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc81_57.1: type = value_of_initializer %int.make_type_32.loc81_57 [template = i32]
+// CHECK:STDOUT:     %.loc81_57.2: type = converted %int.make_type_32.loc81_57, %.loc81_57.1 [template = i32]
+// CHECK:STDOUT:     %int.make_type_32.loc81_66: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc81_66.1: type = value_of_initializer %int.make_type_32.loc81_66 [template = i32]
+// CHECK:STDOUT:     %.loc81_66.2: type = converted %int.make_type_32.loc81_66, %.loc81_66.1 [template = i32]
 // CHECK:STDOUT:     %.loc81_69: type = struct_type {.a: i32, .b: i32} [template = constants.%.16]
 // 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.decl: AccessMemberWithInvalidBaseStruct = fn_decl @AccessMemberWithInvalidBaseStruct [template = constants.%struct.8] {
+// CHECK:STDOUT:   %import_ref.12: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct.decl: AccessMemberWithInvalidBaseStruct = fn_decl @AccessMemberWithInvalidBaseStruct [template = constants.%struct.9] {
 // 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:     %.loc84_57: type = ptr_type DeriveFromStruct [template = constants.%.18]
 // CHECK:STDOUT:     %p.loc84_38.1: DeriveFromStruct* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseStruct.%p: DeriveFromStruct* = bind_name p, %p.loc84_38.1
+// CHECK:STDOUT:     %int.make_type_32.loc84: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc84_63.1: type = value_of_initializer %int.make_type_32.loc84 [template = i32]
+// CHECK:STDOUT:     %.loc84_63.2: type = converted %int.make_type_32.loc84, %.loc84_63.1 [template = i32]
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseStruct.%return: ref i32 = var <return slot>
 // 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.decl: ConvertToBadBaseIncomplete = fn_decl @ConvertToBadBaseIncomplete [template = constants.%struct.9] {
+// CHECK:STDOUT:   %ConvertToBadBaseIncomplete.decl: ConvertToBadBaseIncomplete = fn_decl @ConvertToBadBaseIncomplete [template = constants.%struct.10] {
 // 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
@@ -305,15 +343,19 @@ 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.decl: AccessMemberWithInvalidBaseIncomplete = fn_decl @AccessMemberWithInvalidBaseIncomplete [template = constants.%struct.10] {
+// CHECK:STDOUT:   %import_ref.13: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete.decl: AccessMemberWithInvalidBaseIncomplete = fn_decl @AccessMemberWithInvalidBaseIncomplete [template = constants.%struct.11] {
 // 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:     %.loc105_65: type = ptr_type DeriveFromIncomplete [template = constants.%.19]
 // CHECK:STDOUT:     %p.loc105_42.1: DeriveFromIncomplete* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseIncomplete.%p: DeriveFromIncomplete* = bind_name p, %p.loc105_42.1
+// CHECK:STDOUT:     %int.make_type_32.loc105: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc105_71.1: type = value_of_initializer %int.make_type_32.loc105 [template = i32]
+// CHECK:STDOUT:     %.loc105_71.2: type = converted %int.make_type_32.loc105, %.loc105_71.1 [template = 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.decl: ConvertToBadBaseFinal = fn_decl @ConvertToBadBaseFinal [template = constants.%struct.11] {
+// CHECK:STDOUT:   %ConvertToBadBaseFinal.decl: ConvertToBadBaseFinal = fn_decl @ConvertToBadBaseFinal [template = constants.%struct.12] {
 // 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
@@ -322,18 +364,26 @@ 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.decl: AccessMemberWithInvalidBaseFinal_WithMember = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember [template = constants.%struct.12] {
+// CHECK:STDOUT:   %import_ref.14: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember.decl: AccessMemberWithInvalidBaseFinal_WithMember = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember [template = constants.%struct.13] {
 // 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:     %.loc120_66: 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:     %int.make_type_32.loc120: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc120_72.1: type = value_of_initializer %int.make_type_32.loc120 [template = i32]
+// CHECK:STDOUT:     %.loc120_72.2: type = converted %int.make_type_32.loc120, %.loc120_72.1 [template = i32]
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseFinal_WithMember.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember.decl: AccessMemberWithInvalidBaseFinal_NoMember = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember [template = constants.%struct.13] {
+// CHECK:STDOUT:   %import_ref.15: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember.decl: AccessMemberWithInvalidBaseFinal_NoMember = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember [template = constants.%struct.14] {
 // 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:     %.loc124_64: type = ptr_type DeriveFromFinal [template = constants.%.24]
 // CHECK:STDOUT:     %p.loc124_46.1: DeriveFromFinal* = param p
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseFinal_NoMember.%p: DeriveFromFinal* = bind_name p, %p.loc124_46.1
+// CHECK:STDOUT:     %int.make_type_32.loc124: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc124_70.1: type = value_of_initializer %int.make_type_32.loc124 [template = i32]
+// CHECK:STDOUT:     %.loc124_70.2: type = converted %int.make_type_32.loc124, %.loc124_70.1 [template = i32]
 // CHECK:STDOUT:     @AccessMemberWithInvalidBaseFinal_NoMember.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -344,11 +394,14 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Final {
-// CHECK:STDOUT:   %.loc9: <unbound element of class Final> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %int.make_type_32, %.loc9_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc9_8: <unbound element of class Final> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Final
-// CHECK:STDOUT:   .a = %.loc9
+// CHECK:STDOUT:   .a = %.loc9_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromError {
@@ -372,11 +425,14 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromi32 {
-// CHECK:STDOUT:   %.loc38: <error> = base_decl <error>, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc38_16.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc38_16.2: type = converted %int.make_type_32, %.loc38_16.1 [template = i32]
+// CHECK:STDOUT:   %.loc38_19: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%DeriveFromi32
-// CHECK:STDOUT:   .base = %.loc38
+// CHECK:STDOUT:   .base = %.loc38_19
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -393,6 +449,12 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromStruct {
+// CHECK:STDOUT:   %int.make_type_32.loc74_21: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc74_21.1: type = value_of_initializer %int.make_type_32.loc74_21 [template = i32]
+// CHECK:STDOUT:   %.loc74_21.2: type = converted %int.make_type_32.loc74_21, %.loc74_21.1 [template = i32]
+// CHECK:STDOUT:   %int.make_type_32.loc74_30: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc74_30.1: type = value_of_initializer %int.make_type_32.loc74_30 [template = i32]
+// CHECK:STDOUT:   %.loc74_30.2: type = converted %int.make_type_32.loc74_30, %.loc74_30.1 [template = i32]
 // CHECK:STDOUT:   %.loc74_33: type = struct_type {.a: i32, .b: i32} [template = constants.%.16]
 // CHECK:STDOUT:   %.loc74_34: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
@@ -424,6 +486,8 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   extend name_scope3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @AccessMemberWithInvalidBaseError(%p: DeriveFromError*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: DeriveFromError* = name_ref p, %p
@@ -510,7 +574,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: DeriveFromFinal* = name_ref p, %p
 // CHECK:STDOUT:   %.loc121_11: ref DeriveFromFinal = deref %p.ref
-// CHECK:STDOUT:   %a.ref: <unbound element of class Final> = name_ref a, @Final.%.loc9 [template = @Final.%.loc9]
+// CHECK:STDOUT:   %a.ref: <unbound element of class Final> = name_ref a, @Final.%.loc9_8 [template = @Final.%.loc9_8]
 // CHECK:STDOUT:   %.loc121_14.1: ref Final = class_element_access %.loc121_11, element0
 // CHECK:STDOUT:   %.loc121_14.2: ref Final = converted %.loc121_11, %.loc121_14.1
 // CHECK:STDOUT:   %.loc121_14.3: ref i32 = class_element_access %.loc121_14.2, element0

+ 28 - 12
toolchain/check/testdata/class/fail_compound_type_mismatch.carbon

@@ -23,14 +23,16 @@ fn AccessBInA(a: A) -> i32 {
 // CHECK:STDOUT:
 // 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 {.a: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // 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:   %.4: type = unbound_element_type B, i32 [template]
+// CHECK:STDOUT:   %.5: type = struct_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:   %struct.2: AccessBInA = struct_value () [template]
 // CHECK:STDOUT:   %.6: type = ptr_type {.a: i32} [template]
 // CHECK:STDOUT:   %.7: type = ptr_type {.b: i32} [template]
 // CHECK:STDOUT: }
@@ -44,36 +46,50 @@ fn AccessBInA(a: A) -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A.decl: type = class_decl @A [template = constants.%A] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %B.decl: type = class_decl @B [template = constants.%B] {}
-// CHECK:STDOUT:   %AccessBInA.decl: AccessBInA = fn_decl @AccessBInA [template = constants.%struct] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %AccessBInA.decl: AccessBInA = fn_decl @AccessBInA [template = constants.%struct.2] {
 // 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
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc15_24.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc15_24.2: type = converted %int.make_type_32, %.loc15_24.1 [template = i32]
 // CHECK:STDOUT:     @AccessBInA.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %.loc8: <unbound element of class A> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class A> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A
-// CHECK:STDOUT:   .a = %.loc8
+// CHECK:STDOUT:   .a = %.loc8_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %.loc12: <unbound element of class B> = field_decl b, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc12_8: <unbound element of class B> = field_decl b, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B
-// CHECK:STDOUT:   .b = %.loc12
+// CHECK:STDOUT:   .b = %.loc12_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @AccessBInA(%a: A) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: A = name_ref a, %a
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
-// CHECK:STDOUT:   %b.ref: <unbound element of class B> = name_ref b, @B.%.loc12 [template = @B.%.loc12]
+// CHECK:STDOUT:   %b.ref: <unbound element of class B> = name_ref b, @B.%.loc12_8 [template = @B.%.loc12_8]
 // CHECK:STDOUT:   %.loc19: i32 = class_element_access <error>, element0 [template = <error>]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }

+ 38 - 22
toolchain/check/testdata/class/fail_derived_to_base.carbon

@@ -34,20 +34,22 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %A1: type = class_type @A1 [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type A1, i32 [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type A1, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %A2: type = class_type @A2 [template]
-// CHECK:STDOUT:   %.3: type = unbound_element_type A2, i32 [template]
+// CHECK:STDOUT:   %.4: type = unbound_element_type A2, i32 [template]
 // CHECK:STDOUT:   %B2: type = class_type @B2 [template]
-// CHECK:STDOUT:   %.4: type = ptr_type {.a: i32} [template]
-// CHECK:STDOUT:   %.5: type = unbound_element_type B2, A2 [template]
-// CHECK:STDOUT:   %.6: type = unbound_element_type B2, i32 [template]
-// CHECK:STDOUT:   %.7: type = struct_type {.base: A2, .b: i32} [template]
-// CHECK:STDOUT:   %.8: type = ptr_type B2 [template]
-// CHECK:STDOUT:   %.9: type = ptr_type A1 [template]
+// CHECK:STDOUT:   %.5: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.6: type = unbound_element_type B2, A2 [template]
+// CHECK:STDOUT:   %.7: type = unbound_element_type B2, i32 [template]
+// CHECK:STDOUT:   %.8: type = struct_type {.base: A2, .b: i32} [template]
+// CHECK:STDOUT:   %.9: type = ptr_type B2 [template]
+// CHECK:STDOUT:   %.10: type = ptr_type A1 [template]
 // CHECK:STDOUT:   %ConvertUnrelated: type = fn_type @ConvertUnrelated [template]
-// CHECK:STDOUT:   %.10: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: ConvertUnrelated = struct_value () [template]
+// CHECK:STDOUT:   %struct.2: ConvertUnrelated = struct_value () [template]
 // CHECK:STDOUT:   %.11: type = struct_type {.base: {.a: i32}*, .b: i32} [template]
 // CHECK:STDOUT:   %.12: type = ptr_type {.base: {.a: i32}*, .b: i32} [template]
 // CHECK:STDOUT:   %.13: type = ptr_type {.base: A2, .b: i32} [template]
@@ -55,7 +57,7 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:   %.14: type = ptr_type Incomplete [template]
 // CHECK:STDOUT:   %.15: type = ptr_type A2 [template]
 // CHECK:STDOUT:   %ConvertIncomplete: type = fn_type @ConvertIncomplete [template]
-// CHECK:STDOUT:   %struct.2: ConvertIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: ConvertIncomplete = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -70,19 +72,22 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %A1.decl: type = class_decl @A1 [template = constants.%A1] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %A2.decl: type = class_decl @A2 [template = constants.%A2] {}
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %B2.decl: type = class_decl @B2 [template = constants.%B2] {}
-// CHECK:STDOUT:   %ConvertUnrelated.decl: ConvertUnrelated = fn_decl @ConvertUnrelated [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %ConvertUnrelated.decl: ConvertUnrelated = fn_decl @ConvertUnrelated [template = constants.%struct.2] {
 // CHECK:STDOUT:     %B2.ref: type = name_ref B2, %B2.decl [template = constants.%B2]
-// CHECK:STDOUT:     %.loc24_26: type = ptr_type B2 [template = constants.%.8]
+// CHECK:STDOUT:     %.loc24_26: type = ptr_type B2 [template = constants.%.9]
 // CHECK:STDOUT:     %p.loc24_21.1: B2* = param p
 // CHECK:STDOUT:     @ConvertUnrelated.%p: B2* = bind_name p, %p.loc24_21.1
 // CHECK:STDOUT:     %A1.ref: type = name_ref A1, %A1.decl [template = constants.%A1]
-// CHECK:STDOUT:     %.loc24_34: type = ptr_type A1 [template = constants.%.9]
+// CHECK:STDOUT:     %.loc24_34: type = ptr_type A1 [template = constants.%.10]
 // CHECK:STDOUT:     @ConvertUnrelated.%return: ref A1* = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Incomplete.decl: type = class_decl @Incomplete [template = constants.%Incomplete] {}
-// CHECK:STDOUT:   %ConvertIncomplete.decl: ConvertIncomplete = fn_decl @ConvertIncomplete [template = constants.%struct.2] {
+// CHECK:STDOUT:   %ConvertIncomplete.decl: ConvertIncomplete = fn_decl @ConvertIncomplete [template = constants.%struct.3] {
 // CHECK:STDOUT:     %Incomplete.ref: type = name_ref Incomplete, %Incomplete.decl [template = constants.%Incomplete]
 // CHECK:STDOUT:     %.loc31_35: type = ptr_type Incomplete [template = constants.%.14]
 // CHECK:STDOUT:     %p.loc31_22.1: Incomplete* = param p
@@ -94,35 +99,46 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A1 {
-// CHECK:STDOUT:   %.loc8: <unbound element of class A1> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class A1> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A1
-// CHECK:STDOUT:   .a = %.loc8
+// CHECK:STDOUT:   .a = %.loc8_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A2 {
-// CHECK:STDOUT:   %.loc12: <unbound element of class A2> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc12_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc12_10.2: type = converted %int.make_type_32, %.loc12_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc12_8: <unbound element of class A2> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%A2
-// CHECK:STDOUT:   .a = %.loc12
+// CHECK:STDOUT:   .a = %.loc12_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B2 {
 // CHECK:STDOUT:   %A2.ref: type = name_ref A2, file.%A2.decl [template = constants.%A2]
 // CHECK:STDOUT:   %.loc16: <unbound element of class B2> = base_decl A2, element0 [template]
-// CHECK:STDOUT:   %.loc17: <unbound element of class B2> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc17_10.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:   %.loc17_10.2: type = converted %int.make_type_32, %.loc17_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc17_8: <unbound element of class B2> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%B2
 // CHECK:STDOUT:   .base = %.loc16
-// CHECK:STDOUT:   .b = %.loc17
+// CHECK:STDOUT:   .b = %.loc17_8
 // CHECK:STDOUT:   extend name_scope3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @ConvertUnrelated(%p: B2*) -> A1* {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: B2* = name_ref p, %p

+ 33 - 12
toolchain/check/testdata/class/fail_field_modifiers.carbon

@@ -34,10 +34,13 @@ class Class {
 // 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: i32 = int_literal 0 [template]
-// CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
-// CHECK:STDOUT:   %.4: type = struct_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.3: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.5: type = struct_type {.j: i32, .k: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -47,19 +50,37 @@ class Class {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
+// CHECK:STDOUT:   %import_ref.4: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc13: <unbound element of class Class> = field_decl j, element0 [template]
-// CHECK:STDOUT:   %.loc19: <unbound element of class Class> = field_decl k, element1 [template]
-// CHECK:STDOUT:   %.loc25: i32 = int_literal 0 [template = constants.%.2]
-// CHECK:STDOUT:   %l: i32 = bind_name l, %.loc25
-// CHECK:STDOUT:   %.loc30: i32 = int_literal 1 [template = constants.%.3]
-// CHECK:STDOUT:   %m: i32 = bind_name m, %.loc30
+// CHECK:STDOUT:   %int.make_type_32.loc13: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc13_18.1: type = value_of_initializer %int.make_type_32.loc13 [template = i32]
+// CHECK:STDOUT:   %.loc13_18.2: type = converted %int.make_type_32.loc13, %.loc13_18.1 [template = i32]
+// CHECK:STDOUT:   %.loc13_16: <unbound element of class Class> = field_decl j, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc19: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc19_16.1: type = value_of_initializer %int.make_type_32.loc19 [template = i32]
+// CHECK:STDOUT:   %.loc19_16.2: type = converted %int.make_type_32.loc19, %.loc19_16.1 [template = i32]
+// CHECK:STDOUT:   %.loc19_14: <unbound element of class Class> = field_decl k, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc25_18.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
+// CHECK:STDOUT:   %.loc25_18.2: type = converted %int.make_type_32.loc25, %.loc25_18.1 [template = i32]
+// CHECK:STDOUT:   %.loc25_24: i32 = int_literal 0 [template = constants.%.3]
+// CHECK:STDOUT:   %l: i32 = bind_name l, %.loc25_24
+// CHECK:STDOUT:   %int.make_type_32.loc30: init type = call constants.%struct() [template = i32]
+// CHECK:STDOUT:   %.loc30_16.1: type = value_of_initializer %int.make_type_32.loc30 [template = i32]
+// CHECK:STDOUT:   %.loc30_16.2: type = converted %int.make_type_32.loc30, %.loc30_16.1 [template = i32]
+// CHECK:STDOUT:   %.loc30_22: i32 = int_literal 1 [template = constants.%.4]
+// CHECK:STDOUT:   %m: i32 = bind_name m, %.loc30_22
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .j = %.loc13
-// CHECK:STDOUT:   .k = %.loc19
+// CHECK:STDOUT:   .j = %.loc13_16
+// CHECK:STDOUT:   .k = %.loc19_14
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:

+ 33 - 21
toolchain/check/testdata/class/fail_incomplete.carbon

@@ -144,22 +144,24 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:   %struct.3: ConvertFromStruct = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = struct_type {} [template]
 // CHECK:STDOUT:   %.4: type = ptr_type Class [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.4: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %struct.4: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: G = struct_value () [template]
 // CHECK:STDOUT:   %MemberAccess: type = fn_type @MemberAccess [template]
-// CHECK:STDOUT:   %struct.5: MemberAccess = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: MemberAccess = struct_value () [template]
 // CHECK:STDOUT:   %Copy: type = fn_type @Copy [template]
-// CHECK:STDOUT:   %struct.6: Copy = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: Copy = struct_value () [template]
 // CHECK:STDOUT:   %Let: type = fn_type @Let [template]
-// CHECK:STDOUT:   %struct.7: Let = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: Let = struct_value () [template]
 // CHECK:STDOUT:   %TakeIncomplete: type = fn_type @TakeIncomplete [template]
-// CHECK:STDOUT:   %struct.8: TakeIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.9: TakeIncomplete = struct_value () [template]
 // CHECK:STDOUT:   %ReturnIncomplete: type = fn_type @ReturnIncomplete [template]
-// CHECK:STDOUT:   %struct.9: ReturnIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.10: ReturnIncomplete = struct_value () [template]
 // CHECK:STDOUT:   %CallTakeIncomplete: type = fn_type @CallTakeIncomplete [template]
-// CHECK:STDOUT:   %struct.10: CallTakeIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.11: CallTakeIncomplete = struct_value () [template]
 // CHECK:STDOUT:   %CallReturnIncomplete: type = fn_type @CallReturnIncomplete [template]
-// CHECK:STDOUT:   %struct.11: CallReturnIncomplete = struct_value () [template]
+// CHECK:STDOUT:   %struct.12: CallReturnIncomplete = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -189,21 +191,29 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:     %Class.ref.loc45: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     @ConvertFromStruct.%return: ref Class = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.4] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.5] {
 // CHECK:STDOUT:     %Class.ref.loc47: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc47: type = ptr_type Class [template = constants.%.4]
+// CHECK:STDOUT:     %.loc47_14: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc47_6.1: Class* = param p
 // CHECK:STDOUT:     @G.%p: Class* = bind_name p, %p.loc47_6.1
+// CHECK:STDOUT:     %int.make_type_32.loc47: init type = call constants.%struct.4() [template = i32]
+// CHECK:STDOUT:     %.loc47_20.1: type = value_of_initializer %int.make_type_32.loc47 [template = i32]
+// CHECK:STDOUT:     %.loc47_20.2: type = converted %int.make_type_32.loc47, %.loc47_20.1 [template = i32]
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %MemberAccess.decl: MemberAccess = fn_decl @MemberAccess [template = constants.%struct.5] {
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.4]
+// CHECK:STDOUT:   %MemberAccess.decl: MemberAccess = fn_decl @MemberAccess [template = constants.%struct.6] {
 // CHECK:STDOUT:     %Class.ref.loc58: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc58: type = ptr_type Class [template = constants.%.4]
+// CHECK:STDOUT:     %.loc58_25: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc58_17.1: Class* = param p
 // CHECK:STDOUT:     @MemberAccess.%p: Class* = bind_name p, %p.loc58_17.1
+// CHECK:STDOUT:     %int.make_type_32.loc58: init type = call constants.%struct.4() [template = i32]
+// CHECK:STDOUT:     %.loc58_31.1: type = value_of_initializer %int.make_type_32.loc58 [template = i32]
+// CHECK:STDOUT:     %.loc58_31.2: type = converted %int.make_type_32.loc58, %.loc58_31.1 [template = i32]
 // CHECK:STDOUT:     @MemberAccess.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Copy.decl: Copy = fn_decl @Copy [template = constants.%struct.6] {
+// CHECK:STDOUT:   %Copy.decl: Copy = fn_decl @Copy [template = constants.%struct.7] {
 // CHECK:STDOUT:     %Class.ref.loc76_12: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc76: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc76_9.1: Class* = param p
@@ -211,28 +221,28 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:     %Class.ref.loc76_23: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     @Copy.%return: ref Class = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Let.decl: Let = fn_decl @Let [template = constants.%struct.7] {
+// CHECK:STDOUT:   %Let.decl: Let = fn_decl @Let [template = constants.%struct.8] {
 // CHECK:STDOUT:     %Class.ref.loc80: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc80: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc80_8.1: Class* = param p
 // CHECK:STDOUT:     @Let.%p: Class* = bind_name p, %p.loc80_8.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %TakeIncomplete.decl: TakeIncomplete = fn_decl @TakeIncomplete [template = constants.%struct.8] {
+// CHECK:STDOUT:   %TakeIncomplete.decl: TakeIncomplete = fn_decl @TakeIncomplete [template = constants.%struct.9] {
 // CHECK:STDOUT:     %Class.ref.loc91: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %c.loc91_19.1: Class = param c
 // CHECK:STDOUT:     @TakeIncomplete.%c: Class = bind_name c, %c.loc91_19.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %ReturnIncomplete.decl: ReturnIncomplete = fn_decl @ReturnIncomplete [template = constants.%struct.9] {
+// CHECK:STDOUT:   %ReturnIncomplete.decl: ReturnIncomplete = fn_decl @ReturnIncomplete [template = constants.%struct.10] {
 // CHECK:STDOUT:     %Class.ref.loc93: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     @ReturnIncomplete.%return: ref Class = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %CallTakeIncomplete.decl: CallTakeIncomplete = fn_decl @CallTakeIncomplete [template = constants.%struct.10] {
+// CHECK:STDOUT:   %CallTakeIncomplete.decl: CallTakeIncomplete = fn_decl @CallTakeIncomplete [template = constants.%struct.11] {
 // CHECK:STDOUT:     %Class.ref.loc95: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:     %.loc95: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc95_23.1: Class* = param p
 // CHECK:STDOUT:     @CallTakeIncomplete.%p: Class* = bind_name p, %p.loc95_23.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %CallReturnIncomplete.decl: CallReturnIncomplete = fn_decl @CallReturnIncomplete [template = constants.%struct.11] {}
+// CHECK:STDOUT:   %CallReturnIncomplete.decl: CallReturnIncomplete = fn_decl @CallReturnIncomplete [template = constants.%struct.12] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class;
@@ -255,6 +265,8 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @G(%p: Class*) -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %p.ref: Class* = name_ref p, %p
@@ -291,11 +303,11 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallTakeIncomplete(%p: Class*) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TakeIncomplete.ref.loc106: TakeIncomplete = name_ref TakeIncomplete, file.%TakeIncomplete.decl [template = constants.%struct.8]
+// CHECK:STDOUT:   %TakeIncomplete.ref.loc106: TakeIncomplete = name_ref TakeIncomplete, file.%TakeIncomplete.decl [template = constants.%struct.9]
 // CHECK:STDOUT:   %p.ref: Class* = name_ref p, %p
 // CHECK:STDOUT:   %.loc106: ref Class = deref %p.ref
 // CHECK:STDOUT:   %TakeIncomplete.call.loc106: init () = call %TakeIncomplete.ref.loc106(<invalid>) [template = <error>]
-// CHECK:STDOUT:   %TakeIncomplete.ref.loc118: TakeIncomplete = name_ref TakeIncomplete, file.%TakeIncomplete.decl [template = constants.%struct.8]
+// CHECK:STDOUT:   %TakeIncomplete.ref.loc118: TakeIncomplete = name_ref TakeIncomplete, file.%TakeIncomplete.decl [template = constants.%struct.9]
 // CHECK:STDOUT:   %.loc118: {} = struct_literal ()
 // CHECK:STDOUT:   %TakeIncomplete.call.loc118: init () = call %TakeIncomplete.ref.loc118(<invalid>) [template = <error>]
 // CHECK:STDOUT:   return
@@ -303,7 +315,7 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallReturnIncomplete() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %ReturnIncomplete.ref: ReturnIncomplete = name_ref ReturnIncomplete, file.%ReturnIncomplete.decl [template = constants.%struct.9]
+// CHECK:STDOUT:   %ReturnIncomplete.ref: ReturnIncomplete = name_ref ReturnIncomplete, file.%ReturnIncomplete.decl [template = constants.%struct.10]
 // CHECK:STDOUT:   %ReturnIncomplete.call: init <error> = call %ReturnIncomplete.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 21 - 9
toolchain/check/testdata/class/fail_init.carbon

@@ -30,11 +30,13 @@ fn F() {
 // 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 {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %.3: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.4: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.5: type = struct_type {.a: i32} [template]
 // CHECK:STDOUT:   %.6: type = ptr_type {.a: i32, .b: i32} [template]
@@ -52,19 +54,29 @@ fn F() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32.loc8, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Class> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_10.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %int.make_type_32.loc9, %.loc9_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc9_8: <unbound element of class Class> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .a = %.loc8
-// CHECK:STDOUT:   .b = %.loc9
+// CHECK:STDOUT:   .a = %.loc8_8
+// CHECK:STDOUT:   .b = %.loc9_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc17_9: i32 = int_literal 1 [template = constants.%.4]

+ 28 - 16
toolchain/check/testdata/class/fail_init_as_inplace.carbon

@@ -26,18 +26,20 @@ fn F() {
 // 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 {.a: i32, .b: i32} [template]
-// CHECK:STDOUT:   %.3: type = ptr_type Class [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.4: type = ptr_type Class [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %.4: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
 // CHECK:STDOUT:   %F: type = fn_type @F [template]
-// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: F = struct_value () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT:   %.6: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %.7: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %struct.3: Class = struct_value (%.6, %.7) [template]
+// CHECK:STDOUT:   %struct.4: Class = struct_value (%.6, %.7) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -49,25 +51,35 @@ fn F() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.1] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
 // CHECK:STDOUT:     %Class.ref: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc12: type = ptr_type Class [template = constants.%.3]
+// CHECK:STDOUT:     %.loc12: type = ptr_type Class [template = constants.%.4]
 // CHECK:STDOUT:     %p.loc12_6.1: Class* = param p
 // CHECK:STDOUT:     @G.%p: Class* = bind_name p, %p.loc12_6.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.3] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl a, element0 [template]
-// CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %int.make_type_32.loc8, %.loc8_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Class> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc9_10.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %int.make_type_32.loc9, %.loc9_10.1 [template = i32]
+// CHECK:STDOUT:   %.loc9_8: <unbound element of class Class> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .a = %.loc8
-// CHECK:STDOUT:   .b = %.loc9
+// CHECK:STDOUT:   .a = %.loc8_8
+// CHECK:STDOUT:   .b = %.loc9_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @G(%p: Class*);
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
@@ -84,12 +96,12 @@ fn F() {
 // CHECK:STDOUT:   %.loc21_33.4: init i32 = initialize_from %.loc21_24 to %.loc21_33.3 [template = constants.%.6]
 // CHECK:STDOUT:   %.loc21_33.5: ref i32 = class_element_access %.loc21_33.2, element1
 // CHECK:STDOUT:   %.loc21_33.6: init i32 = initialize_from %.loc21_32 to %.loc21_33.5 [template = constants.%.7]
-// CHECK:STDOUT:   %.loc21_33.7: init Class = class_init (%.loc21_33.4, %.loc21_33.6), %.loc21_33.2 [template = constants.%struct.3]
+// CHECK:STDOUT:   %.loc21_33.7: init Class = class_init (%.loc21_33.4, %.loc21_33.6), %.loc21_33.2 [template = constants.%struct.4]
 // CHECK:STDOUT:   %.loc21_33.8: ref Class = temporary %.loc21_33.2, %.loc21_33.7
 // CHECK:STDOUT:   %.loc21_35.1: ref Class = converted %.loc21_33.1, %.loc21_33.8
 // CHECK:STDOUT:   %.loc21_35.2: Class = bind_value %.loc21_35.1
 // CHECK:STDOUT:   assign %c.var, <error>
-// CHECK:STDOUT:   %G.ref: G = name_ref G, file.%G.decl [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.ref: G = name_ref G, file.%G.decl [template = constants.%struct.2]
 // CHECK:STDOUT:   %c.ref: ref Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc22: Class* = addr_of %c.ref
 // CHECK:STDOUT:   %G.call: init () = call %G.ref(%.loc22)

+ 13 - 5
toolchain/check/testdata/class/fail_member_of_let.carbon

@@ -22,12 +22,14 @@ fn T.F() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
-// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: type = fn_type @.1 [template]
-// CHECK:STDOUT:   %struct.2: <invalid> = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: <invalid> = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -37,13 +39,17 @@ fn T.F() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
+// CHECK:STDOUT:   %import_ref: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, %Class.decl [template = constants.%Class]
 // CHECK:STDOUT:   %T: type = bind_name T, %Class.ref
-// CHECK:STDOUT:   %.decl: <invalid> = fn_decl @.1 [template = constants.%struct.2] {}
+// CHECK:STDOUT:   %.decl: <invalid> = fn_decl @.1 [template = constants.%struct.3] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_13.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc8_13.2: type = converted %int.make_type_32, %.loc8_13.1 [template = i32]
 // CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
@@ -52,6 +58,8 @@ fn T.F() {}
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32;
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @.1() {

+ 17 - 5
toolchain/check/testdata/class/fail_scope.carbon

@@ -21,13 +21,15 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
-// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %Int32: type = fn_type @Int32 [template]
 // CHECK:STDOUT:   %.1: type = tuple_type () [template]
-// CHECK:STDOUT:   %struct.1: F = struct_value () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %F: type = fn_type @F [template]
+// CHECK:STDOUT:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
 // CHECK:STDOUT:   %.3: i32 = int_literal 1 [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: G = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -38,13 +40,21 @@ fn G() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc13_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc13_11.2: type = converted %int.make_type_32, %.loc13_11.1 [template = i32]
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc8_13.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc8_13.2: type = converted %int.make_type_32, %.loc8_13.1 [template = i32]
 // CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
@@ -53,6 +63,8 @@ fn G() -> i32 {
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc9: i32 = int_literal 1 [template = constants.%.3]

+ 14 - 7
toolchain/check/testdata/class/fail_self_type_member.carbon

@@ -25,26 +25,33 @@ fn F() -> bool {
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
-// CHECK:STDOUT:   %.1: type = unbound_element_type Class, bool [template]
-// CHECK:STDOUT:   %.2: type = struct_type {.b: bool} [template]
+// CHECK:STDOUT:   %Bool: type = fn_type @Bool [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Bool = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, bool [template]
+// CHECK:STDOUT:   %.3: type = struct_type {.b: bool} [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:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.4: type = ptr_type {.b: bool} [template]
 // CHECK:STDOUT:   %.5: bool = bool_literal true [template]
-// CHECK:STDOUT:   %struct.2: Class = struct_value (%.5) [template]
+// CHECK:STDOUT:   %struct.3: Class = struct_value (%.5) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl b, element0 [template]
+// CHECK:STDOUT:   %bool.make_type: init type = call constants.%struct.1() [template = bool]
+// CHECK:STDOUT:   %.loc8_10.1: type = value_of_initializer %bool.make_type [template = bool]
+// CHECK:STDOUT:   %.loc8_10.2: type = converted %bool.make_type, %.loc8_10.1 [template = bool]
+// CHECK:STDOUT:   %.loc8_8: <unbound element of class Class> = field_decl b, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .b = %.loc8
+// CHECK:STDOUT:   .b = %.loc8_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Bool() -> type = "bool.make_type";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: }

+ 26 - 14
toolchain/check/testdata/class/fail_todo_modifiers.carbon

@@ -75,21 +75,23 @@ abstract class Abstract {
 // 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %struct.3: Int32 = struct_value () [template]
 // CHECK:STDOUT:   %.2: type = unbound_element_type Access, i32 [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.k: i32, .l: i32} [template]
 // CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %H: type = fn_type @H [template]
-// CHECK:STDOUT:   %struct.3: H = struct_value () [template]
+// CHECK:STDOUT:   %struct.4: H = struct_value () [template]
 // CHECK:STDOUT:   %I: type = fn_type @I [template]
-// CHECK:STDOUT:   %struct.4: I = struct_value () [template]
+// CHECK:STDOUT:   %struct.5: I = struct_value () [template]
 // CHECK:STDOUT:   %.4: type = struct_type {} [template]
 // CHECK:STDOUT:   %Abstract: type = class_type @Abstract [template]
 // CHECK:STDOUT:   %J: type = fn_type @J [template]
-// CHECK:STDOUT:   %struct.5: J = struct_value () [template]
+// CHECK:STDOUT:   %struct.6: J = struct_value () [template]
 // CHECK:STDOUT:   %K: type = fn_type @K [template]
-// CHECK:STDOUT:   %struct.6: K = struct_value () [template]
+// CHECK:STDOUT:   %struct.7: K = struct_value () [template]
 // CHECK:STDOUT:   %L: type = fn_type @L [template]
-// CHECK:STDOUT:   %struct.7: L = struct_value () [template]
+// CHECK:STDOUT:   %struct.8: L = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -101,6 +103,8 @@ abstract class Abstract {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Access.decl: type = class_decl @Access [template = constants.%Access] {}
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.3]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.3]
 // CHECK:STDOUT:   %Base.decl: type = class_decl @Base [template = constants.%Base] {}
 // CHECK:STDOUT:   %Abstract.decl: type = class_decl @Abstract [template = constants.%Abstract] {}
 // CHECK:STDOUT: }
@@ -108,20 +112,26 @@ abstract class Abstract {
 // CHECK:STDOUT: class @Access {
 // CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {}
 // CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {}
-// CHECK:STDOUT:   %.loc25: <unbound element of class Access> = field_decl k, element0 [template]
-// CHECK:STDOUT:   %.loc31: <unbound element of class Access> = field_decl l, element1 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc25: init type = call constants.%struct.3() [template = i32]
+// CHECK:STDOUT:   %.loc25_18.1: type = value_of_initializer %int.make_type_32.loc25 [template = i32]
+// CHECK:STDOUT:   %.loc25_18.2: type = converted %int.make_type_32.loc25, %.loc25_18.1 [template = i32]
+// CHECK:STDOUT:   %.loc25_16: <unbound element of class Access> = field_decl k, element0 [template]
+// CHECK:STDOUT:   %int.make_type_32.loc31: init type = call constants.%struct.3() [template = i32]
+// CHECK:STDOUT:   %.loc31_20.1: type = value_of_initializer %int.make_type_32.loc31 [template = i32]
+// CHECK:STDOUT:   %.loc31_20.2: type = converted %int.make_type_32.loc31, %.loc31_20.1 [template = i32]
+// CHECK:STDOUT:   %.loc31_18: <unbound element of class Access> = field_decl l, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Access
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT:   .G = %G.decl
-// CHECK:STDOUT:   .k = %.loc25
-// CHECK:STDOUT:   .l = %.loc31
+// CHECK:STDOUT:   .k = %.loc25_16
+// CHECK:STDOUT:   .l = %.loc31_18
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %H.decl: H = fn_decl @H [template = constants.%struct.3] {}
-// CHECK:STDOUT:   %I.decl: I = fn_decl @I [template = constants.%struct.4] {}
+// CHECK:STDOUT:   %H.decl: H = fn_decl @H [template = constants.%struct.4] {}
+// CHECK:STDOUT:   %I.decl: I = fn_decl @I [template = constants.%struct.5] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Base
@@ -130,9 +140,9 @@ abstract class Abstract {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Abstract {
-// CHECK:STDOUT:   %J.decl: J = fn_decl @J [template = constants.%struct.5] {}
-// CHECK:STDOUT:   %K.decl: K = fn_decl @K [template = constants.%struct.6] {}
-// CHECK:STDOUT:   %L.decl: L = fn_decl @L [template = constants.%struct.7] {}
+// CHECK:STDOUT:   %J.decl: J = fn_decl @J [template = constants.%struct.6] {}
+// CHECK:STDOUT:   %K.decl: K = fn_decl @K [template = constants.%struct.7] {}
+// CHECK:STDOUT:   %L.decl: L = fn_decl @L [template = constants.%struct.8] {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Abstract
@@ -145,6 +155,8 @@ abstract class Abstract {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G();
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @H();
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @I();

+ 26 - 10
toolchain/check/testdata/class/fail_unbound_field.carbon

@@ -26,13 +26,15 @@ fn G() -> 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:   %Int32: type = fn_type @Int32 [template]
+// CHECK:STDOUT:   %.1: type = tuple_type () [template]
+// CHECK:STDOUT:   %struct.1: Int32 = struct_value () [template]
+// CHECK:STDOUT:   %.2: type = unbound_element_type Class, i32 [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:   %struct.2: F = struct_value () [template]
 // CHECK:STDOUT:   %.3: type = struct_type {.field: i32} [template]
 // CHECK:STDOUT:   %G: type = fn_type @G [template]
-// CHECK:STDOUT:   %struct.2: G = struct_value () [template]
+// CHECK:STDOUT:   %struct.3: G = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -43,33 +45,47 @@ fn G() -> i32 {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Class.decl: type = class_decl @Class [template = constants.%Class] {}
-// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.2] {
+// CHECK:STDOUT:   %import_ref.1: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.2: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %import_ref.3: Int32 = import_ref ir3, inst+3, loaded [template = constants.%struct.1]
+// CHECK:STDOUT:   %G.decl: G = fn_decl @G [template = constants.%struct.3] {
+// CHECK:STDOUT:     %int.make_type_32: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc18_11.1: type = value_of_initializer %int.make_type_32 [template = i32]
+// CHECK:STDOUT:     %.loc18_11.2: type = converted %int.make_type_32, %.loc18_11.1 [template = i32]
 // CHECK:STDOUT:     @G.%return: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl field, element0 [template]
-// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.1] {
+// CHECK:STDOUT:   %int.make_type_32.loc8: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:   %.loc8_14.1: type = value_of_initializer %int.make_type_32.loc8 [template = i32]
+// CHECK:STDOUT:   %.loc8_14.2: type = converted %int.make_type_32.loc8, %.loc8_14.1 [template = i32]
+// CHECK:STDOUT:   %.loc8_12: <unbound element of class Class> = field_decl field, element0 [template]
+// CHECK:STDOUT:   %F.decl: F = fn_decl @F [template = constants.%struct.2] {
+// CHECK:STDOUT:     %int.make_type_32.loc9: init type = call constants.%struct.1() [template = i32]
+// CHECK:STDOUT:     %.loc9_13.1: type = value_of_initializer %int.make_type_32.loc9 [template = i32]
+// CHECK:STDOUT:     %.loc9_13.2: type = converted %int.make_type_32.loc9, %.loc9_13.1 [template = i32]
 // CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = constants.%Class
-// CHECK:STDOUT:   .field = %.loc8
+// CHECK:STDOUT:   .field = %.loc8_12
 // CHECK:STDOUT:   .F = %F.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32";
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%.loc8 [template = @Class.%.loc8]
+// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%.loc8_12 [template = @Class.%.loc8_12]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%.loc8 [template = @Class.%.loc8]
+// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%.loc8_12 [template = @Class.%.loc8_12]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

Some files were not shown because too many files changed in this diff