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

Make snegate / unegate overflow handling consistent with other builtins. (#4744)

Make `int.snegate` ignore the signedness of its operand and
unconditionally check for signed overflow like all the other `int.s*`
builtins do. Fix the prelude implementation of unary `-` for `Core.UInt`
to use `int.unegate` instead of `int.snegate`.

Fix the test for unsigned negate to actually test negating unsigned
integers, and add some tests that unary `-` also works.
Richard Smith 1 год назад
Родитель
Сommit
7d8d59cb7e

+ 1 - 1
core/prelude/types/uint.carbon

@@ -66,7 +66,7 @@ impl forall [N:! IntLiteral()] UInt(N) as Mul {
 }
 }
 
 
 impl forall [N:! IntLiteral()] UInt(N) as Negate {
 impl forall [N:! IntLiteral()] UInt(N) as Negate {
-  fn Op[self: Self]() -> Self = "int.snegate";
+  fn Op[self: Self]() -> Self = "int.unegate";
 }
 }
 
 
 impl forall [N:! IntLiteral()] UInt(N) as Sub {
 impl forall [N:! IntLiteral()] UInt(N) as Sub {

+ 1 - 1
toolchain/check/eval.cpp

@@ -783,7 +783,7 @@ static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc,
 
 
   switch (builtin_kind) {
   switch (builtin_kind) {
     case SemIR::BuiltinFunctionKind::IntSNegate:
     case SemIR::BuiltinFunctionKind::IntSNegate:
-      if (is_signed && op_val.isMinSignedValue()) {
+      if (op_val.isMinSignedValue()) {
         CARBON_DIAGNOSTIC(CompileTimeIntegerNegateOverflow, Error,
         CARBON_DIAGNOSTIC(CompileTimeIntegerNegateOverflow, Error,
                           "integer overflow in negation of {0}", TypedInt);
                           "integer overflow in negation of {0}", TypedInt);
         context.emitter().Emit(loc, CompileTimeIntegerNegateOverflow,
         context.emitter().Emit(loc, CompileTimeIntegerNegateOverflow,

+ 465 - 272
toolchain/check/testdata/builtins/int/unegate.carbon

@@ -10,14 +10,14 @@
 
 
 // --- int_negate.carbon
 // --- int_negate.carbon
 
 
-fn Negate(a: i32) -> i32 = "int.unegate";
+fn Negate(a: u32) -> u32 = "int.unegate";
 
 
-var arr: [i32; Negate(Negate(123))];
-let arr_p: [i32; 123]* = &arr;
+var arr: [u32; Negate(Negate(123))];
+let arr_p: [u32; 123]* = &arr;
 
 
-let n: i32 = Negate(1);
+let n: u32 = Negate(1);
 
 
-fn RuntimeCall(a: i32, b: i32) -> i32 {
+fn RuntimeCall(a: u32, b: u32) -> u32 {
   return Negate(a);
   return Negate(a);
 }
 }
 
 
@@ -26,75 +26,75 @@ fn RuntimeCall(a: i32, b: i32) -> i32 {
 package FailBadDecl;
 package FailBadDecl;
 
 
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
-// CHECK:STDERR: fn TooFew() -> i32 = "int.unegate";
+// CHECK:STDERR: fn TooFew() -> u32 = "int.unegate";
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-fn TooFew() -> i32 = "int.unegate";
+fn TooFew() -> u32 = "int.unegate";
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
-// CHECK:STDERR: fn TooMany(a: i32, b: i32) -> i32 = "int.unegate";
+// CHECK:STDERR: fn TooMany(a: u32, b: u32) -> u32 = "int.unegate";
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-fn TooMany(a: i32, b: i32) -> i32 = "int.unegate";
+fn TooMany(a: u32, b: u32) -> u32 = "int.unegate";
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.unegate" [InvalidBuiltinSignature]
-// CHECK:STDERR: fn BadReturnType(a: i32) -> bool = "int.unegate";
+// CHECK:STDERR: fn BadReturnType(a: u32) -> bool = "int.unegate";
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-fn BadReturnType(a: i32) -> bool = "int.unegate";
-fn JustRight(a: i32) -> i32 = "int.unegate";
+fn BadReturnType(a: u32) -> bool = "int.unegate";
+fn JustRight(a: u32) -> u32 = "int.unegate";
 
 
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:20: error: array bound is not a constant [InvalidArrayExpr]
-// CHECK:STDERR: var too_few: [i32; TooFew()];
+// CHECK:STDERR: var too_few: [u32; TooFew()];
 // CHECK:STDERR:                    ^~~~~~~~
 // CHECK:STDERR:                    ^~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-var too_few: [i32; TooFew()];
+var too_few: [u32; TooFew()];
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:21: error: array bound is not a constant [InvalidArrayExpr]
-// CHECK:STDERR: var too_many: [i32; TooMany(1, 2)];
+// CHECK:STDERR: var too_many: [u32; TooMany(1, 2)];
 // CHECK:STDERR:                     ^~~~~~~~~~~~~
 // CHECK:STDERR:                     ^~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-var too_many: [i32; TooMany(1, 2)];
+var too_many: [u32; TooMany(1, 2)];
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:28: error: array bound is not a constant [InvalidArrayExpr]
-// CHECK:STDERR: var bad_return_type: [i32; BadReturnType(1)];
+// CHECK:STDERR: var bad_return_type: [u32; BadReturnType(1)];
 // CHECK:STDERR:                            ^~~~~~~~~~~~~~~~
 // CHECK:STDERR:                            ^~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-var bad_return_type: [i32; BadReturnType(1)];
+var bad_return_type: [u32; BadReturnType(1)];
 
 
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:21: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch]
-// CHECK:STDERR: var bad_call: [i32; JustRight(1, 2)];
+// CHECK:STDERR: var bad_call: [u32; JustRight(1, 2)];
 // CHECK:STDERR:                     ^~~~~~~~~~~~~~~
 // CHECK:STDERR:                     ^~~~~~~~~~~~~~~
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-21]]:1: note: calling function declared here [InCallToEntity]
 // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-21]]:1: note: calling function declared here [InCallToEntity]
-// CHECK:STDERR: fn JustRight(a: i32) -> i32 = "int.unegate";
+// CHECK:STDERR: fn JustRight(a: u32) -> u32 = "int.unegate";
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:
 // CHECK:STDERR:
-var bad_call: [i32; JustRight(1, 2)];
+var bad_call: [u32; JustRight(1, 2)];
 
 
-fn RuntimeCallTooFew(a: i32) -> i32 {
+fn RuntimeCallTooFew(a: u32) -> u32 {
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 1 argument passed to function expecting 0 arguments [CallArgCountMismatch]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 1 argument passed to function expecting 0 arguments [CallArgCountMismatch]
   // CHECK:STDERR:   return TooFew(a);
   // CHECK:STDERR:   return TooFew(a);
   // CHECK:STDERR:          ^~~~~~~~~
   // CHECK:STDERR:          ^~~~~~~~~
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-42]]:1: note: calling function declared here [InCallToEntity]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-42]]:1: note: calling function declared here [InCallToEntity]
-  // CHECK:STDERR: fn TooFew() -> i32 = "int.unegate";
+  // CHECK:STDERR: fn TooFew() -> u32 = "int.unegate";
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   // CHECK:STDERR:
   return TooFew(a);
   return TooFew(a);
 }
 }
 
 
-fn RuntimeCallTooMany(a: i32, b: i32, c: i32) -> i32 {
+fn RuntimeCallTooMany(a: u32, b: u32, c: u32) -> u32 {
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+7]]:10: error: 3 arguments passed to function expecting 2 arguments [CallArgCountMismatch]
   // CHECK:STDERR:   return TooMany(a, b, c);
   // CHECK:STDERR:   return TooMany(a, b, c);
   // CHECK:STDERR:          ^~~~~~~~~~~~~~~~
   // CHECK:STDERR:          ^~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-48]]:1: note: calling function declared here [InCallToEntity]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-48]]:1: note: calling function declared here [InCallToEntity]
-  // CHECK:STDERR: fn TooMany(a: i32, b: i32) -> i32 = "int.unegate";
+  // CHECK:STDERR: fn TooMany(a: u32, b: u32) -> u32 = "int.unegate";
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:
   // CHECK:STDERR:
   return TooMany(a, b, c);
   return TooMany(a, b, c);
 }
 }
 
 
-fn RuntimeCallBadReturnType(a: i32, b: i32) -> bool {
+fn RuntimeCallBadReturnType(a: u32, b: u32) -> bool {
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+6]]:10: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+6]]:10: error: 2 arguments passed to function expecting 1 argument [CallArgCountMismatch]
   // CHECK:STDERR:   return BadReturnType(a, b);
   // CHECK:STDERR:   return BadReturnType(a, b);
   // CHECK:STDERR:          ^~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR:          ^~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-54]]:1: note: calling function declared here [InCallToEntity]
   // CHECK:STDERR: fail_bad_decl.carbon:[[@LINE-54]]:1: note: calling function declared here [InCallToEntity]
-  // CHECK:STDERR: fn BadReturnType(a: i32) -> bool = "int.unegate";
+  // CHECK:STDERR: fn BadReturnType(a: u32) -> bool = "int.unegate";
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   return BadReturnType(a, b);
   return BadReturnType(a, b);
 }
 }
@@ -103,41 +103,47 @@ fn RuntimeCallBadReturnType(a: i32, b: i32) -> bool {
 
 
 package Overflow;
 package Overflow;
 
 
-fn Negate(a: i32) -> i32 = "int.unegate";
-fn Sub(a: i32, b: i32) -> i32 = "int.usub";
+fn Negate(a: u32) -> u32 = "int.unegate";
 
 
-// -(-INT_MAX) is INT_MAX.
-let a: i32 = Negate(Negate(0x7FFFFFFF));
+class Expect(N:! u32) {}
+fn Test(N:! u32) -> Expect(N) { return {}; }
+
+fn F() {
+  // -(-INT_MAX) is INT_MAX.
+  Test(Negate(Negate(0x7FFF_FFFF))) as Expect(0x7FFF_FFFF);
+  Test(-(Negate(0x7FFF_FFFF))) as Expect(0x7FFF_FFFF);
+  // -(-(INT_MAX + 1)) is `INT_MAX + 1`.
+  Test(Negate(Negate(0x8000_0000))) as Expect(0x8000_0000);
+  Test(-(Negate(0x8000_0000))) as Expect(0x8000_0000);
+}
 
 
-// -(-INT_MAX - 1) wraps around to INT_MIN.
-let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 
 
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT: --- int_negate.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
-// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
+// CHECK:STDOUT:   %u32: type = class_type @UInt, @UInt(%int_32) [template]
 // CHECK:STDOUT:   %Negate.type.1: type = fn_type @Negate.1 [template]
 // CHECK:STDOUT:   %Negate.type.1: type = fn_type @Negate.1 [template]
 // CHECK:STDOUT:   %Negate: %Negate.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %Negate: %Negate.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %int_123.1: Core.IntLiteral = int_value 123 [template]
 // CHECK:STDOUT:   %int_123.1: Core.IntLiteral = int_value 123 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%u32) [template]
 // CHECK:STDOUT:   %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
 // CHECK:STDOUT:   %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
 // CHECK:STDOUT:   %Convert.10: %Convert.type.10 = struct_value () [template]
 // CHECK:STDOUT:   %Convert.10: %Convert.type.10 = struct_value () [template]
 // CHECK:STDOUT:   %interface.19: <witness> = interface_witness (%Convert.10) [template]
 // CHECK:STDOUT:   %interface.19: <witness> = interface_witness (%Convert.10) [template]
-// CHECK:STDOUT:   %array_type: type = array_type %int_123.1, %i32 [template]
+// CHECK:STDOUT:   %array_type: type = array_type %int_123.1, %u32 [template]
 // CHECK:STDOUT:   %ptr: type = ptr_type %array_type [template]
 // CHECK:STDOUT:   %ptr: type = ptr_type %array_type [template]
 // CHECK:STDOUT:   %int_1.1: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT:   %int_1.1: Core.IntLiteral = int_value 1 [template]
 // CHECK:STDOUT:   %Convert.bound.3: <bound method> = bound_method %int_1.1, %Convert.10 [template]
 // CHECK:STDOUT:   %Convert.bound.3: <bound method> = bound_method %int_1.1, %Convert.10 [template]
 // CHECK:STDOUT:   %Convert.specific_fn.3: <specific function> = specific_function %Convert.bound.3, @Convert.2(%int_32) [template]
 // CHECK:STDOUT:   %Convert.specific_fn.3: <specific function> = specific_function %Convert.bound.3, @Convert.2(%int_32) [template]
-// CHECK:STDOUT:   %int_1.2: %i32 = int_value 1 [template]
-// CHECK:STDOUT:   %int_-1: %i32 = int_value -1 [template]
+// CHECK:STDOUT:   %int_1.2: %u32 = int_value 1 [template]
+// CHECK:STDOUT:   %int_4294967295: %u32 = int_value 4294967295 [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall.type: type = fn_type @RuntimeCall [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT:   %RuntimeCall: %RuntimeCall.type = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int = %import_ref.1
+// CHECK:STDOUT:     .UInt = %import_ref.1
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.5
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.5
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:     import Core//prelude/...
@@ -155,60 +161,60 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Negate.decl: %Negate.type.1 = fn_decl @Negate.1 [template = constants.%Negate] {
 // CHECK:STDOUT:   %Negate.decl: %Negate.type.1 = fn_decl @Negate.1 [template = constants.%Negate] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc2_22: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc2_22: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc2_22: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc2: type = splice_block %i32.loc2_14 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc2_22: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc2: type = splice_block %u32.loc2_14 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc2_14: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc2_14: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc2_14: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc2_14: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %arr.var: ref %array_type = var arr
 // CHECK:STDOUT:   %arr.var: ref %array_type = var arr
 // CHECK:STDOUT:   %arr: ref %array_type = bind_name arr, %arr.var
 // CHECK:STDOUT:   %arr: ref %array_type = bind_name arr, %arr.var
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
 // CHECK:STDOUT:   %RuntimeCall.decl: %RuntimeCall.type = fn_decl @RuntimeCall [template = constants.%RuntimeCall] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %b.patt: %i32 = binding_pattern b
-// CHECK:STDOUT:     %b.param_patt: %i32 = value_param_pattern %b.patt, runtime_param1
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param2
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %b.patt: %u32 = binding_pattern b
+// CHECK:STDOUT:     %b.param_patt: %u32 = value_param_pattern %b.patt, runtime_param1
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc9_35: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc9_35: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc9_35: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc9_19: type = splice_block %i32.loc9_19 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc9_35: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc9_19: type = splice_block %u32.loc9_19 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc9_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc9_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc9_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc9_19: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %b.param: %i32 = value_param runtime_param1
-// CHECK:STDOUT:     %.loc9_27: type = splice_block %i32.loc9_27 [template = constants.%i32] {
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %b.param: %u32 = value_param runtime_param1
+// CHECK:STDOUT:     %.loc9_27: type = splice_block %u32.loc9_27 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc9_27: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc9_27: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc9_27: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc9_27: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %b: %i32 = bind_name b, %b.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %b: %u32 = bind_name b, %b.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param2
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Negate.1(%a.param_patt: %i32) -> %i32 = "int.unegate";
+// CHECK:STDOUT: fn @Negate.1(%a.param_patt: %u32) -> %u32 = "int.unegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @RuntimeCall(%a.param_patt: %i32, %b.param_patt: %i32) -> %i32 {
+// CHECK:STDOUT: fn @RuntimeCall(%a.param_patt: %u32, %b.param_patt: %u32) -> %u32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Negate.ref: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
 // CHECK:STDOUT:   %Negate.ref: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// 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
-// CHECK:STDOUT:   %.loc10_19.2: %i32 = converted %int.unegate, %.loc10_19.1
+// CHECK:STDOUT:   %a.ref: %u32 = name_ref a, %a
+// CHECK:STDOUT:   %int.unegate: init %u32 = call %Negate.ref(%a.ref)
+// CHECK:STDOUT:   %.loc10_19.1: %u32 = value_of_initializer %int.unegate
+// CHECK:STDOUT:   %.loc10_19.2: %u32 = converted %int.unegate, %.loc10_19.1
 // CHECK:STDOUT:   return %.loc10_19.2
 // CHECK:STDOUT:   return %.loc10_19.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -222,13 +228,13 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %impl.elem0: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
 // CHECK:STDOUT:   %impl.elem0: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
 // CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_1, %impl.elem0 [template = constants.%Convert.bound.3]
 // CHECK:STDOUT:   %Convert.bound: <bound method> = bound_method %int_1, %impl.elem0 [template = constants.%Convert.bound.3]
 // CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.3]
 // CHECK:STDOUT:   %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.3]
-// CHECK:STDOUT:   %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_1) [template = constants.%int_1.2]
-// CHECK:STDOUT:   %.loc7_21.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_1.2]
-// CHECK:STDOUT:   %.loc7_21.2: %i32 = converted %int_1, %.loc7_21.1 [template = constants.%int_1.2]
-// CHECK:STDOUT:   %int.unegate: init %i32 = call %Negate.ref(%.loc7_21.2) [template = constants.%int_-1]
-// CHECK:STDOUT:   %.loc7_23.1: %i32 = value_of_initializer %int.unegate [template = constants.%int_-1]
-// CHECK:STDOUT:   %.loc7_23.2: %i32 = converted %int.unegate, %.loc7_23.1 [template = constants.%int_-1]
-// CHECK:STDOUT:   %n: %i32 = bind_name n, %.loc7_23.2
+// CHECK:STDOUT:   %int.convert_checked: init %u32 = call %Convert.specific_fn(%int_1) [template = constants.%int_1.2]
+// CHECK:STDOUT:   %.loc7_21.1: %u32 = value_of_initializer %int.convert_checked [template = constants.%int_1.2]
+// CHECK:STDOUT:   %.loc7_21.2: %u32 = converted %int_1, %.loc7_21.1 [template = constants.%int_1.2]
+// CHECK:STDOUT:   %int.unegate: init %u32 = call %Negate.ref(%.loc7_21.2) [template = constants.%int_4294967295]
+// CHECK:STDOUT:   %.loc7_23.1: %u32 = value_of_initializer %int.unegate [template = constants.%int_4294967295]
+// CHECK:STDOUT:   %.loc7_23.2: %u32 = converted %int.unegate, %.loc7_23.1 [template = constants.%int_4294967295]
+// CHECK:STDOUT:   %n: %u32 = bind_name n, %.loc7_23.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -236,7 +242,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
-// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
+// CHECK:STDOUT:   %u32: type = class_type @UInt, @UInt(%int_32) [template]
 // CHECK:STDOUT:   %TooFew.type: type = fn_type @TooFew [template]
 // CHECK:STDOUT:   %TooFew.type: type = fn_type @TooFew [template]
 // CHECK:STDOUT:   %TooFew: %TooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %TooFew: %TooFew.type = struct_value () [template]
 // CHECK:STDOUT:   %TooMany.type: type = fn_type @TooMany [template]
 // CHECK:STDOUT:   %TooMany.type: type = fn_type @TooMany [template]
@@ -257,7 +263,7 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int = %import_ref.1
+// CHECK:STDOUT:     .UInt = %import_ref.1
 // CHECK:STDOUT:     .Bool = %import_ref.5
 // CHECK:STDOUT:     .Bool = %import_ref.5
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.6
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.6
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude
@@ -282,73 +288,73 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %TooFew.decl: %TooFew.type = fn_decl @TooFew [template = constants.%TooFew] {
 // CHECK:STDOUT:   %TooFew.decl: %TooFew.type = fn_decl @TooFew [template = constants.%TooFew] {
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param0
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param0
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %u32: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param0
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TooMany.decl: %TooMany.type = fn_decl @TooMany [template = constants.%TooMany] {
 // CHECK:STDOUT:   %TooMany.decl: %TooMany.type = fn_decl @TooMany [template = constants.%TooMany] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %b.patt: %i32 = binding_pattern b
-// CHECK:STDOUT:     %b.param_patt: %i32 = value_param_pattern %b.patt, runtime_param1
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param2
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %b.patt: %u32 = binding_pattern b
+// CHECK:STDOUT:     %b.param_patt: %u32 = value_param_pattern %b.patt, runtime_param1
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc13_31: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc13_31: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc13_31: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc13_15: type = splice_block %i32.loc13_15 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc13_31: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc13_15: type = splice_block %u32.loc13_15 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc13_15: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc13_15: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc13_15: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc13_15: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %b.param: %i32 = value_param runtime_param1
-// CHECK:STDOUT:     %.loc13_23: type = splice_block %i32.loc13_23 [template = constants.%i32] {
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %b.param: %u32 = value_param runtime_param1
+// CHECK:STDOUT:     %.loc13_23: type = splice_block %u32.loc13_23 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc13_23: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc13_23: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc13_23: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc13_23: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %b: %i32 = bind_name b, %b.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %b: %u32 = bind_name b, %b.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param2
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %BadReturnType.decl: %BadReturnType.type = fn_decl @BadReturnType [template = constants.%BadReturnType] {
 // CHECK:STDOUT:   %BadReturnType.decl: %BadReturnType.type = fn_decl @BadReturnType [template = constants.%BadReturnType] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
 // CHECK:STDOUT:     %return.patt: bool = return_slot_pattern
 // CHECK:STDOUT:     %return.patt: bool = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: bool = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:     %return.param_patt: bool = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc18_29.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc18_29.2: type = converted %bool.make_type, %.loc18_29.1 [template = bool]
 // CHECK:STDOUT:     %.loc18_29.2: type = converted %bool.make_type, %.loc18_29.1 [template = bool]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc18_21: type = splice_block %i32 [template = constants.%i32] {
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc18_21: type = splice_block %u32 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
 // CHECK:STDOUT:     %return.param: ref bool = out_param runtime_param1
 // CHECK:STDOUT:     %return.param: ref bool = out_param runtime_param1
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %JustRight.decl: %JustRight.type = fn_decl @JustRight [template = constants.%JustRight] {
 // CHECK:STDOUT:   %JustRight.decl: %JustRight.type = fn_decl @JustRight [template = constants.%JustRight] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc19_25: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc19_25: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc19_25: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc19: type = splice_block %i32.loc19_17 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc19_25: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc19: type = splice_block %u32.loc19_17 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc19_17: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc19_17: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc19_17: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc19_17: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %too_few.var: ref <error> = var too_few
 // 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:   %too_few: ref <error> = bind_name too_few, %too_few.var
@@ -359,112 +365,112 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   %bad_call.var: ref <error> = var bad_call
 // 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:   %bad_call: ref <error> = bind_name bad_call, %bad_call.var
 // CHECK:STDOUT:   %RuntimeCallTooFew.decl: %RuntimeCallTooFew.type = fn_decl @RuntimeCallTooFew [template = constants.%RuntimeCallTooFew] {
 // CHECK:STDOUT:   %RuntimeCallTooFew.decl: %RuntimeCallTooFew.type = fn_decl @RuntimeCallTooFew [template = constants.%RuntimeCallTooFew] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc46_33: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc46_33: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc46_33: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc46: type = splice_block %i32.loc46_25 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc46_33: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc46: type = splice_block %u32.loc46_25 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc46_25: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc46_25: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc46_25: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc46_25: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %RuntimeCallTooMany.decl: %RuntimeCallTooMany.type = fn_decl @RuntimeCallTooMany [template = constants.%RuntimeCallTooMany] {
 // CHECK:STDOUT:   %RuntimeCallTooMany.decl: %RuntimeCallTooMany.type = fn_decl @RuntimeCallTooMany [template = constants.%RuntimeCallTooMany] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %b.patt: %i32 = binding_pattern b
-// CHECK:STDOUT:     %b.param_patt: %i32 = value_param_pattern %b.patt, runtime_param1
-// CHECK:STDOUT:     %c.patt: %i32 = binding_pattern c
-// CHECK:STDOUT:     %c.param_patt: %i32 = value_param_pattern %c.patt, runtime_param2
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param3
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %b.patt: %u32 = binding_pattern b
+// CHECK:STDOUT:     %b.param_patt: %u32 = value_param_pattern %b.patt, runtime_param1
+// CHECK:STDOUT:     %c.patt: %u32 = binding_pattern c
+// CHECK:STDOUT:     %c.param_patt: %u32 = value_param_pattern %c.patt, runtime_param2
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param3
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc57_50: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc57_50: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc57_50: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc57_26: type = splice_block %i32.loc57_26 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc57_50: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc57_26: type = splice_block %u32.loc57_26 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc57_26: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc57_26: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc57_26: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc57_26: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %b.param: %i32 = value_param runtime_param1
-// CHECK:STDOUT:     %.loc57_34: type = splice_block %i32.loc57_34 [template = constants.%i32] {
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %b.param: %u32 = value_param runtime_param1
+// CHECK:STDOUT:     %.loc57_34: type = splice_block %u32.loc57_34 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc57_34: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc57_34: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc57_34: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc57_34: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %b: %i32 = bind_name b, %b.param
-// CHECK:STDOUT:     %c.param: %i32 = value_param runtime_param2
-// CHECK:STDOUT:     %.loc57_42: type = splice_block %i32.loc57_42 [template = constants.%i32] {
+// CHECK:STDOUT:     %b: %u32 = bind_name b, %b.param
+// CHECK:STDOUT:     %c.param: %u32 = value_param runtime_param2
+// CHECK:STDOUT:     %.loc57_42: type = splice_block %u32.loc57_42 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc57_42: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc57_42: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc57_42: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc57_42: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %c: %i32 = bind_name c, %c.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param3
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %c: %u32 = bind_name c, %c.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param3
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: %RuntimeCallBadReturnType.type = fn_decl @RuntimeCallBadReturnType [template = constants.%RuntimeCallBadReturnType] {
 // CHECK:STDOUT:   %RuntimeCallBadReturnType.decl: %RuntimeCallBadReturnType.type = fn_decl @RuntimeCallBadReturnType [template = constants.%RuntimeCallBadReturnType] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %b.patt: %i32 = binding_pattern b
-// CHECK:STDOUT:     %b.param_patt: %i32 = value_param_pattern %b.patt, runtime_param1
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %b.patt: %u32 = binding_pattern b
+// CHECK:STDOUT:     %b.param_patt: %u32 = value_param_pattern %b.patt, runtime_param1
 // CHECK:STDOUT:     %return.patt: bool = return_slot_pattern
 // CHECK:STDOUT:     %return.patt: bool = return_slot_pattern
 // CHECK:STDOUT:     %return.param_patt: bool = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:     %return.param_patt: bool = out_param_pattern %return.patt, runtime_param2
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:     %bool.make_type: init type = call constants.%Bool() [template = bool]
 // CHECK:STDOUT:     %.loc68_48.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc68_48.1: type = value_of_initializer %bool.make_type [template = bool]
 // CHECK:STDOUT:     %.loc68_48.2: type = converted %bool.make_type, %.loc68_48.1 [template = bool]
 // CHECK:STDOUT:     %.loc68_48.2: type = converted %bool.make_type, %.loc68_48.1 [template = bool]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc68_32: type = splice_block %i32.loc68_32 [template = constants.%i32] {
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc68_32: type = splice_block %u32.loc68_32 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc68_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc68_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc68_32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc68_32: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %b.param: %i32 = value_param runtime_param1
-// CHECK:STDOUT:     %.loc68_40: type = splice_block %i32.loc68_40 [template = constants.%i32] {
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %b.param: %u32 = value_param runtime_param1
+// CHECK:STDOUT:     %.loc68_40: type = splice_block %u32.loc68_40 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc68_40: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc68_40: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc68_40: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc68_40: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %b: %i32 = bind_name b, %b.param
+// CHECK:STDOUT:     %b: %u32 = bind_name b, %b.param
 // CHECK:STDOUT:     %return.param: ref bool = out_param runtime_param2
 // CHECK:STDOUT:     %return.param: ref bool = out_param runtime_param2
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:     %return: ref bool = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @TooFew() -> %i32;
+// CHECK:STDOUT: fn @TooFew() -> %u32;
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @TooMany(%a.param_patt: %i32, %b.param_patt: %i32) -> %i32;
+// CHECK:STDOUT: fn @TooMany(%a.param_patt: %u32, %b.param_patt: %u32) -> %u32;
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @BadReturnType(%a.param_patt: %i32) -> bool;
+// CHECK:STDOUT: fn @BadReturnType(%a.param_patt: %u32) -> bool;
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @JustRight(%a.param_patt: %i32) -> %i32 = "int.unegate";
+// CHECK:STDOUT: fn @JustRight(%a.param_patt: %u32) -> %u32 = "int.unegate";
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @RuntimeCallTooFew(%a.param_patt: %i32) -> %i32 {
+// CHECK:STDOUT: fn @RuntimeCallTooFew(%a.param_patt: %u32) -> %u32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %TooFew.ref: %TooFew.type = name_ref TooFew, file.%TooFew.decl [template = constants.%TooFew]
 // CHECK:STDOUT:   %TooFew.ref: %TooFew.type = name_ref TooFew, file.%TooFew.decl [template = constants.%TooFew]
-// CHECK:STDOUT:   %a.ref: %i32 = name_ref a, %a
+// CHECK:STDOUT:   %a.ref: %u32 = name_ref a, %a
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @RuntimeCallTooMany(%a.param_patt: %i32, %b.param_patt: %i32, %c.param_patt: %i32) -> %i32 {
+// CHECK:STDOUT: fn @RuntimeCallTooMany(%a.param_patt: %u32, %b.param_patt: %u32, %c.param_patt: %u32) -> %u32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, file.%TooMany.decl [template = constants.%TooMany]
 // CHECK:STDOUT:   %TooMany.ref: %TooMany.type = name_ref TooMany, file.%TooMany.decl [template = constants.%TooMany]
-// 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
+// CHECK:STDOUT:   %a.ref: %u32 = name_ref a, %a
+// CHECK:STDOUT:   %b.ref: %u32 = name_ref b, %b
+// CHECK:STDOUT:   %c.ref: %u32 = name_ref c, %c
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a.param_patt: %i32, %b.param_patt: %i32) -> bool {
+// CHECK:STDOUT: fn @RuntimeCallBadReturnType(%a.param_patt: %u32, %b.param_patt: %u32) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%BadReturnType]
 // CHECK:STDOUT:   %BadReturnType.ref: %BadReturnType.type = name_ref BadReturnType, file.%BadReturnType.decl [template = constants.%BadReturnType]
-// CHECK:STDOUT:   %a.ref: %i32 = name_ref a, %a
-// CHECK:STDOUT:   %b.ref: %i32 = name_ref b, %b
+// CHECK:STDOUT:   %a.ref: %u32 = name_ref a, %a
+// CHECK:STDOUT:   %b.ref: %u32 = name_ref b, %b
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -472,31 +478,56 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
 // CHECK:STDOUT:   %int_32: Core.IntLiteral = int_value 32 [template]
-// CHECK:STDOUT:   %i32: type = class_type @Int, @Int(%int_32) [template]
+// CHECK:STDOUT:   %u32: type = class_type @UInt, @UInt(%int_32) [template]
 // CHECK:STDOUT:   %Negate.type.1: type = fn_type @Negate.1 [template]
 // CHECK:STDOUT:   %Negate.type.1: type = fn_type @Negate.1 [template]
 // CHECK:STDOUT:   %Negate: %Negate.type.1 = struct_value () [template]
 // CHECK:STDOUT:   %Negate: %Negate.type.1 = struct_value () [template]
-// CHECK:STDOUT:   %Sub.type.1: type = fn_type @Sub.1 [template]
-// CHECK:STDOUT:   %Sub: %Sub.type.1 = struct_value () [template]
+// CHECK:STDOUT:   %N.2: %u32 = bind_symbolic_name N, 0 [symbolic]
+// CHECK:STDOUT:   %N.patt.2: %u32 = symbolic_binding_pattern N, 0 [symbolic]
+// CHECK:STDOUT:   %Expect.type: type = generic_class_type @Expect [template]
+// CHECK:STDOUT:   %Expect.generic: %Expect.type = struct_value () [template]
+// CHECK:STDOUT:   %Expect.1: type = class_type @Expect, @Expect(%N.2) [symbolic]
+// CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [template]
+// CHECK:STDOUT:   %complete_type.3: <witness> = complete_type_witness %empty_struct_type [template]
+// CHECK:STDOUT:   %Test.type: type = fn_type @Test [template]
+// CHECK:STDOUT:   %Test: %Test.type = struct_value () [template]
+// CHECK:STDOUT:   %require_complete.2: <witness> = require_complete_type %Expect.1 [symbolic]
+// CHECK:STDOUT:   %Expect.val.1: %Expect.1 = struct_value () [symbolic]
+// CHECK:STDOUT:   %F.type: type = fn_type @F [template]
+// CHECK:STDOUT:   %F: %F.type = struct_value () [template]
 // CHECK:STDOUT:   %int_2147483647.1: Core.IntLiteral = int_value 2147483647 [template]
 // CHECK:STDOUT:   %int_2147483647.1: Core.IntLiteral = int_value 2147483647 [template]
-// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
+// CHECK:STDOUT:   %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%u32) [template]
 // CHECK:STDOUT:   %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
 // CHECK:STDOUT:   %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
 // CHECK:STDOUT:   %Convert.10: %Convert.type.10 = struct_value () [template]
 // CHECK:STDOUT:   %Convert.10: %Convert.type.10 = struct_value () [template]
 // CHECK:STDOUT:   %interface.19: <witness> = interface_witness (%Convert.10) [template]
 // CHECK:STDOUT:   %interface.19: <witness> = interface_witness (%Convert.10) [template]
 // CHECK:STDOUT:   %Convert.bound.1: <bound method> = bound_method %int_2147483647.1, %Convert.10 [template]
 // CHECK:STDOUT:   %Convert.bound.1: <bound method> = bound_method %int_2147483647.1, %Convert.10 [template]
 // CHECK:STDOUT:   %Convert.specific_fn.1: <specific function> = specific_function %Convert.bound.1, @Convert.2(%int_32) [template]
 // CHECK:STDOUT:   %Convert.specific_fn.1: <specific function> = specific_function %Convert.bound.1, @Convert.2(%int_32) [template]
-// CHECK:STDOUT:   %int_2147483647.2: %i32 = int_value 2147483647 [template]
-// CHECK:STDOUT:   %int_-2147483647: %i32 = int_value -2147483647 [template]
-// CHECK:STDOUT:   %int_1.1: Core.IntLiteral = int_value 1 [template]
-// CHECK:STDOUT:   %Convert.bound.2: <bound method> = bound_method %int_1.1, %Convert.10 [template]
+// CHECK:STDOUT:   %int_2147483647.2: %u32 = int_value 2147483647 [template]
+// CHECK:STDOUT:   %int_2147483649: %u32 = int_value 2147483649 [template]
+// CHECK:STDOUT:   %Expect.2: type = class_type @Expect, @Expect(%int_2147483647.2) [template]
+// CHECK:STDOUT:   %Test.specific_fn.1: <specific function> = specific_function %Test, @Test(%int_2147483647.2) [template]
+// CHECK:STDOUT:   %Op.type.13: type = fn_type @Op.13 [template]
+// CHECK:STDOUT:   %Op.type.14: type = fn_type @Op.5, @impl.11(%int_32) [template]
+// CHECK:STDOUT:   %Op.14: %Op.type.14 = struct_value () [template]
+// CHECK:STDOUT:   %interface.20: <witness> = interface_witness (%Op.14) [template]
+// CHECK:STDOUT:   %Op.bound.1: <bound method> = bound_method %int_2147483649, %Op.14 [template]
+// CHECK:STDOUT:   %Op.specific_fn.1: <specific function> = specific_function %Op.bound.1, @Op.5(%int_32) [template]
+// CHECK:STDOUT:   %int_2147483648.1: Core.IntLiteral = int_value 2147483648 [template]
+// CHECK:STDOUT:   %Convert.bound.2: <bound method> = bound_method %int_2147483648.1, %Convert.10 [template]
 // CHECK:STDOUT:   %Convert.specific_fn.2: <specific function> = specific_function %Convert.bound.2, @Convert.2(%int_32) [template]
 // CHECK:STDOUT:   %Convert.specific_fn.2: <specific function> = specific_function %Convert.bound.2, @Convert.2(%int_32) [template]
-// CHECK:STDOUT:   %int_1.2: %i32 = int_value 1 [template]
-// CHECK:STDOUT:   %int_-2147483648: %i32 = int_value -2147483648 [template]
+// CHECK:STDOUT:   %int_2147483648.2: %u32 = int_value 2147483648 [template]
+// CHECK:STDOUT:   %Expect.3: type = class_type @Expect, @Expect(%int_2147483648.2) [template]
+// CHECK:STDOUT:   %Test.specific_fn.2: <specific function> = specific_function %Test, @Test(%int_2147483648.2) [template]
+// CHECK:STDOUT:   %Op.bound.2: <bound method> = bound_method %int_2147483648.2, %Op.14 [template]
+// CHECK:STDOUT:   %Op.specific_fn.2: <specific function> = specific_function %Op.bound.2, @Op.5(%int_32) [template]
+// CHECK:STDOUT:   %Expect.val.2: %Expect.2 = struct_value () [template]
+// CHECK:STDOUT:   %Expect.val.3: %Expect.3 = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [template] {
-// CHECK:STDOUT:     .Int = %import_ref.1
+// CHECK:STDOUT:     .UInt = %import_ref.1
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.5
 // CHECK:STDOUT:     .ImplicitAs = %import_ref.5
+// CHECK:STDOUT:     .Negate = %import_ref.193
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
@@ -506,104 +537,266 @@ let b: i32 = Negate(Sub(Negate(0x7FFFFFFF), 1));
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .Negate = %Negate.decl
 // CHECK:STDOUT:     .Negate = %Negate.decl
-// CHECK:STDOUT:     .Sub = %Sub.decl
-// CHECK:STDOUT:     .a = @__global_init.%a
-// CHECK:STDOUT:     .b = @__global_init.%b
+// CHECK:STDOUT:     .Expect = %Expect.decl
+// CHECK:STDOUT:     .Test = %Test.decl
+// CHECK:STDOUT:     .F = %F.decl
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %Negate.decl: %Negate.type.1 = fn_decl @Negate.1 [template = constants.%Negate] {
 // CHECK:STDOUT:   %Negate.decl: %Negate.type.1 = fn_decl @Negate.1 [template = constants.%Negate] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
+// CHECK:STDOUT:     %a.patt: %u32 = binding_pattern a
+// CHECK:STDOUT:     %a.param_patt: %u32 = value_param_pattern %a.patt, runtime_param0
+// CHECK:STDOUT:     %return.patt: %u32 = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: %u32 = out_param_pattern %return.patt, runtime_param1
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %int_32.loc4_22: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:     %int_32.loc4_22: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc4_22: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc4: type = splice_block %i32.loc4_14 [template = constants.%i32] {
+// CHECK:STDOUT:     %u32.loc4_22: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
+// CHECK:STDOUT:     %a.param: %u32 = value_param runtime_param0
+// CHECK:STDOUT:     %.loc4: type = splice_block %u32.loc4_14 [template = constants.%u32] {
 // CHECK:STDOUT:       %int_32.loc4_14: Core.IntLiteral = int_value 32 [template = constants.%int_32]
 // CHECK:STDOUT:       %int_32.loc4_14: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc4_14: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:       %u32.loc4_14: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param1
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %a: %u32 = bind_name a, %a.param
+// CHECK:STDOUT:     %return.param: ref %u32 = out_param runtime_param1
+// CHECK:STDOUT:     %return: ref %u32 = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %Sub.decl: %Sub.type.1 = fn_decl @Sub.1 [template = constants.%Sub] {
-// CHECK:STDOUT:     %a.patt: %i32 = binding_pattern a
-// CHECK:STDOUT:     %a.param_patt: %i32 = value_param_pattern %a.patt, runtime_param0
-// CHECK:STDOUT:     %b.patt: %i32 = binding_pattern b
-// CHECK:STDOUT:     %b.param_patt: %i32 = value_param_pattern %b.patt, runtime_param1
-// CHECK:STDOUT:     %return.patt: %i32 = return_slot_pattern
-// CHECK:STDOUT:     %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param2
+// CHECK:STDOUT:   %Expect.decl: %Expect.type = class_decl @Expect [template = constants.%Expect.generic] {
+// CHECK:STDOUT:     %N.patt.loc6_14.1: %u32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_14.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %N.param_patt: %u32 = value_param_pattern %N.patt.loc6_14.1, runtime_param<invalid> [symbolic = %N.patt.loc6_14.2 (constants.%N.patt.2)]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %int_32.loc5_27: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:     %i32.loc5_27: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
-// CHECK:STDOUT:     %a.param: %i32 = value_param runtime_param0
-// CHECK:STDOUT:     %.loc5_11: type = splice_block %i32.loc5_11 [template = constants.%i32] {
-// CHECK:STDOUT:       %int_32.loc5_11: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc5_11: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %N.param: %u32 = value_param runtime_param<invalid>
+// CHECK:STDOUT:     %.loc6: type = splice_block %u32 [template = constants.%u32] {
+// CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:       %u32: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %a: %i32 = bind_name a, %a.param
-// CHECK:STDOUT:     %b.param: %i32 = value_param runtime_param1
-// CHECK:STDOUT:     %.loc5_19: type = splice_block %i32.loc5_19 [template = constants.%i32] {
-// CHECK:STDOUT:       %int_32.loc5_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
-// CHECK:STDOUT:       %i32.loc5_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
+// CHECK:STDOUT:     %N.loc6_14.1: %u32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc6_14.2 (constants.%N.2)]
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Test.decl: %Test.type = fn_decl @Test [template = constants.%Test] {
+// CHECK:STDOUT:     %N.patt.loc7_9.1: %u32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc7_9.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %N.param_patt: %u32 = value_param_pattern %N.patt.loc7_9.1, runtime_param<invalid> [symbolic = %N.patt.loc7_9.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:     %return.patt: @Test.%Expect.loc7_29.2 (%Expect.1) = return_slot_pattern
+// CHECK:STDOUT:     %return.param_patt: @Test.%Expect.loc7_29.2 (%Expect.1) = out_param_pattern %return.patt, runtime_param0
+// CHECK:STDOUT:   } {
+// CHECK:STDOUT:     %Expect.ref: %Expect.type = name_ref Expect, file.%Expect.decl [template = constants.%Expect.generic]
+// CHECK:STDOUT:     %N.ref: %u32 = name_ref N, %N.loc7_9.1 [symbolic = %N.loc7_9.2 (constants.%N.2)]
+// CHECK:STDOUT:     %Expect.loc7_29.1: type = class_type @Expect, @Expect(constants.%N.2) [symbolic = %Expect.loc7_29.2 (constants.%Expect.1)]
+// CHECK:STDOUT:     %N.param: %u32 = value_param runtime_param<invalid>
+// CHECK:STDOUT:     %.loc7_13: type = splice_block %u32 [template = constants.%u32] {
+// CHECK:STDOUT:       %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
+// CHECK:STDOUT:       %u32: type = class_type @UInt, @UInt(constants.%int_32) [template = constants.%u32]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %b: %i32 = bind_name b, %b.param
-// CHECK:STDOUT:     %return.param: ref %i32 = out_param runtime_param2
-// CHECK:STDOUT:     %return: ref %i32 = return_slot %return.param
+// CHECK:STDOUT:     %N.loc7_9.1: %u32 = bind_symbolic_name N, 0, %N.param [symbolic = %N.loc7_9.2 (constants.%N.2)]
+// CHECK:STDOUT:     %return.param: ref @Test.%Expect.loc7_29.2 (%Expect.1) = out_param runtime_param0
+// CHECK:STDOUT:     %return: ref @Test.%Expect.loc7_29.2 (%Expect.1) = return_slot %return.param
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Negate.1(%a.param_patt: %i32) -> %i32 = "int.unegate";
+// CHECK:STDOUT: generic class @Expect(%N.loc6_14.1: %u32) {
+// CHECK:STDOUT:   %N.loc6_14.2: %u32 = bind_symbolic_name N, 0 [symbolic = %N.loc6_14.2 (constants.%N.2)]
+// CHECK:STDOUT:   %N.patt.loc6_14.2: %u32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc6_14.2 (constants.%N.patt.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @Sub.1(%a.param_patt: %i32, %b.param_patt: %i32) -> %i32 = "int.usub";
+// CHECK:STDOUT: !definition:
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @__global_init() {
+// CHECK:STDOUT:   class {
+// CHECK:STDOUT:     %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type.3]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   !members:
+// CHECK:STDOUT:     .Self = constants.%Expect.1
+// CHECK:STDOUT:     complete_type_witness = %complete_type
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @Negate.1(%a.param_patt: %u32) -> %u32 = "int.unegate";
+// CHECK:STDOUT:
+// CHECK:STDOUT: generic fn @Test(%N.loc7_9.1: %u32) {
+// CHECK:STDOUT:   %N.loc7_9.2: %u32 = bind_symbolic_name N, 0 [symbolic = %N.loc7_9.2 (constants.%N.2)]
+// CHECK:STDOUT:   %N.patt.loc7_9.2: %u32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc7_9.2 (constants.%N.patt.2)]
+// CHECK:STDOUT:   %Expect.loc7_29.2: type = class_type @Expect, @Expect(%N.loc7_9.2) [symbolic = %Expect.loc7_29.2 (constants.%Expect.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type @Test.%Expect.loc7_29.2 (%Expect.1) [symbolic = %require_complete (constants.%require_complete.2)]
+// CHECK:STDOUT:   %Expect.val: @Test.%Expect.loc7_29.2 (%Expect.1) = struct_value () [symbolic = %Expect.val (constants.%Expect.val.1)]
+// CHECK:STDOUT:
+// CHECK:STDOUT:   fn(%N.param_patt: %u32) -> %return.param_patt: @Test.%Expect.loc7_29.2 (%Expect.1) {
+// CHECK:STDOUT:   !entry:
+// CHECK:STDOUT:     %.loc7_41.1: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %.loc7_41.2: init @Test.%Expect.loc7_29.2 (%Expect.1) = class_init (), %return [symbolic = %Expect.val (constants.%Expect.val.1)]
+// CHECK:STDOUT:     %.loc7_42: init @Test.%Expect.loc7_29.2 (%Expect.1) = converted %.loc7_41.1, %.loc7_41.2 [symbolic = %Expect.val (constants.%Expect.val.1)]
+// CHECK:STDOUT:     return %.loc7_42 to %return
+// CHECK:STDOUT:   }
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Negate.ref.loc8_14: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %Negate.ref.loc8_21: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %int_2147483647.loc8: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
-// CHECK:STDOUT:   %impl.elem0.loc8: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
-// CHECK:STDOUT:   %Convert.bound.loc8: <bound method> = bound_method %int_2147483647.loc8, %impl.elem0.loc8 [template = constants.%Convert.bound.1]
-// CHECK:STDOUT:   %Convert.specific_fn.loc8: <specific function> = specific_function %Convert.bound.loc8, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
-// CHECK:STDOUT:   %int.convert_checked.loc8: init %i32 = call %Convert.specific_fn.loc8(%int_2147483647.loc8) [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc8_28.1: %i32 = value_of_initializer %int.convert_checked.loc8 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc8_28.2: %i32 = converted %int_2147483647.loc8, %.loc8_28.1 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %int.unegate.loc8_38: init %i32 = call %Negate.ref.loc8_21(%.loc8_28.2) [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %.loc8_38.1: %i32 = value_of_initializer %int.unegate.loc8_38 [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %.loc8_38.2: %i32 = converted %int.unegate.loc8_38, %.loc8_38.1 [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %int.unegate.loc8_39: init %i32 = call %Negate.ref.loc8_14(%.loc8_38.2) [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc8_40.1: %i32 = value_of_initializer %int.unegate.loc8_39 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc8_40.2: %i32 = converted %int.unegate.loc8_39, %.loc8_40.1 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %a: %i32 = bind_name a, %.loc8_40.2
-// CHECK:STDOUT:   %Negate.ref.loc11_14: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %Sub.ref: %Sub.type.1 = name_ref Sub, file.%Sub.decl [template = constants.%Sub]
-// CHECK:STDOUT:   %Negate.ref.loc11_25: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
-// CHECK:STDOUT:   %int_2147483647.loc11: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
-// CHECK:STDOUT:   %impl.elem0.loc11_32: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
-// CHECK:STDOUT:   %Convert.bound.loc11_32: <bound method> = bound_method %int_2147483647.loc11, %impl.elem0.loc11_32 [template = constants.%Convert.bound.1]
-// CHECK:STDOUT:   %Convert.specific_fn.loc11_32: <specific function> = specific_function %Convert.bound.loc11_32, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
-// CHECK:STDOUT:   %int.convert_checked.loc11_32: init %i32 = call %Convert.specific_fn.loc11_32(%int_2147483647.loc11) [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc11_32.1: %i32 = value_of_initializer %int.convert_checked.loc11_32 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %.loc11_32.2: %i32 = converted %int_2147483647.loc11, %.loc11_32.1 [template = constants.%int_2147483647.2]
-// CHECK:STDOUT:   %int.unegate.loc11_42: init %i32 = call %Negate.ref.loc11_25(%.loc11_32.2) [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [template = constants.%int_1.1]
-// CHECK:STDOUT:   %.loc11_42.1: %i32 = value_of_initializer %int.unegate.loc11_42 [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %.loc11_42.2: %i32 = converted %int.unegate.loc11_42, %.loc11_42.1 [template = constants.%int_-2147483647]
-// CHECK:STDOUT:   %impl.elem0.loc11_45: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
-// CHECK:STDOUT:   %Convert.bound.loc11_45: <bound method> = bound_method %int_1, %impl.elem0.loc11_45 [template = constants.%Convert.bound.2]
-// CHECK:STDOUT:   %Convert.specific_fn.loc11_45: <specific function> = specific_function %Convert.bound.loc11_45, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
-// CHECK:STDOUT:   %int.convert_checked.loc11_45: init %i32 = call %Convert.specific_fn.loc11_45(%int_1) [template = constants.%int_1.2]
-// CHECK:STDOUT:   %.loc11_45.1: %i32 = value_of_initializer %int.convert_checked.loc11_45 [template = constants.%int_1.2]
-// CHECK:STDOUT:   %.loc11_45.2: %i32 = converted %int_1, %.loc11_45.1 [template = constants.%int_1.2]
-// CHECK:STDOUT:   %int.usub: init %i32 = call %Sub.ref(%.loc11_42.2, %.loc11_45.2) [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %.loc11_46.1: %i32 = value_of_initializer %int.usub [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %.loc11_46.2: %i32 = converted %int.usub, %.loc11_46.1 [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %int.unegate.loc11_47: init %i32 = call %Negate.ref.loc11_14(%.loc11_46.2) [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %.loc11_48.1: %i32 = value_of_initializer %int.unegate.loc11_47 [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %.loc11_48.2: %i32 = converted %int.unegate.loc11_47, %.loc11_48.1 [template = constants.%int_-2147483648]
-// CHECK:STDOUT:   %b: %i32 = bind_name b, %.loc11_48.2
+// CHECK:STDOUT:   %Test.ref.loc11: %Test.type = name_ref Test, file.%Test.decl [template = constants.%Test]
+// CHECK:STDOUT:   %Negate.ref.loc11_8: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc11_15: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %int_2147483647.loc11_22: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
+// CHECK:STDOUT:   %impl.elem0.loc11_22: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc11_22: <bound method> = bound_method %int_2147483647.loc11_22, %impl.elem0.loc11_22 [template = constants.%Convert.bound.1]
+// CHECK:STDOUT:   %Convert.specific_fn.loc11_22: <specific function> = specific_function %Convert.bound.loc11_22, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
+// CHECK:STDOUT:   %int.convert_checked.loc11_22: init %u32 = call %Convert.specific_fn.loc11_22(%int_2147483647.loc11_22) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_22.1: %u32 = value_of_initializer %int.convert_checked.loc11_22 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_22.2: %u32 = converted %int_2147483647.loc11_22, %.loc11_22.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %int.unegate.loc11_33: init %u32 = call %Negate.ref.loc11_15(%.loc11_22.2) [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %.loc11_33.1: %u32 = value_of_initializer %int.unegate.loc11_33 [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %.loc11_33.2: %u32 = converted %int.unegate.loc11_33, %.loc11_33.1 [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %int.unegate.loc11_34: init %u32 = call %Negate.ref.loc11_8(%.loc11_33.2) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_35.1: %u32 = value_of_initializer %int.unegate.loc11_34 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_35.2: %u32 = converted %int.unegate.loc11_34, %.loc11_35.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %Test.specific_fn.loc11: <specific function> = specific_function %Test.ref.loc11, @Test(constants.%int_2147483647.2) [template = constants.%Test.specific_fn.1]
+// CHECK:STDOUT:   %.loc11_35.3: ref %Expect.2 = temporary_storage
+// CHECK:STDOUT:   %Test.call.loc11: init %Expect.2 = call %Test.specific_fn.loc11() to %.loc11_35.3
+// CHECK:STDOUT:   %Expect.ref.loc11: %Expect.type = name_ref Expect, file.%Expect.decl [template = constants.%Expect.generic]
+// CHECK:STDOUT:   %int_2147483647.loc11_47: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
+// CHECK:STDOUT:   %impl.elem0.loc11_58: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc11_58: <bound method> = bound_method %int_2147483647.loc11_47, %impl.elem0.loc11_58 [template = constants.%Convert.bound.1]
+// CHECK:STDOUT:   %Convert.specific_fn.loc11_58: <specific function> = specific_function %Convert.bound.loc11_58, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
+// CHECK:STDOUT:   %int.convert_checked.loc11_58: init %u32 = call %Convert.specific_fn.loc11_58(%int_2147483647.loc11_47) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_58.1: %u32 = value_of_initializer %int.convert_checked.loc11_58 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc11_58.2: %u32 = converted %int_2147483647.loc11_47, %.loc11_58.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %Expect.loc11: type = class_type @Expect, @Expect(constants.%int_2147483647.2) [template = constants.%Expect.2]
+// CHECK:STDOUT:   %.loc11_35.4: ref %Expect.2 = temporary %.loc11_35.3, %Test.call.loc11
+// CHECK:STDOUT:   %Test.ref.loc12: %Test.type = name_ref Test, file.%Test.decl [template = constants.%Test]
+// CHECK:STDOUT:   %Negate.ref.loc12: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %int_2147483647.loc12_17: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
+// CHECK:STDOUT:   %impl.elem0.loc12_17: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc12_17: <bound method> = bound_method %int_2147483647.loc12_17, %impl.elem0.loc12_17 [template = constants.%Convert.bound.1]
+// CHECK:STDOUT:   %Convert.specific_fn.loc12_17: <specific function> = specific_function %Convert.bound.loc12_17, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
+// CHECK:STDOUT:   %int.convert_checked.loc12_17: init %u32 = call %Convert.specific_fn.loc12_17(%int_2147483647.loc12_17) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_17.1: %u32 = value_of_initializer %int.convert_checked.loc12_17 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_17.2: %u32 = converted %int_2147483647.loc12_17, %.loc12_17.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %int.unegate.loc12_28: init %u32 = call %Negate.ref.loc12(%.loc12_17.2) [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %impl.elem0.loc12_8: %Op.type.13 = interface_witness_access constants.%interface.20, element0 [template = constants.%Op.14]
+// CHECK:STDOUT:   %Op.bound.loc12: <bound method> = bound_method %int.unegate.loc12_28, %impl.elem0.loc12_8 [template = constants.%Op.bound.1]
+// CHECK:STDOUT:   %Op.specific_fn.loc12: <specific function> = specific_function %Op.bound.loc12, @Op.5(constants.%int_32) [template = constants.%Op.specific_fn.1]
+// CHECK:STDOUT:   %.loc12_28.1: %u32 = value_of_initializer %int.unegate.loc12_28 [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %.loc12_28.2: %u32 = converted %int.unegate.loc12_28, %.loc12_28.1 [template = constants.%int_2147483649]
+// CHECK:STDOUT:   %int.unegate.loc12_8: init %u32 = call %Op.specific_fn.loc12(%.loc12_28.2) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_30.1: %u32 = value_of_initializer %int.unegate.loc12_8 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_30.2: %u32 = converted %int.unegate.loc12_8, %.loc12_30.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %Test.specific_fn.loc12: <specific function> = specific_function %Test.ref.loc12, @Test(constants.%int_2147483647.2) [template = constants.%Test.specific_fn.1]
+// CHECK:STDOUT:   %.loc12_30.3: ref %Expect.2 = temporary_storage
+// CHECK:STDOUT:   %Test.call.loc12: init %Expect.2 = call %Test.specific_fn.loc12() to %.loc12_30.3
+// CHECK:STDOUT:   %Expect.ref.loc12: %Expect.type = name_ref Expect, file.%Expect.decl [template = constants.%Expect.generic]
+// CHECK:STDOUT:   %int_2147483647.loc12_42: Core.IntLiteral = int_value 2147483647 [template = constants.%int_2147483647.1]
+// CHECK:STDOUT:   %impl.elem0.loc12_53: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc12_53: <bound method> = bound_method %int_2147483647.loc12_42, %impl.elem0.loc12_53 [template = constants.%Convert.bound.1]
+// CHECK:STDOUT:   %Convert.specific_fn.loc12_53: <specific function> = specific_function %Convert.bound.loc12_53, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
+// CHECK:STDOUT:   %int.convert_checked.loc12_53: init %u32 = call %Convert.specific_fn.loc12_53(%int_2147483647.loc12_42) [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_53.1: %u32 = value_of_initializer %int.convert_checked.loc12_53 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %.loc12_53.2: %u32 = converted %int_2147483647.loc12_42, %.loc12_53.1 [template = constants.%int_2147483647.2]
+// CHECK:STDOUT:   %Expect.loc12: type = class_type @Expect, @Expect(constants.%int_2147483647.2) [template = constants.%Expect.2]
+// CHECK:STDOUT:   %.loc12_30.4: ref %Expect.2 = temporary %.loc12_30.3, %Test.call.loc12
+// CHECK:STDOUT:   %Test.ref.loc14: %Test.type = name_ref Test, file.%Test.decl [template = constants.%Test]
+// CHECK:STDOUT:   %Negate.ref.loc14_8: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %Negate.ref.loc14_15: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %int_2147483648.loc14_22: Core.IntLiteral = int_value 2147483648 [template = constants.%int_2147483648.1]
+// CHECK:STDOUT:   %impl.elem0.loc14_22: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc14_22: <bound method> = bound_method %int_2147483648.loc14_22, %impl.elem0.loc14_22 [template = constants.%Convert.bound.2]
+// CHECK:STDOUT:   %Convert.specific_fn.loc14_22: <specific function> = specific_function %Convert.bound.loc14_22, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
+// CHECK:STDOUT:   %int.convert_checked.loc14_22: init %u32 = call %Convert.specific_fn.loc14_22(%int_2147483648.loc14_22) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_22.1: %u32 = value_of_initializer %int.convert_checked.loc14_22 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_22.2: %u32 = converted %int_2147483648.loc14_22, %.loc14_22.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %int.unegate.loc14_33: init %u32 = call %Negate.ref.loc14_15(%.loc14_22.2) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_33.1: %u32 = value_of_initializer %int.unegate.loc14_33 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_33.2: %u32 = converted %int.unegate.loc14_33, %.loc14_33.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %int.unegate.loc14_34: init %u32 = call %Negate.ref.loc14_8(%.loc14_33.2) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_35.1: %u32 = value_of_initializer %int.unegate.loc14_34 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_35.2: %u32 = converted %int.unegate.loc14_34, %.loc14_35.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %Test.specific_fn.loc14: <specific function> = specific_function %Test.ref.loc14, @Test(constants.%int_2147483648.2) [template = constants.%Test.specific_fn.2]
+// CHECK:STDOUT:   %.loc14_35.3: ref %Expect.3 = temporary_storage
+// CHECK:STDOUT:   %Test.call.loc14: init %Expect.3 = call %Test.specific_fn.loc14() to %.loc14_35.3
+// CHECK:STDOUT:   %Expect.ref.loc14: %Expect.type = name_ref Expect, file.%Expect.decl [template = constants.%Expect.generic]
+// CHECK:STDOUT:   %int_2147483648.loc14_47: Core.IntLiteral = int_value 2147483648 [template = constants.%int_2147483648.1]
+// CHECK:STDOUT:   %impl.elem0.loc14_58: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc14_58: <bound method> = bound_method %int_2147483648.loc14_47, %impl.elem0.loc14_58 [template = constants.%Convert.bound.2]
+// CHECK:STDOUT:   %Convert.specific_fn.loc14_58: <specific function> = specific_function %Convert.bound.loc14_58, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
+// CHECK:STDOUT:   %int.convert_checked.loc14_58: init %u32 = call %Convert.specific_fn.loc14_58(%int_2147483648.loc14_47) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_58.1: %u32 = value_of_initializer %int.convert_checked.loc14_58 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc14_58.2: %u32 = converted %int_2147483648.loc14_47, %.loc14_58.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %Expect.loc14: type = class_type @Expect, @Expect(constants.%int_2147483648.2) [template = constants.%Expect.3]
+// CHECK:STDOUT:   %.loc14_35.4: ref %Expect.3 = temporary %.loc14_35.3, %Test.call.loc14
+// CHECK:STDOUT:   %Test.ref.loc15: %Test.type = name_ref Test, file.%Test.decl [template = constants.%Test]
+// CHECK:STDOUT:   %Negate.ref.loc15: %Negate.type.1 = name_ref Negate, file.%Negate.decl [template = constants.%Negate]
+// CHECK:STDOUT:   %int_2147483648.loc15_17: Core.IntLiteral = int_value 2147483648 [template = constants.%int_2147483648.1]
+// CHECK:STDOUT:   %impl.elem0.loc15_17: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc15_17: <bound method> = bound_method %int_2147483648.loc15_17, %impl.elem0.loc15_17 [template = constants.%Convert.bound.2]
+// CHECK:STDOUT:   %Convert.specific_fn.loc15_17: <specific function> = specific_function %Convert.bound.loc15_17, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
+// CHECK:STDOUT:   %int.convert_checked.loc15_17: init %u32 = call %Convert.specific_fn.loc15_17(%int_2147483648.loc15_17) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_17.1: %u32 = value_of_initializer %int.convert_checked.loc15_17 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_17.2: %u32 = converted %int_2147483648.loc15_17, %.loc15_17.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %int.unegate.loc15_28: init %u32 = call %Negate.ref.loc15(%.loc15_17.2) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %impl.elem0.loc15_8: %Op.type.13 = interface_witness_access constants.%interface.20, element0 [template = constants.%Op.14]
+// CHECK:STDOUT:   %Op.bound.loc15: <bound method> = bound_method %int.unegate.loc15_28, %impl.elem0.loc15_8 [template = constants.%Op.bound.2]
+// CHECK:STDOUT:   %Op.specific_fn.loc15: <specific function> = specific_function %Op.bound.loc15, @Op.5(constants.%int_32) [template = constants.%Op.specific_fn.2]
+// CHECK:STDOUT:   %.loc15_28.1: %u32 = value_of_initializer %int.unegate.loc15_28 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_28.2: %u32 = converted %int.unegate.loc15_28, %.loc15_28.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %int.unegate.loc15_8: init %u32 = call %Op.specific_fn.loc15(%.loc15_28.2) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_30.1: %u32 = value_of_initializer %int.unegate.loc15_8 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_30.2: %u32 = converted %int.unegate.loc15_8, %.loc15_30.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %Test.specific_fn.loc15: <specific function> = specific_function %Test.ref.loc15, @Test(constants.%int_2147483648.2) [template = constants.%Test.specific_fn.2]
+// CHECK:STDOUT:   %.loc15_30.3: ref %Expect.3 = temporary_storage
+// CHECK:STDOUT:   %Test.call.loc15: init %Expect.3 = call %Test.specific_fn.loc15() to %.loc15_30.3
+// CHECK:STDOUT:   %Expect.ref.loc15: %Expect.type = name_ref Expect, file.%Expect.decl [template = constants.%Expect.generic]
+// CHECK:STDOUT:   %int_2147483648.loc15_42: Core.IntLiteral = int_value 2147483648 [template = constants.%int_2147483648.1]
+// CHECK:STDOUT:   %impl.elem0.loc15_53: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
+// CHECK:STDOUT:   %Convert.bound.loc15_53: <bound method> = bound_method %int_2147483648.loc15_42, %impl.elem0.loc15_53 [template = constants.%Convert.bound.2]
+// CHECK:STDOUT:   %Convert.specific_fn.loc15_53: <specific function> = specific_function %Convert.bound.loc15_53, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
+// CHECK:STDOUT:   %int.convert_checked.loc15_53: init %u32 = call %Convert.specific_fn.loc15_53(%int_2147483648.loc15_42) [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_53.1: %u32 = value_of_initializer %int.convert_checked.loc15_53 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %.loc15_53.2: %u32 = converted %int_2147483648.loc15_42, %.loc15_53.1 [template = constants.%int_2147483648.2]
+// CHECK:STDOUT:   %Expect.loc15: type = class_type @Expect, @Expect(constants.%int_2147483648.2) [template = constants.%Expect.3]
+// CHECK:STDOUT:   %.loc15_30.4: ref %Expect.3 = temporary %.loc15_30.3, %Test.call.loc15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
+// CHECK:STDOUT: specific @Expect(constants.%N.2) {
+// CHECK:STDOUT:   %N.loc6_14.2 => constants.%N.2
+// CHECK:STDOUT:   %N.patt.loc6_14.2 => constants.%N.2
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Expect(@Test.%N.loc7_9.2) {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Test(constants.%N.2) {
+// CHECK:STDOUT:   %N.loc7_9.2 => constants.%N.2
+// CHECK:STDOUT:   %N.patt.loc7_9.2 => constants.%N.2
+// CHECK:STDOUT:   %Expect.loc7_29.2 => constants.%Expect.1
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Test(constants.%int_2147483647.2) {
+// CHECK:STDOUT:   %N.loc7_9.2 => constants.%int_2147483647.2
+// CHECK:STDOUT:   %N.patt.loc7_9.2 => constants.%int_2147483647.2
+// CHECK:STDOUT:   %Expect.loc7_29.2 => constants.%Expect.2
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.3
+// CHECK:STDOUT:   %Expect.val => constants.%Expect.val.2
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Expect(constants.%int_2147483647.2) {
+// CHECK:STDOUT:   %N.loc6_14.2 => constants.%int_2147483647.2
+// CHECK:STDOUT:   %N.patt.loc6_14.2 => constants.%int_2147483647.2
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Test(constants.%int_2147483648.2) {
+// CHECK:STDOUT:   %N.loc7_9.2 => constants.%int_2147483648.2
+// CHECK:STDOUT:   %N.patt.loc7_9.2 => constants.%int_2147483648.2
+// CHECK:STDOUT:   %Expect.loc7_29.2 => constants.%Expect.3
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.3
+// CHECK:STDOUT:   %Expect.val => constants.%Expect.val.3
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: specific @Expect(constants.%int_2147483648.2) {
+// CHECK:STDOUT:   %N.loc6_14.2 => constants.%int_2147483648.2
+// CHECK:STDOUT:   %N.patt.loc6_14.2 => constants.%int_2147483648.2
+// CHECK:STDOUT:
+// CHECK:STDOUT: !definition:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 2 - 2
toolchain/lower/testdata/operators/arithmetic.carbon

@@ -93,8 +93,8 @@ fn div_u16(a: u16, b: u16) -> u16 { return a / b; }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: define i32 @_Cneg_u32.Main(i32 %a) !dbg !33 {
 // CHECK:STDOUT: define i32 @_Cneg_u32.Main(i32 %a) !dbg !33 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %int.snegate = sub i32 0, %a, !dbg !34
-// CHECK:STDOUT:   ret i32 %int.snegate, !dbg !35
+// CHECK:STDOUT:   %int.unegate = sub i32 0, %a, !dbg !34
+// CHECK:STDOUT:   ret i32 %int.unegate, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: define i32 @_Csub_i32.Main(i32 %a, i32 %b) !dbg !36 {
 // CHECK:STDOUT: define i32 @_Csub_i32.Main(i32 %a, i32 %b) !dbg !36 {