diff --git a/core/prelude/types/int.carbon b/core/prelude/types/int.carbon index 937160113500..e3ab2f43f158 100644 --- a/core/prelude/types/int.carbon +++ b/core/prelude/types/int.carbon @@ -106,77 +106,44 @@ impl forall [N:! IntLiteral()] Int(N) as RightShift { // Compound assignments. -// TODO: Once we can lower specific functions, make these generic. -// Each function has a commented out generic signature. - -// impl forall [N:! IntLiteral()] Int(N) as AddAssign { -impl i32 as AddAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self + other; - } +impl forall [N:! IntLiteral()] Int(N) as AddAssign { + fn Op[addr self: Self*](other: Self) = "int.sadd_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as BitAndAssign { -impl i32 as BitAndAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self & other; - } +impl forall [N:! IntLiteral()] Int(N) as BitAndAssign { + fn Op[addr self: Self*](other: Self) = "int.and_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as BitOrAssign { -impl i32 as BitOrAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self | other; - } +impl forall [N:! IntLiteral()] Int(N) as BitOrAssign { + fn Op[addr self: Self*](other: Self) = "int.or_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as BitXorAssign { -impl i32 as BitXorAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self ^ other; - } +impl forall [N:! IntLiteral()] Int(N) as BitXorAssign { + fn Op[addr self: Self*](other: Self) = "int.xor_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as DivAssign { -impl i32 as DivAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self / other; - } +impl forall [N:! IntLiteral()] Int(N) as DivAssign { + fn Op[addr self: Self*](other: Self) = "int.sdiv_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as LeftShiftAssign { -impl i32 as LeftShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self << other; - } +impl forall [N:! IntLiteral()] Int(N) as LeftShiftAssign { + fn Op[addr self: Self*](other: Self) = "int.left_shift_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as ModAssign { -impl i32 as ModAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self % other; - } +impl forall [N:! IntLiteral()] Int(N) as ModAssign { + fn Op[addr self: Self*](other: Self) = "int.smod_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as MulAssign { -impl i32 as MulAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self * other; - } +impl forall [N:! IntLiteral()] Int(N) as MulAssign { + fn Op[addr self: Self*](other: Self) = "int.smul_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as RightShiftAssign { -impl i32 as RightShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self >> other; - } +impl forall [N:! IntLiteral()] Int(N) as RightShiftAssign { + fn Op[addr self: Self*](other: Self) = "int.right_shift_assign"; } -// impl forall [N:! IntLiteral()] Int(N) as SubAssign { -impl i32 as SubAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self - other; - } +impl forall [N:! IntLiteral()] Int(N) as SubAssign { + fn Op[addr self: Self*](other: Self) = "int.ssub_assign"; } // Increment and decrement. diff --git a/core/prelude/types/uint.carbon b/core/prelude/types/uint.carbon index 2478a35ad796..fca3bfbb497b 100644 --- a/core/prelude/types/uint.carbon +++ b/core/prelude/types/uint.carbon @@ -117,77 +117,44 @@ impl forall [N:! IntLiteral()] UInt(N) as RightShift { // Compound assignments. -// TODO: Once we can lower specific functions, make these generic. -// Each function has a commented out generic signature. - -// impl forall [N:! IntLiteral()] UInt(N) as AddAssign { -impl u32 as AddAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self + other; - } +impl forall [N:! IntLiteral()] UInt(N) as AddAssign { + fn Op[addr self: Self*](other: Self) = "int.uadd_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as BitAndAssign { -impl u32 as BitAndAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self & other; - } +impl forall [N:! IntLiteral()] UInt(N) as BitAndAssign { + fn Op[addr self: Self*](other: Self) = "int.and_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as BitOrAssign { -impl u32 as BitOrAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self | other; - } +impl forall [N:! IntLiteral()] UInt(N) as BitOrAssign { + fn Op[addr self: Self*](other: Self) = "int.or_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as BitXorAssign { -impl u32 as BitXorAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self ^ other; - } +impl forall [N:! IntLiteral()] UInt(N) as BitXorAssign { + fn Op[addr self: Self*](other: Self) = "int.xor_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as DivAssign { -impl u32 as DivAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self / other; - } +impl forall [N:! IntLiteral()] UInt(N) as DivAssign { + fn Op[addr self: Self*](other: Self) = "int.udiv_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as LeftShiftAssign { -impl u32 as LeftShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self << other; - } +impl forall [N:! IntLiteral()] UInt(N) as LeftShiftAssign { + fn Op[addr self: Self*](other: Self) = "int.left_shift_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as ModAssign { -impl u32 as ModAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self % other; - } +impl forall [N:! IntLiteral()] UInt(N) as ModAssign { + fn Op[addr self: Self*](other: Self) = "int.umod_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as MulAssign { -impl u32 as MulAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self * other; - } +impl forall [N:! IntLiteral()] UInt(N) as MulAssign { + fn Op[addr self: Self*](other: Self) = "int.umul_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as RightShiftAssign { -impl u32 as RightShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self >> other; - } +impl forall [N:! IntLiteral()] UInt(N) as RightShiftAssign { + fn Op[addr self: Self*](other: Self) = "int.right_shift_assign"; } -// impl forall [N:! IntLiteral()] UInt(N) as SubAssign { -impl u32 as SubAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self - other; - } +impl forall [N:! IntLiteral()] UInt(N) as SubAssign { + fn Op[addr self: Self*](other: Self) = "int.usub_assign"; } // Increment and decrement. diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index e04d07d363ce..c7b87d862cf1 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -1394,7 +1394,22 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, case SemIR::BuiltinFunctionKind::PrintChar: case SemIR::BuiltinFunctionKind::PrintInt: - case SemIR::BuiltinFunctionKind::ReadChar: { + case SemIR::BuiltinFunctionKind::ReadChar: + case SemIR::BuiltinFunctionKind::IntSAddAssign: + case SemIR::BuiltinFunctionKind::IntSSubAssign: + case SemIR::BuiltinFunctionKind::IntSMulAssign: + case SemIR::BuiltinFunctionKind::IntSDivAssign: + case SemIR::BuiltinFunctionKind::IntSModAssign: + case SemIR::BuiltinFunctionKind::IntUAddAssign: + case SemIR::BuiltinFunctionKind::IntUSubAssign: + case SemIR::BuiltinFunctionKind::IntUMulAssign: + case SemIR::BuiltinFunctionKind::IntUDivAssign: + case SemIR::BuiltinFunctionKind::IntUModAssign: + case SemIR::BuiltinFunctionKind::IntAndAssign: + case SemIR::BuiltinFunctionKind::IntOrAssign: + case SemIR::BuiltinFunctionKind::IntXorAssign: + case SemIR::BuiltinFunctionKind::IntLeftShiftAssign: + case SemIR::BuiltinFunctionKind::IntRightShiftAssign: { // These are runtime-only builtins. // TODO: Consider tracking this on the `BuiltinFunctionKind`. return SemIR::ConstantId::NotConstant; diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 31285bb11b0d..47375d54334f 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -696,16 +696,16 @@ static auto IsValidBuiltinDeclaration(Context& context, const SemIR::Function& function, SemIR::BuiltinFunctionKind builtin_kind) -> bool { + // Find the list of call parameters other than the implicit return slot. + auto call_params = context.inst_blocks().Get(function.call_params_id); + if (function.return_slot_pattern_id.has_value()) { + call_params = call_params.drop_back(); + } + // Form the list of parameter types for the declaration. llvm::SmallVector param_type_ids; - auto implicit_param_patterns = - context.inst_blocks().GetOrEmpty(function.implicit_param_patterns_id); - auto param_patterns = - context.inst_blocks().GetOrEmpty(function.param_patterns_id); - param_type_ids.reserve(implicit_param_patterns.size() + - param_patterns.size()); - for (auto param_id : llvm::concat( - implicit_param_patterns, param_patterns)) { + param_type_ids.reserve(call_params.size()); + for (auto param_id : call_params) { // TODO: We also need to track whether the parameter is declared with // `var`. param_type_ids.push_back(context.insts().Get(param_id).type_id()); diff --git a/toolchain/check/testdata/array/canonicalize_index.carbon b/toolchain/check/testdata/array/canonicalize_index.carbon index 482952f3d5a2..b8bfa4559636 100644 --- a/toolchain/check/testdata/array/canonicalize_index.carbon +++ b/toolchain/check/testdata/array/canonicalize_index.carbon @@ -56,7 +56,7 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %bound_method.c6f: = bound_method %int_3.822, %Convert.specific_fn.8a8 [concrete] // CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %array_type: type = array_type %int_3.1ba, %i32 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %array_type [concrete] +// CHECK:STDOUT: %ptr.f01: type = ptr_type %array_type [concrete] // CHECK:STDOUT: %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %Convert.bound.b30: = bound_method %int_3.1ba, %Convert.956 [concrete] @@ -175,20 +175,20 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %array_type = bind_name a, %a.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %b.patt: %ptr = binding_pattern b +// CHECK:STDOUT: %b.patt: %ptr.f01 = binding_pattern b // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc15: type = splice_block %ptr.loc15 [concrete = constants.%ptr] { +// CHECK:STDOUT: %.loc15: type = splice_block %ptr.loc15 [concrete = constants.%ptr.f01] { // CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %int_3.loc15: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %array_type.loc15: type = array_type %int_3.loc15, %i32.loc15 [concrete = constants.%array_type] -// CHECK:STDOUT: %ptr.loc15: type = ptr_type %array_type.loc15 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr.loc15: type = ptr_type %array_type.loc15 [concrete = constants.%ptr.f01] // CHECK:STDOUT: } -// CHECK:STDOUT: %b: %ptr = bind_name b, @__global_init.%addr.loc15 +// CHECK:STDOUT: %b: %ptr.f01 = bind_name b, @__global_init.%addr.loc15 // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %c.patt: %ptr = binding_pattern c +// CHECK:STDOUT: %c.patt: %ptr.f01 = binding_pattern c // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc16_35: type = splice_block %ptr.loc16 [concrete = constants.%ptr] { +// CHECK:STDOUT: %.loc16_35: type = splice_block %ptr.loc16 [concrete = constants.%ptr.f01] { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %ConvertToU32.ref: %ConvertToU32.type = name_ref ConvertToU32, %ConvertToU32.decl [concrete = constants.%ConvertToU32] @@ -211,9 +211,9 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %.loc16_33.3: Core.IntLiteral = value_of_initializer %int.convert_checked.loc16_33.2 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %.loc16_33.4: Core.IntLiteral = converted %int.convert_checked.loc16_33.1, %.loc16_33.3 [concrete = constants.%int_3.1ba] // CHECK:STDOUT: %array_type.loc16: type = array_type %.loc16_33.4, %i32.loc16 [concrete = constants.%array_type] -// CHECK:STDOUT: %ptr.loc16: type = ptr_type %array_type.loc16 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr.loc16: type = ptr_type %array_type.loc16 [concrete = constants.%ptr.f01] // CHECK:STDOUT: } -// CHECK:STDOUT: %c: %ptr = bind_name c, @__global_init.%addr.loc16 +// CHECK:STDOUT: %c: %ptr.f01 = bind_name c, @__global_init.%addr.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @Add.1(%a.param_patt: %i32, %b.param_patt: %i32) -> %i32 = "int.sadd"; @@ -257,9 +257,9 @@ let c: array(i32, ConvertToU32(3))* = &a; // CHECK:STDOUT: %.loc14_1: init %array_type = converted %.loc14_40.1, %.loc14_40.11 [concrete = constants.%array] // CHECK:STDOUT: assign file.%a.var, %.loc14_1 // CHECK:STDOUT: %a.ref.loc15: ref %array_type = name_ref a, file.%a -// CHECK:STDOUT: %addr.loc15: %ptr = addr_of %a.ref.loc15 +// CHECK:STDOUT: %addr.loc15: %ptr.f01 = addr_of %a.ref.loc15 // CHECK:STDOUT: %a.ref.loc16: ref %array_type = name_ref a, file.%a -// CHECK:STDOUT: %addr.loc16: %ptr = addr_of %a.ref.loc16 +// CHECK:STDOUT: %addr.loc16: %ptr.f01 = addr_of %a.ref.loc16 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/builtins/int/and_assign.carbon b/toolchain/check/testdata/builtins/int/and_assign.carbon new file mode 100644 index 000000000000..335fb01a0109 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/and_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/and_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/and_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.and_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.and_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.and_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.and_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.and_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.and_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.and_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.and_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.and_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.and_assign"; diff --git a/toolchain/check/testdata/builtins/int/left_shift_assign.carbon b/toolchain/check/testdata/builtins/int/left_shift_assign.carbon new file mode 100644 index 000000000000..ed3bc0a24fd3 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/left_shift_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/left_shift_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/left_shift_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.left_shift_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +fn MixedTypes(a: i32*, b: i64) = "int.left_shift_assign"; + +fn CallMixed(a: i32*, b: i64) { + MixedTypes(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.left_shift_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.left_shift_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.left_shift_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.left_shift_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.left_shift_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.left_shift_assign"; diff --git a/toolchain/check/testdata/builtins/int/or_assign.carbon b/toolchain/check/testdata/builtins/int/or_assign.carbon new file mode 100644 index 000000000000..ed1f388be783 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/or_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/or_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/or_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.or_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.or_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.or_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.or_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.or_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.or_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.or_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.or_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.or_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.or_assign"; diff --git a/toolchain/check/testdata/builtins/int/right_shift_assign.carbon b/toolchain/check/testdata/builtins/int/right_shift_assign.carbon new file mode 100644 index 000000000000..e0102f9c819f --- /dev/null +++ b/toolchain/check/testdata/builtins/int/right_shift_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/right_shift_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/right_shift_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.right_shift_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +fn MixedTypes(a: i32*, b: i64) = "int.right_shift_assign"; + +fn CallMixed(a: i32*, b: i64) { + MixedTypes(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.right_shift_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.right_shift_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.right_shift_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.right_shift_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.right_shift_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.right_shift_assign"; diff --git a/toolchain/check/testdata/builtins/int/sadd_assign.carbon b/toolchain/check/testdata/builtins/int/sadd_assign.carbon new file mode 100644 index 000000000000..c5021a3c8b6a --- /dev/null +++ b/toolchain/check/testdata/builtins/int/sadd_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/sadd_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/sadd_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.sadd_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.sadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.sadd_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.sadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.sadd_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.sadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.sadd_assign"; diff --git a/toolchain/check/testdata/builtins/int/sdiv_assign.carbon b/toolchain/check/testdata/builtins/int/sdiv_assign.carbon new file mode 100644 index 000000000000..7e9198a85174 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/sdiv_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/sdiv_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/sdiv_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.sdiv_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sdiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.sdiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.sdiv_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sdiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.sdiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.sdiv_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.sdiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.sdiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.sdiv_assign"; diff --git a/toolchain/check/testdata/builtins/int/smod_assign.carbon b/toolchain/check/testdata/builtins/int/smod_assign.carbon new file mode 100644 index 000000000000..3c34c2f9774d --- /dev/null +++ b/toolchain/check/testdata/builtins/int/smod_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/smod_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/smod_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.smod_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.smod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.smod_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.smod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.smod_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.smod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.smod_assign"; diff --git a/toolchain/check/testdata/builtins/int/smul_assign.carbon b/toolchain/check/testdata/builtins/int/smul_assign.carbon new file mode 100644 index 000000000000..a80ba8acaf1e --- /dev/null +++ b/toolchain/check/testdata/builtins/int/smul_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/smul_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/smul_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.smul_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.smul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.smul_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.smul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.smul_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.smul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.smul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.smul_assign"; diff --git a/toolchain/check/testdata/builtins/int/ssub_assign.carbon b/toolchain/check/testdata/builtins/int/ssub_assign.carbon new file mode 100644 index 000000000000..c068fa58c05a --- /dev/null +++ b/toolchain/check/testdata/builtins/int/ssub_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/ssub_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/ssub_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.ssub_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.ssub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.ssub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.ssub_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.ssub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.ssub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.ssub_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.ssub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.ssub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.ssub_assign"; diff --git a/toolchain/check/testdata/builtins/int/uadd_assign.carbon b/toolchain/check/testdata/builtins/int/uadd_assign.carbon new file mode 100644 index 000000000000..38af1742fbae --- /dev/null +++ b/toolchain/check/testdata/builtins/int/uadd_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/uadd_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/uadd_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.uadd_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.uadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.uadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.uadd_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.uadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.uadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.uadd_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.uadd_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.uadd_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.uadd_assign"; diff --git a/toolchain/check/testdata/builtins/int/udiv_assign.carbon b/toolchain/check/testdata/builtins/int/udiv_assign.carbon new file mode 100644 index 000000000000..8e343dce17d4 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/udiv_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/udiv_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/udiv_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.udiv_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.udiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.udiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.udiv_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.udiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.udiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.udiv_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.udiv_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.udiv_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.udiv_assign"; diff --git a/toolchain/check/testdata/builtins/int/umod_assign.carbon b/toolchain/check/testdata/builtins/int/umod_assign.carbon new file mode 100644 index 000000000000..b14a9dc01eb0 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/umod_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/umod_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/umod_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.umod_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.umod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.umod_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.umod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.umod_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umod_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.umod_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.umod_assign"; diff --git a/toolchain/check/testdata/builtins/int/umul_assign.carbon b/toolchain/check/testdata/builtins/int/umul_assign.carbon new file mode 100644 index 000000000000..571466074676 --- /dev/null +++ b/toolchain/check/testdata/builtins/int/umul_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/umul_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/umul_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.umul_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.umul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.umul_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.umul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.umul_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.umul_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.umul_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.umul_assign"; diff --git a/toolchain/check/testdata/builtins/int/usub_assign.carbon b/toolchain/check/testdata/builtins/int/usub_assign.carbon new file mode 100644 index 000000000000..c5da5833f94a --- /dev/null +++ b/toolchain/check/testdata/builtins/int/usub_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/usub_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/usub_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.usub_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.usub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.usub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.usub_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.usub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.usub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.usub_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.usub_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.usub_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.usub_assign"; diff --git a/toolchain/check/testdata/builtins/int/xor_assign.carbon b/toolchain/check/testdata/builtins/int/xor_assign.carbon new file mode 100644 index 000000000000..0fd34bebb56a --- /dev/null +++ b/toolchain/check/testdata/builtins/int/xor_assign.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --no-dump-sem-ir +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/xor_assign.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/xor_assign.carbon + +// --- call.carbon + +library "[[@TEST_NAME]]"; + +fn Builtin(a: i32*, b: i32) = "int.xor_assign"; + +fn Call(a: i32*, b: i32) { + Builtin(a, b); +} + +// --- fail_unsized.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_unsized.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.xor_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.xor_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn Builtin(a: Core.IntLiteral()*, b: Core.IntLiteral()) = "int.xor_assign"; + +// --- fail_bad_decl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.xor_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn NotPtr(a: i32, b: i32) = "int.xor_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn NotPtr(a: i32, b: i32) = "int.xor_assign"; + +// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "int.xor_assign" [InvalidBuiltinSignature] +// CHECK:STDERR: fn MixedTypes(a: i32*, b: i64) = "int.xor_assign"; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +fn MixedTypes(a: i32*, b: i64) = "int.xor_assign"; diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index 5d260cbd0207..1d47fec133fa 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -368,5 +368,5 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @F[%self.param_patt: %ForwardDeclared.7b34f2.1]() [from "a.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: fn @G[addr .inst1161: %ptr.6cf]() [from "a.carbon"]; +// CHECK:STDOUT: fn @G[addr .inst1395: %ptr.6cf]() [from "a.carbon"]; // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/generic/param_in_type.carbon b/toolchain/check/testdata/function/generic/param_in_type.carbon index b147077309a3..b7f65b6edbdc 100644 --- a/toolchain/check/testdata/function/generic/param_in_type.carbon +++ b/toolchain/check/testdata/function/generic/param_in_type.carbon @@ -30,7 +30,7 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method: = bound_method %N.51e, %Convert.specific_fn [symbolic] // CHECK:STDOUT: %int.convert_checked: init Core.IntLiteral = call %bound_method(%N.51e) [symbolic] // CHECK:STDOUT: %array_type: type = array_type %int.convert_checked, %i32 [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type %array_type [symbolic] +// CHECK:STDOUT: %ptr.0ad: type = ptr_type %array_type [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -52,16 +52,16 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %N.patt.loc11_6.1: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc11_6.2 (constants.%N.patt.8e2)] -// CHECK:STDOUT: %a.patt: @F.%ptr.loc11_31.2 (%ptr) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @F.%ptr.loc11_31.2 (%ptr) = value_param_pattern %a.patt, call_param0 +// CHECK:STDOUT: %a.patt: @F.%ptr.loc11_31.2 (%ptr.0ad) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @F.%ptr.loc11_31.2 (%ptr.0ad) = value_param_pattern %a.patt, call_param0 // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc11_10: type = splice_block %i32.loc11_10 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32.loc11_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc11_6.1: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc11_6.2 (constants.%N.51e)] -// CHECK:STDOUT: %a.param: @F.%ptr.loc11_31.2 (%ptr) = value_param call_param0 -// CHECK:STDOUT: %.loc11_31: type = splice_block %ptr.loc11_31.1 [symbolic = %ptr.loc11_31.2 (constants.%ptr)] { +// CHECK:STDOUT: %a.param: @F.%ptr.loc11_31.2 (%ptr.0ad) = value_param call_param0 +// CHECK:STDOUT: %.loc11_31: type = splice_block %ptr.loc11_31.1 [symbolic = %ptr.loc11_31.2 (constants.%ptr.0ad)] { // CHECK:STDOUT: %int_32.loc11_24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11_24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc11_6.1 [symbolic = %N.loc11_6.2 (constants.%N.51e)] @@ -73,9 +73,9 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %.loc11_29.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc11_29.1 [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] // CHECK:STDOUT: %.loc11_29.2: Core.IntLiteral = converted %N.ref, %.loc11_29.1 [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] // CHECK:STDOUT: %array_type.loc11_30.1: type = array_type %.loc11_29.2, %i32.loc11_24 [symbolic = %array_type.loc11_30.2 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc11_31.1: type = ptr_type %array_type.loc11_30.1 [symbolic = %ptr.loc11_31.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc11_31.1: type = ptr_type %array_type.loc11_30.1 [symbolic = %ptr.loc11_31.2 (constants.%ptr.0ad)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%ptr.loc11_31.2 (%ptr) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%ptr.loc11_31.2 (%ptr.0ad) = bind_name a, %a.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -86,9 +86,9 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method.loc11_29.3: = bound_method %N.loc11_6.2, constants.%Convert.specific_fn [symbolic = %bound_method.loc11_29.3 (constants.%bound_method)] // CHECK:STDOUT: %int.convert_checked.loc11_29.2: init Core.IntLiteral = call %bound_method.loc11_29.3(%N.loc11_6.2) [symbolic = %int.convert_checked.loc11_29.2 (constants.%int.convert_checked)] // CHECK:STDOUT: %array_type.loc11_30.2: type = array_type %int.convert_checked.loc11_29.2, constants.%i32 [symbolic = %array_type.loc11_30.2 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc11_31.2: type = ptr_type %array_type.loc11_30.2 [symbolic = %ptr.loc11_31.2 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc11_31.2: type = ptr_type %array_type.loc11_30.2 [symbolic = %ptr.loc11_31.2 (constants.%ptr.0ad)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%N.patt.loc11_6.1: %i32, %a.param_patt: @F.%ptr.loc11_31.2 (%ptr)); +// CHECK:STDOUT: fn(%N.patt.loc11_6.1: %i32, %a.param_patt: @F.%ptr.loc11_31.2 (%ptr.0ad)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%N.51e) { @@ -98,6 +98,6 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method.loc11_29.3 => constants.%bound_method // CHECK:STDOUT: %int.convert_checked.loc11_29.2 => constants.%int.convert_checked // CHECK:STDOUT: %array_type.loc11_30.2 => constants.%array_type -// CHECK:STDOUT: %ptr.loc11_31.2 => constants.%ptr +// CHECK:STDOUT: %ptr.loc11_31.2 => constants.%ptr.0ad // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/if_expr/constant_condition.carbon b/toolchain/check/testdata/if_expr/constant_condition.carbon index f398338689b2..771899b7dfbe 100644 --- a/toolchain/check/testdata/if_expr/constant_condition.carbon +++ b/toolchain/check/testdata/if_expr/constant_condition.carbon @@ -65,7 +65,7 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: %false: bool = bool_literal false [concrete] // CHECK:STDOUT: %Constant.type: type = fn_type @Constant [concrete] // CHECK:STDOUT: %Constant: %Constant.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %PartiallyConstant.type: type = fn_type @PartiallyConstant [concrete] // CHECK:STDOUT: %PartiallyConstant: %PartiallyConstant.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -253,7 +253,7 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: !if.expr.else.loc23: // CHECK:STDOUT: %int_32.loc23_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc23_32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr.loc23: type = ptr_type %i32.loc23_32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr.loc23: type = ptr_type %i32.loc23_32 [concrete = constants.%ptr.235] // CHECK:STDOUT: br !if.expr.result.loc23(%ptr.loc23) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result.loc23: @@ -263,12 +263,12 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: !.loc23_7: // CHECK:STDOUT: %v: ref %i32 = bind_name v, %v.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %w.patt: %ptr = binding_pattern w -// CHECK:STDOUT: %.loc24_3: %ptr = var_pattern %w.patt +// CHECK:STDOUT: %w.patt: %ptr.235 = binding_pattern w +// CHECK:STDOUT: %.loc24_3: %ptr.235 = var_pattern %w.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %w.var: ref %ptr = var w +// CHECK:STDOUT: %w.var: ref %ptr.235 = var w // CHECK:STDOUT: %v.ref: ref %i32 = name_ref v, %v -// CHECK:STDOUT: %addr: %ptr = addr_of %v.ref +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %v.ref // CHECK:STDOUT: assign %w.var, %addr // CHECK:STDOUT: br !.loc24_13 // CHECK:STDOUT: @@ -284,17 +284,17 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: !if.expr.else.loc24: // CHECK:STDOUT: %int_32.loc24_33: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc24_33: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr.loc24: type = ptr_type %i32.loc24_33 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr.loc24: type = ptr_type %i32.loc24_33 [concrete = constants.%ptr.235] // CHECK:STDOUT: br !if.expr.result.loc24(%ptr.loc24) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result.loc24: -// CHECK:STDOUT: %.loc24_10: type = block_arg !if.expr.result.loc24 [concrete = constants.%ptr] +// CHECK:STDOUT: %.loc24_10: type = block_arg !if.expr.result.loc24 [concrete = constants.%ptr.235] // CHECK:STDOUT: br !.loc24_7 // CHECK:STDOUT: // CHECK:STDOUT: !.loc24_7: -// CHECK:STDOUT: %w: ref %ptr = bind_name w, %w.var -// CHECK:STDOUT: %w.ref: ref %ptr = name_ref w, %w -// CHECK:STDOUT: %.loc25_11: %ptr = bind_value %w.ref +// CHECK:STDOUT: %w: ref %ptr.235 = bind_name w, %w.var +// CHECK:STDOUT: %w.ref: ref %ptr.235 = name_ref w, %w +// CHECK:STDOUT: %.loc25_11: %ptr.235 = bind_value %w.ref // CHECK:STDOUT: %.loc25_10.1: ref %i32 = deref %.loc25_11 // CHECK:STDOUT: %.loc25_10.2: %i32 = bind_value %.loc25_10.1 // CHECK:STDOUT: return %.loc25_10.2 @@ -337,12 +337,12 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: !.loc29_7: // CHECK:STDOUT: %v: ref %i32 = bind_name v, %v.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %w.patt: %ptr = binding_pattern w -// CHECK:STDOUT: %.loc30_3: %ptr = var_pattern %w.patt +// CHECK:STDOUT: %w.patt: %ptr.235 = binding_pattern w +// CHECK:STDOUT: %.loc30_3: %ptr.235 = var_pattern %w.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %w.var: ref %ptr = var w +// CHECK:STDOUT: %w.var: ref %ptr.235 = var w // CHECK:STDOUT: %v.ref: ref %i32 = name_ref v, %v -// CHECK:STDOUT: %addr: %ptr = addr_of %v.ref +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %v.ref // CHECK:STDOUT: assign %w.var, %addr // CHECK:STDOUT: br !.loc30_13 // CHECK:STDOUT: @@ -357,17 +357,17 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: !if.expr.else.loc30: // CHECK:STDOUT: %int_32.loc30: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc30: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc30 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc30 [concrete = constants.%ptr.235] // CHECK:STDOUT: br !if.expr.result.loc30(%ptr) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result.loc30: -// CHECK:STDOUT: %.loc30_10: type = block_arg !if.expr.result.loc30 [concrete = constants.%ptr] +// CHECK:STDOUT: %.loc30_10: type = block_arg !if.expr.result.loc30 [concrete = constants.%ptr.235] // CHECK:STDOUT: br !.loc30_7 // CHECK:STDOUT: // CHECK:STDOUT: !.loc30_7: -// CHECK:STDOUT: %w: ref %ptr = bind_name w, %w.var -// CHECK:STDOUT: %w.ref: ref %ptr = name_ref w, %w -// CHECK:STDOUT: %.loc31_11: %ptr = bind_value %w.ref +// CHECK:STDOUT: %w: ref %ptr.235 = bind_name w, %w.var +// CHECK:STDOUT: %w.ref: ref %ptr.235 = name_ref w, %w +// CHECK:STDOUT: %.loc31_11: %ptr.235 = bind_value %w.ref // CHECK:STDOUT: %.loc31_10.1: ref %i32 = deref %.loc31_11 // CHECK:STDOUT: %.loc31_10.2: %i32 = bind_value %.loc31_10.1 // CHECK:STDOUT: return %.loc31_10.2 diff --git a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon index 2a7d7708818b..fddd12e5d0a1 100644 --- a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon +++ b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon @@ -94,7 +94,7 @@ class C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: %i32 = bind_name x, .inst1083.loc27_14 +// CHECK:STDOUT: %x: %i32 = bind_name x, .inst1317.loc27_14 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %y.patt: %i32 = binding_pattern y // CHECK:STDOUT: %.loc37: %i32 = var_pattern %y.patt diff --git a/toolchain/check/testdata/impl/impl_assoc_const.carbon b/toolchain/check/testdata/impl/impl_assoc_const.carbon index 9136fd24aa59..193d7232c94e 100644 --- a/toolchain/check/testdata/impl/impl_assoc_const.carbon +++ b/toolchain/check/testdata/impl/impl_assoc_const.carbon @@ -71,21 +71,21 @@ impl () as I where .X = {.a = true, .b = (1, 2)} and .X = {.a = false, .b = (3, // CHECK:STDOUT: %struct: %struct_type.a.b.fe2 = struct_value (%true, %tuple) [concrete] // CHECK:STDOUT: %false: bool = bool_literal false [concrete] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete] -// CHECK:STDOUT: %Op.type.111: type = fn_type @Op.13 [concrete] +// CHECK:STDOUT: %Op.type.111: type = fn_type @Op.23 [concrete] // CHECK:STDOUT: %Sub.impl_witness_table.d7b = impl_witness_table (imports.%Core.import_ref.6c4), @impl.bf8 [concrete] // CHECK:STDOUT: %Sub.impl_witness.37d: = impl_witness %Sub.impl_witness_table.d7b [concrete] // CHECK:STDOUT: %Sub.facet: %Sub.type = facet_value Core.IntLiteral, (%Sub.impl_witness.37d) [concrete] // CHECK:STDOUT: %.07b: type = fn_type_with_self_type %Op.type.111, %Sub.facet [concrete] -// CHECK:STDOUT: %Op.type.2b9: type = fn_type @Op.14 [concrete] +// CHECK:STDOUT: %Op.type.2b9: type = fn_type @Op.24 [concrete] // CHECK:STDOUT: %Op.667: %Op.type.2b9 = struct_value () [concrete] // CHECK:STDOUT: %Op.bound.645: = bound_method %int_3, %Op.667 [concrete] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete] -// CHECK:STDOUT: %Op.type.784: type = fn_type @Op.15 [concrete] +// CHECK:STDOUT: %Op.type.784: type = fn_type @Op.25 [concrete] // CHECK:STDOUT: %Div.impl_witness_table.381 = impl_witness_table (imports.%Core.import_ref.dfd), @impl.f0e [concrete] // CHECK:STDOUT: %Div.impl_witness.ec4: = impl_witness %Div.impl_witness_table.381 [concrete] // CHECK:STDOUT: %Div.facet: %Div.type = facet_value Core.IntLiteral, (%Div.impl_witness.ec4) [concrete] // CHECK:STDOUT: %.d13: type = fn_type_with_self_type %Op.type.784, %Div.facet [concrete] -// CHECK:STDOUT: %Op.type.c38: type = fn_type @Op.16 [concrete] +// CHECK:STDOUT: %Op.type.c38: type = fn_type @Op.26 [concrete] // CHECK:STDOUT: %Op.553: %Op.type.c38 = struct_value () [concrete] // CHECK:STDOUT: %Op.bound.2e7: = bound_method %int_4, %Op.553 [concrete] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %struct> [concrete] diff --git a/toolchain/check/testdata/index/fail_negative_indexing.carbon b/toolchain/check/testdata/index/fail_negative_indexing.carbon index 18c90c1065b9..27449fdb5985 100644 --- a/toolchain/check/testdata/index/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/index/fail_negative_indexing.carbon @@ -42,12 +42,12 @@ var d: i32 = c[-10]; // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %array: %array_type = tuple_value (%int_42.c68, %int_42.c68) [concrete] // CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete] -// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.13 [concrete] +// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.23 [concrete] // CHECK:STDOUT: %Negate.impl_witness_table.e09 = impl_witness_table (imports.%Core.import_ref.c15), @impl.8cb [concrete] // CHECK:STDOUT: %Negate.impl_witness.561: = impl_witness %Negate.impl_witness_table.e09 [concrete] // CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value Core.IntLiteral, (%Negate.impl_witness.561) [concrete] // CHECK:STDOUT: %.63a: type = fn_type_with_self_type %Op.type.e42, %Negate.facet [concrete] -// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.14 [concrete] +// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.24 [concrete] // CHECK:STDOUT: %Op.bba: %Op.type.1be = struct_value () [concrete] // CHECK:STDOUT: %Op.bound: = bound_method %int_10, %Op.bba [concrete] // CHECK:STDOUT: %int_-10.06d: Core.IntLiteral = int_value -10 [concrete] diff --git a/toolchain/check/testdata/interop/cpp/function_decl.carbon b/toolchain/check/testdata/interop/cpp/function_decl.carbon index 01d1660115d6..5c8ee8275071 100644 --- a/toolchain/check/testdata/interop/cpp/function_decl.carbon +++ b/toolchain/check/testdata/interop/cpp/function_decl.carbon @@ -895,7 +895,7 @@ fn F() { // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.956, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -947,7 +947,7 @@ fn F() { // CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: = name_ref foo, [concrete = ] // CHECK:STDOUT: %a.ref: ref %i32 = name_ref a, %a -// CHECK:STDOUT: %addr: %ptr = addr_of %a.ref +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %a.ref // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/pointer/address_of_deref.carbon b/toolchain/check/testdata/pointer/address_of_deref.carbon index 8a841343266d..c0ba4bceb353 100644 --- a/toolchain/check/testdata/pointer/address_of_deref.carbon +++ b/toolchain/check/testdata/pointer/address_of_deref.carbon @@ -33,7 +33,7 @@ fn F() -> i32 { // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.956, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -83,9 +83,9 @@ fn F() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %n: ref %i32 = bind_name n, %n.var // CHECK:STDOUT: %n.ref: ref %i32 = name_ref n, %n -// CHECK:STDOUT: %addr.loc13_13: %ptr = addr_of %n.ref +// CHECK:STDOUT: %addr.loc13_13: %ptr.235 = addr_of %n.ref // CHECK:STDOUT: %.loc13_12: ref %i32 = deref %addr.loc13_13 -// CHECK:STDOUT: %addr.loc13_11: %ptr = addr_of %.loc13_12 +// CHECK:STDOUT: %addr.loc13_11: %ptr.235 = addr_of %.loc13_12 // CHECK:STDOUT: %.loc13_10.1: ref %i32 = deref %addr.loc13_11 // CHECK:STDOUT: %.loc13_10.2: %i32 = bind_value %.loc13_10.1 // CHECK:STDOUT: return %.loc13_10.2 diff --git a/toolchain/check/testdata/pointer/basic.carbon b/toolchain/check/testdata/pointer/basic.carbon index fcc3ba67032e..c543495cad1f 100644 --- a/toolchain/check/testdata/pointer/basic.carbon +++ b/toolchain/check/testdata/pointer/basic.carbon @@ -35,7 +35,7 @@ fn F() -> i32 { // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.956, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -85,21 +85,21 @@ fn F() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %n: ref %i32 = bind_name n, %n.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %p.patt: %ptr = binding_pattern p -// CHECK:STDOUT: %.loc13_3: %ptr = var_pattern %p.patt +// CHECK:STDOUT: %p.patt: %ptr.235 = binding_pattern p +// CHECK:STDOUT: %.loc13_3: %ptr.235 = var_pattern %p.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %p.var: ref %ptr = var p +// CHECK:STDOUT: %p.var: ref %ptr.235 = var p // CHECK:STDOUT: %n.ref: ref %i32 = name_ref n, %n -// CHECK:STDOUT: %addr: %ptr = addr_of %n.ref +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %n.ref // CHECK:STDOUT: assign %p.var, %addr -// CHECK:STDOUT: %.loc13_13: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %.loc13_13: type = splice_block %ptr [concrete = constants.%ptr.235] { // CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc13: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc13 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc13 [concrete = constants.%ptr.235] // CHECK:STDOUT: } -// CHECK:STDOUT: %p: ref %ptr = bind_name p, %p.var -// CHECK:STDOUT: %p.ref: ref %ptr = name_ref p, %p -// CHECK:STDOUT: %.loc15_11: %ptr = bind_value %p.ref +// CHECK:STDOUT: %p: ref %ptr.235 = bind_name p, %p.var +// CHECK:STDOUT: %p.ref: ref %ptr.235 = name_ref p, %p +// CHECK:STDOUT: %.loc15_11: %ptr.235 = bind_value %p.ref // CHECK:STDOUT: %.loc15_10.1: ref %i32 = deref %.loc15_11 // CHECK:STDOUT: %.loc15_10.2: %i32 = bind_value %.loc15_10.1 // CHECK:STDOUT: return %.loc15_10.2 diff --git a/toolchain/check/testdata/pointer/import.carbon b/toolchain/check/testdata/pointer/import.carbon index 8bdd512bfe66..094400198275 100644 --- a/toolchain/check/testdata/pointer/import.carbon +++ b/toolchain/check/testdata/pointer/import.carbon @@ -39,7 +39,7 @@ var a: i32* = a_ref; // CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.956, @Convert.2(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -69,16 +69,16 @@ var a: i32* = a_ref; // CHECK:STDOUT: } // CHECK:STDOUT: %a_orig: ref %i32 = bind_name a_orig, %a_orig.var // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %a_ref.patt: %ptr = binding_pattern a_ref -// CHECK:STDOUT: %.loc5_1: %ptr = var_pattern %a_ref.patt +// CHECK:STDOUT: %a_ref.patt: %ptr.235 = binding_pattern a_ref +// CHECK:STDOUT: %.loc5_1: %ptr.235 = var_pattern %a_ref.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %a_ref.var: ref %ptr = var a_ref -// CHECK:STDOUT: %.loc5_15: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %a_ref.var: ref %ptr.235 = var a_ref +// CHECK:STDOUT: %.loc5_15: type = splice_block %ptr [concrete = constants.%ptr.235] { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc5 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc5 [concrete = constants.%ptr.235] // CHECK:STDOUT: } -// CHECK:STDOUT: %a_ref: ref %ptr = bind_name a_ref, %a_ref.var +// CHECK:STDOUT: %a_ref: ref %ptr.235 = bind_name a_ref, %a_ref.var // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -92,7 +92,7 @@ var a: i32* = a_ref; // CHECK:STDOUT: %.loc4: init %i32 = converted %int_0, %int.convert_checked [concrete = constants.%int_0.6a9] // CHECK:STDOUT: assign file.%a_orig.var, %.loc4 // CHECK:STDOUT: %a_orig.ref: ref %i32 = name_ref a_orig, file.%a_orig -// CHECK:STDOUT: %addr: %ptr = addr_of %a_orig.ref +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %a_orig.ref // CHECK:STDOUT: assign file.%a_ref.var, %addr // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -102,12 +102,12 @@ var a: i32* = a_ref; // CHECK:STDOUT: constants { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.9e1: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Implicit.a_orig = import_ref Implicit//default, a_orig, unloaded -// CHECK:STDOUT: %Implicit.a_ref: ref %ptr = import_ref Implicit//default, a_ref, loaded +// CHECK:STDOUT: %Implicit.a_ref: ref %ptr.9e1 = import_ref Implicit//default, a_ref, loaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude @@ -126,22 +126,22 @@ var a: i32* = a_ref; // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %a.patt: %ptr = binding_pattern a -// CHECK:STDOUT: %.loc4_1: %ptr = var_pattern %a.patt +// CHECK:STDOUT: %a.patt: %ptr.9e1 = binding_pattern a +// CHECK:STDOUT: %.loc4_1: %ptr.9e1 = var_pattern %a.patt // CHECK:STDOUT: } -// CHECK:STDOUT: %a.var: ref %ptr = var a -// CHECK:STDOUT: %.loc4_11: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %a.var: ref %ptr.9e1 = var a +// CHECK:STDOUT: %.loc4_11: type = splice_block %ptr [concrete = constants.%ptr.9e1] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr.9e1] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: ref %ptr = bind_name a, %a.var +// CHECK:STDOUT: %a: ref %ptr.9e1 = bind_name a, %a.var // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a_ref.ref: ref %ptr = name_ref a_ref, imports.%Implicit.a_ref -// CHECK:STDOUT: %.loc4: %ptr = bind_value %a_ref.ref +// CHECK:STDOUT: %a_ref.ref: ref %ptr.9e1 = name_ref a_ref, imports.%Implicit.a_ref +// CHECK:STDOUT: %.loc4: %ptr.9e1 = bind_value %a_ref.ref // CHECK:STDOUT: assign file.%a.var, %.loc4 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index ea53e83c3f83..d7ea63782419 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -331,7 +331,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1160 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1394 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -508,7 +508,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1160 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1394 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -626,7 +626,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1160 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1394 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon index ad33f0e2547c..0397ee91aa98 100644 --- a/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon +++ b/toolchain/check/testdata/tuple/access/fail_negative_indexing.carbon @@ -43,12 +43,12 @@ var b: i32 = a.(-10); // CHECK:STDOUT: %int_6.e56: %i32 = int_value 6 [concrete] // CHECK:STDOUT: %tuple: %tuple.type.d07 = tuple_value (%int_12.1e1, %int_6.e56) [concrete] // CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete] -// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.13 [concrete] +// CHECK:STDOUT: %Op.type.e42: type = fn_type @Op.23 [concrete] // CHECK:STDOUT: %Negate.impl_witness_table.e09 = impl_witness_table (imports.%Core.import_ref.c15), @impl.8cb [concrete] // CHECK:STDOUT: %Negate.impl_witness.561: = impl_witness %Negate.impl_witness_table.e09 [concrete] // CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value Core.IntLiteral, (%Negate.impl_witness.561) [concrete] // CHECK:STDOUT: %.63a: type = fn_type_with_self_type %Op.type.e42, %Negate.facet [concrete] -// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.14 [concrete] +// CHECK:STDOUT: %Op.type.1be: type = fn_type @Op.24 [concrete] // CHECK:STDOUT: %Op.bba: %Op.type.1be = struct_value () [concrete] // CHECK:STDOUT: %Op.bound: = bound_method %int_10, %Op.bba [concrete] // CHECK:STDOUT: %int_-10: Core.IntLiteral = int_value -10 [concrete] diff --git a/toolchain/check/testdata/tuple/import.carbon b/toolchain/check/testdata/tuple/import.carbon index 9a713eae51f2..8f48f9db4085 100644 --- a/toolchain/check/testdata/tuple/import.carbon +++ b/toolchain/check/testdata/tuple/import.carbon @@ -361,7 +361,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1197 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1431 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -554,7 +554,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1197 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1431 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -673,7 +673,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1197 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1431 [no loc], unloaded // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index cb5aa4b7e537..317742221e84 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -7,6 +7,7 @@ #include "common/vlog.h" #include "toolchain/base/kind_switch.h" #include "toolchain/sem_ir/file.h" +#include "toolchain/sem_ir/generic.h" namespace Carbon::Lower { @@ -171,6 +172,10 @@ auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id, } } +auto FunctionContext::GetTypeOfInst(SemIR::InstId inst_id) -> SemIR::TypeId { + return SemIR::GetTypeOfInstInSpecific(sem_ir(), specific_id(), inst_id); +} + auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, SemIR::InstId dest_id) -> void { switch (auto rep = SemIR::ValueRepr::ForType(sem_ir(), type_id); rep.kind) { diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index fc19c112fa9f..5b90afa5ac2b 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -92,6 +92,9 @@ class FunctionContext { return file_context_->GetType(type_id); } + // Returns the type of the given instruction in the current specific. + auto GetTypeOfInst(SemIR::InstId inst_id) -> SemIR::TypeId; + // Returns a lowered value to use for a value of type `type`. auto GetTypeAsValue() -> llvm::Value* { return file_context_->GetTypeAsValue(); diff --git a/toolchain/lower/handle_call.cpp b/toolchain/lower/handle_call.cpp index 58425f365d1b..cd8d8615e752 100644 --- a/toolchain/lower/handle_call.cpp +++ b/toolchain/lower/handle_call.cpp @@ -64,8 +64,7 @@ static auto GetBuiltinFCmpPredicate(SemIR::BuiltinFunctionKind builtin_kind) // Returns whether the specified instruction has a signed integer type. static auto IsSignedInt(FunctionContext& context, SemIR::InstId int_id) -> bool { - return context.sem_ir().types().IsSignedInt( - context.sem_ir().insts().Get(int_id).type_id()); + return context.sem_ir().types().IsSignedInt(context.GetTypeOfInst(int_id)); } // Creates a zext or sext instruction depending on the signedness of the @@ -86,13 +85,10 @@ static auto CreateExtOrTrunc(FunctionContext& context, llvm::Value* value, : context.builder().CreateZExtOrTrunc(value, type, name); } -// Handles a call to a builtin integer bit shift operator. -static auto HandleIntShift(FunctionContext& context, SemIR::InstId inst_id, +// Create a integer bit shift for a call to a builtin bit shift function. +static auto CreateIntShift(FunctionContext& context, llvm::Instruction::BinaryOps bin_op, - SemIR::InstId lhs_id, SemIR::InstId rhs_id) -> void { - llvm::Value* lhs = context.GetValue(lhs_id); - llvm::Value* rhs = context.GetValue(rhs_id); - + llvm::Value* lhs, llvm::Value* rhs) -> llvm::Value* { // Weirdly, LLVM requires the operands of bit shift operators to be of the // same type. We can always use the width of the LHS, because if the RHS // doesn't fit in that then the cast is out of range anyway. Zero-extending is @@ -102,8 +98,7 @@ static auto HandleIntShift(FunctionContext& context, SemIR::InstId inst_id, // negative or greater than or equal to the number of bits in the left-hand // type. rhs = context.builder().CreateZExtOrTrunc(rhs, lhs->getType(), "rhs"); - - context.SetLocal(inst_id, context.builder().CreateBinOp(bin_op, lhs, rhs)); + return context.builder().CreateBinOp(bin_op, lhs, rhs); } // Handles a call to a builtin integer comparison operator. @@ -150,6 +145,102 @@ static auto HandleIntComparison(FunctionContext& context, SemIR::InstId inst_id, GetBuiltinICmpPredicate(builtin_kind, cmp_signed), lhs, rhs)); } +// Creates a binary operator for a call to a builtin for either that operation +// or the corresponding compound assignment. +static auto CreateBinaryOperatorForBuiltin( + FunctionContext& context, SemIR::InstId inst_id, + SemIR::BuiltinFunctionKind builtin_kind, llvm::Value* lhs, llvm::Value* rhs) + -> llvm::Value* { + // TODO: Consider setting this to true in the performance build mode if the + // result type is a signed integer type. + constexpr bool SignedOverflowIsUB = false; + + switch (builtin_kind) { + case SemIR::BuiltinFunctionKind::IntSAdd: + case SemIR::BuiltinFunctionKind::IntSAddAssign: { + return context.builder().CreateAdd(lhs, rhs, "", + /*HasNUW=*/false, + /*HasNSW=*/SignedOverflowIsUB); + } + case SemIR::BuiltinFunctionKind::IntSSub: + case SemIR::BuiltinFunctionKind::IntSSubAssign: { + return context.builder().CreateSub(lhs, rhs, "", + /*HasNUW=*/false, + /*HasNSW=*/SignedOverflowIsUB); + } + case SemIR::BuiltinFunctionKind::IntSMul: + case SemIR::BuiltinFunctionKind::IntSMulAssign: { + return context.builder().CreateMul(lhs, rhs, "", + /*HasNUW=*/false, + /*HasNSW=*/SignedOverflowIsUB); + } + case SemIR::BuiltinFunctionKind::IntSDiv: + case SemIR::BuiltinFunctionKind::IntSDivAssign: { + return context.builder().CreateSDiv(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntSMod: + case SemIR::BuiltinFunctionKind::IntSModAssign: { + return context.builder().CreateSRem(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntUAdd: + case SemIR::BuiltinFunctionKind::IntUAddAssign: { + return context.builder().CreateAdd(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntUSub: + case SemIR::BuiltinFunctionKind::IntUSubAssign: { + return context.builder().CreateSub(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntUMul: + case SemIR::BuiltinFunctionKind::IntUMulAssign: { + return context.builder().CreateMul(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntUDiv: + case SemIR::BuiltinFunctionKind::IntUDivAssign: { + return context.builder().CreateUDiv(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntUMod: + case SemIR::BuiltinFunctionKind::IntUModAssign: { + return context.builder().CreateURem(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntAnd: + case SemIR::BuiltinFunctionKind::IntAndAssign: { + return context.builder().CreateAnd(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntOr: + case SemIR::BuiltinFunctionKind::IntOrAssign: { + return context.builder().CreateOr(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntXor: + case SemIR::BuiltinFunctionKind::IntXorAssign: { + return context.builder().CreateXor(lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntLeftShift: + case SemIR::BuiltinFunctionKind::IntLeftShiftAssign: { + return CreateIntShift(context, llvm::Instruction::Shl, lhs, rhs); + } + case SemIR::BuiltinFunctionKind::IntRightShift: + case SemIR::BuiltinFunctionKind::IntRightShiftAssign: { + // TODO: Split each of these builtins into separate signed and unsigned + // builtins rather than working out here whether we're performing an + // arithmetic or logical shift. + auto lhs_id = context.sem_ir().inst_blocks().Get( + context.sem_ir().insts().GetAs(inst_id).args_id)[0]; + auto lhs_type_id = context.GetTypeOfInst(lhs_id); + if (builtin_kind == SemIR::BuiltinFunctionKind::IntRightShiftAssign) { + lhs_type_id = context.sem_ir().GetPointeeType(lhs_type_id); + } + return CreateIntShift(context, + context.sem_ir().types().IsSignedInt(lhs_type_id) + ? llvm::Instruction::AShr + : llvm::Instruction::LShr, + lhs, rhs); + } + default: { + CARBON_FATAL("Unexpected binary operator {0}", builtin_kind); + } + } +} + // Handles a call to a builtin function. static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, SemIR::BuiltinFunctionKind builtin_kind, @@ -262,100 +353,56 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id, llvm::ConstantInt::getSigned(operand->getType(), -1), operand)); return; } - case SemIR::BuiltinFunctionKind::IntSAdd: { - context.SetLocal( - inst_id, context.builder().CreateAdd(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]), "", - /*HasNUW=*/false, - /*HasNSW=*/SignedOverflowIsUB)); - return; - } - case SemIR::BuiltinFunctionKind::IntSSub: { - context.SetLocal( - inst_id, context.builder().CreateSub(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]), "", - /*HasNUW=*/false, - /*HasNSW=*/SignedOverflowIsUB)); - return; - } - case SemIR::BuiltinFunctionKind::IntSMul: { - context.SetLocal( - inst_id, context.builder().CreateMul(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]), "", - /*HasNUW=*/false, - /*HasNSW=*/SignedOverflowIsUB)); - return; - } - case SemIR::BuiltinFunctionKind::IntSDiv: { - context.SetLocal( - inst_id, context.builder().CreateSDiv(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntSMod: { - context.SetLocal( - inst_id, context.builder().CreateSRem(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntUAdd: { - context.SetLocal( - inst_id, context.builder().CreateAdd(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntUSub: { - context.SetLocal( - inst_id, context.builder().CreateSub(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntUMul: { - context.SetLocal( - inst_id, context.builder().CreateMul(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntUDiv: { - context.SetLocal( - inst_id, context.builder().CreateUDiv(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntUMod: { - context.SetLocal( - inst_id, context.builder().CreateURem(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntAnd: { - context.SetLocal( - inst_id, context.builder().CreateAnd(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntOr: { - context.SetLocal( - inst_id, context.builder().CreateOr(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntXor: { - context.SetLocal( - inst_id, context.builder().CreateXor(context.GetValue(arg_ids[0]), - context.GetValue(arg_ids[1]))); - return; - } - case SemIR::BuiltinFunctionKind::IntLeftShift: { - HandleIntShift(context, inst_id, llvm::Instruction::Shl, arg_ids[0], - arg_ids[1]); - return; - } + case SemIR::BuiltinFunctionKind::IntSAdd: + case SemIR::BuiltinFunctionKind::IntSSub: + case SemIR::BuiltinFunctionKind::IntSMul: + case SemIR::BuiltinFunctionKind::IntSDiv: + case SemIR::BuiltinFunctionKind::IntSMod: + case SemIR::BuiltinFunctionKind::IntUAdd: + case SemIR::BuiltinFunctionKind::IntUSub: + case SemIR::BuiltinFunctionKind::IntUMul: + case SemIR::BuiltinFunctionKind::IntUDiv: + case SemIR::BuiltinFunctionKind::IntUMod: + case SemIR::BuiltinFunctionKind::IntAnd: + case SemIR::BuiltinFunctionKind::IntOr: + case SemIR::BuiltinFunctionKind::IntXor: + case SemIR::BuiltinFunctionKind::IntLeftShift: case SemIR::BuiltinFunctionKind::IntRightShift: { - HandleIntShift(context, inst_id, - IsSignedInt(context, inst_id) ? llvm::Instruction::AShr - : llvm::Instruction::LShr, - arg_ids[0], arg_ids[1]); + context.SetLocal(inst_id, CreateBinaryOperatorForBuiltin( + context, inst_id, builtin_kind, + context.GetValue(arg_ids[0]), + context.GetValue(arg_ids[1]))); + return; + } + case SemIR::BuiltinFunctionKind::IntSAddAssign: + case SemIR::BuiltinFunctionKind::IntSSubAssign: + case SemIR::BuiltinFunctionKind::IntSMulAssign: + case SemIR::BuiltinFunctionKind::IntSDivAssign: + case SemIR::BuiltinFunctionKind::IntSModAssign: + case SemIR::BuiltinFunctionKind::IntUAddAssign: + case SemIR::BuiltinFunctionKind::IntUSubAssign: + case SemIR::BuiltinFunctionKind::IntUMulAssign: + case SemIR::BuiltinFunctionKind::IntUDivAssign: + case SemIR::BuiltinFunctionKind::IntUModAssign: + case SemIR::BuiltinFunctionKind::IntAndAssign: + case SemIR::BuiltinFunctionKind::IntOrAssign: + case SemIR::BuiltinFunctionKind::IntXorAssign: + case SemIR::BuiltinFunctionKind::IntLeftShiftAssign: + case SemIR::BuiltinFunctionKind::IntRightShiftAssign: { + auto* lhs_ptr = context.GetValue(arg_ids[0]); + auto lhs_type_id = context.GetTypeOfInst(arg_ids[0]); + auto pointee_type_id = context.sem_ir().GetPointeeType(lhs_type_id); + // TODO: Factor out the code to create loads and stores, and include alias + // and alignment information. + auto* lhs_value = context.builder().CreateLoad( + context.GetType(pointee_type_id), lhs_ptr); + auto* result = CreateBinaryOperatorForBuiltin( + context, inst_id, builtin_kind, lhs_value, + context.GetValue(arg_ids[1])); + context.builder().CreateStore(result, lhs_ptr); + // TODO: Add a helper to get a "no value representation" value. + context.SetLocal(inst_id, llvm::PoisonValue::get(context.GetType( + context.GetTypeOfInst(inst_id)))); return; } case SemIR::BuiltinFunctionKind::IntEq: @@ -444,8 +491,7 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, std::vector args; - auto inst_type_id = SemIR::GetTypeOfInstInSpecific( - context.sem_ir(), context.specific_id(), inst_id); + auto inst_type_id = context.GetTypeOfInst(inst_id); if (SemIR::ReturnTypeInfo::ForType(context.sem_ir(), inst_type_id) .has_return_slot()) { @@ -454,7 +500,7 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, } for (auto arg_id : arg_ids) { - auto arg_type_id = context.sem_ir().insts().Get(arg_id).type_id(); + auto arg_type_id = context.GetTypeOfInst(arg_id); if (SemIR::ValueRepr::ForType(context.sem_ir(), arg_type_id).kind != SemIR::ValueRepr::None) { args.push_back(context.GetValue(arg_id)); diff --git a/toolchain/lower/testdata/builtins/int.carbon b/toolchain/lower/testdata/builtins/int.carbon index 015d3e5ab45a..1e035ce45092 100644 --- a/toolchain/lower/testdata/builtins/int.carbon +++ b/toolchain/lower/testdata/builtins/int.carbon @@ -69,6 +69,58 @@ fn TestGreater(a: i32, b: i32) -> bool { return Greater(a, b); } fn GreaterEq(a: i32, b: i32) -> bool = "int.greater_eq"; fn TestGreaterEq(a: i32, b: i32) -> bool { return GreaterEq(a, b); } +// --- compound_assign.carbon + +library "[[@TEST_NAME]]"; + +fn SAdd(a: i32*, b: i32) = "int.sadd_assign"; +fn TestSAdd(a: i32*, b: i32) { SAdd(a, b); } + +fn SSub(a: i32*, b: i32) = "int.ssub_assign"; +fn TestSSub(a: i32*, b: i32) { SSub(a, b); } + +fn SMul(a: i32*, b: i32) = "int.smul_assign"; +fn TestSMul(a: i32*, b: i32) { SMul(a, b); } + +fn SDiv(a: i32*, b: i32) = "int.sdiv_assign"; +fn TestSDiv(a: i32*, b: i32) { SDiv(a, b); } + +fn SMod(a: i32*, b: i32) = "int.smod_assign"; +fn TestSMod(a: i32*, b: i32) { SMod(a, b); } + +fn UAdd(a: i32*, b: i32) = "int.uadd_assign"; +fn TestUAdd(a: i32*, b: i32) { UAdd(a, b); } + +fn USub(a: i32*, b: i32) = "int.usub_assign"; +fn TestUSub(a: i32*, b: i32) { USub(a, b); } + +fn UMul(a: i32*, b: i32) = "int.umul_assign"; +fn TestUMul(a: i32*, b: i32) { UMul(a, b); } + +fn UDiv(a: i32*, b: i32) = "int.udiv_assign"; +fn TestUDiv(a: i32*, b: i32) { UDiv(a, b); } + +fn UMod(a: i32*, b: i32) = "int.umod_assign"; +fn TestUMod(a: i32*, b: i32) { UMod(a, b); } + +fn And(a: i32*, b: i32) = "int.and_assign"; +fn TestAnd(a: i32*, b: i32) { And(a, b); } + +fn Or(a: i32*, b: i32) = "int.or_assign"; +fn TestOr(a: i32*, b: i32) { Or(a, b); } + +fn Xor(a: i32*, b: i32) = "int.xor_assign"; +fn TestXor(a: i32*, b: i32) { Xor(a, b); } + +fn LeftShift(a: i32*, b: i32) = "int.left_shift_assign"; +fn TestLeftShift(a: i32*, b: i32) { LeftShift(a, b); } + +fn ArithmeticRightShift(a: i32*, b: u32) = "int.right_shift_assign"; +fn TestArithmeticRightShift(a: i32*, b: u32) { ArithmeticRightShift(a, b); } + +fn LogicalRightShift(a: u32*, b: u32) = "int.right_shift_assign"; +fn TestLogicalRightShift(a: u32*, b: u32) { LogicalRightShift(a, b); } + // --- mixed_shift.carbon library "[[@TEST_NAME]]"; @@ -351,6 +403,194 @@ fn TestUint32ToUint64(a: u32) -> u64 { return Uint32ToUint64(a); } // CHECK:STDOUT: !60 = distinct !DISubprogram(name: "TestGreaterEq", linkageName: "_CTestGreaterEq.Main", scope: null, file: !3, line: 59, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !61 = !DILocation(line: 59, column: 51, scope: !60) // CHECK:STDOUT: !62 = !DILocation(line: 59, column: 44, scope: !60) +// CHECK:STDOUT: ; ModuleID = 'compound_assign.carbon' +// CHECK:STDOUT: source_filename = "compound_assign.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestSAdd.Main(ptr %a, i32 %b) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.sadd_assign = load i32, ptr %a, align 4, !dbg !7 +// CHECK:STDOUT: %int.sadd_assign1 = add i32 %int.sadd_assign, %b, !dbg !7 +// CHECK:STDOUT: store i32 %int.sadd_assign1, ptr %a, align 4, !dbg !7 +// CHECK:STDOUT: ret void, !dbg !8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestSSub.Main(ptr %a, i32 %b) !dbg !9 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.ssub_assign = load i32, ptr %a, align 4, !dbg !10 +// CHECK:STDOUT: %int.ssub_assign1 = sub i32 %int.ssub_assign, %b, !dbg !10 +// CHECK:STDOUT: store i32 %int.ssub_assign1, ptr %a, align 4, !dbg !10 +// CHECK:STDOUT: ret void, !dbg !11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestSMul.Main(ptr %a, i32 %b) !dbg !12 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.smul_assign = load i32, ptr %a, align 4, !dbg !13 +// CHECK:STDOUT: %int.smul_assign1 = mul i32 %int.smul_assign, %b, !dbg !13 +// CHECK:STDOUT: store i32 %int.smul_assign1, ptr %a, align 4, !dbg !13 +// CHECK:STDOUT: ret void, !dbg !14 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestSDiv.Main(ptr %a, i32 %b) !dbg !15 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.sdiv_assign = load i32, ptr %a, align 4, !dbg !16 +// CHECK:STDOUT: %int.sdiv_assign1 = sdiv i32 %int.sdiv_assign, %b, !dbg !16 +// CHECK:STDOUT: store i32 %int.sdiv_assign1, ptr %a, align 4, !dbg !16 +// CHECK:STDOUT: ret void, !dbg !17 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestSMod.Main(ptr %a, i32 %b) !dbg !18 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.smod_assign = load i32, ptr %a, align 4, !dbg !19 +// CHECK:STDOUT: %int.smod_assign1 = srem i32 %int.smod_assign, %b, !dbg !19 +// CHECK:STDOUT: store i32 %int.smod_assign1, ptr %a, align 4, !dbg !19 +// CHECK:STDOUT: ret void, !dbg !20 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestUAdd.Main(ptr %a, i32 %b) !dbg !21 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.uadd_assign = load i32, ptr %a, align 4, !dbg !22 +// CHECK:STDOUT: %int.uadd_assign1 = add i32 %int.uadd_assign, %b, !dbg !22 +// CHECK:STDOUT: store i32 %int.uadd_assign1, ptr %a, align 4, !dbg !22 +// CHECK:STDOUT: ret void, !dbg !23 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestUSub.Main(ptr %a, i32 %b) !dbg !24 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.usub_assign = load i32, ptr %a, align 4, !dbg !25 +// CHECK:STDOUT: %int.usub_assign1 = sub i32 %int.usub_assign, %b, !dbg !25 +// CHECK:STDOUT: store i32 %int.usub_assign1, ptr %a, align 4, !dbg !25 +// CHECK:STDOUT: ret void, !dbg !26 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestUMul.Main(ptr %a, i32 %b) !dbg !27 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.umul_assign = load i32, ptr %a, align 4, !dbg !28 +// CHECK:STDOUT: %int.umul_assign1 = mul i32 %int.umul_assign, %b, !dbg !28 +// CHECK:STDOUT: store i32 %int.umul_assign1, ptr %a, align 4, !dbg !28 +// CHECK:STDOUT: ret void, !dbg !29 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestUDiv.Main(ptr %a, i32 %b) !dbg !30 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.udiv_assign = load i32, ptr %a, align 4, !dbg !31 +// CHECK:STDOUT: %int.udiv_assign1 = udiv i32 %int.udiv_assign, %b, !dbg !31 +// CHECK:STDOUT: store i32 %int.udiv_assign1, ptr %a, align 4, !dbg !31 +// CHECK:STDOUT: ret void, !dbg !32 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestUMod.Main(ptr %a, i32 %b) !dbg !33 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.umod_assign = load i32, ptr %a, align 4, !dbg !34 +// CHECK:STDOUT: %int.umod_assign1 = urem i32 %int.umod_assign, %b, !dbg !34 +// CHECK:STDOUT: store i32 %int.umod_assign1, ptr %a, align 4, !dbg !34 +// CHECK:STDOUT: ret void, !dbg !35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestAnd.Main(ptr %a, i32 %b) !dbg !36 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.and_assign = load i32, ptr %a, align 4, !dbg !37 +// CHECK:STDOUT: %int.and_assign1 = and i32 %int.and_assign, %b, !dbg !37 +// CHECK:STDOUT: store i32 %int.and_assign1, ptr %a, align 4, !dbg !37 +// CHECK:STDOUT: ret void, !dbg !38 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestOr.Main(ptr %a, i32 %b) !dbg !39 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.or_assign = load i32, ptr %a, align 4, !dbg !40 +// CHECK:STDOUT: %int.or_assign1 = or i32 %int.or_assign, %b, !dbg !40 +// CHECK:STDOUT: store i32 %int.or_assign1, ptr %a, align 4, !dbg !40 +// CHECK:STDOUT: ret void, !dbg !41 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestXor.Main(ptr %a, i32 %b) !dbg !42 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.xor_assign = load i32, ptr %a, align 4, !dbg !43 +// CHECK:STDOUT: %int.xor_assign1 = xor i32 %int.xor_assign, %b, !dbg !43 +// CHECK:STDOUT: store i32 %int.xor_assign1, ptr %a, align 4, !dbg !43 +// CHECK:STDOUT: ret void, !dbg !44 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestLeftShift.Main(ptr %a, i32 %b) !dbg !45 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.left_shift_assign = load i32, ptr %a, align 4, !dbg !46 +// CHECK:STDOUT: %int.left_shift_assign1 = shl i32 %int.left_shift_assign, %b, !dbg !46 +// CHECK:STDOUT: store i32 %int.left_shift_assign1, ptr %a, align 4, !dbg !46 +// CHECK:STDOUT: ret void, !dbg !47 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestArithmeticRightShift.Main(ptr %a, i32 %b) !dbg !48 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.right_shift_assign = load i32, ptr %a, align 4, !dbg !49 +// CHECK:STDOUT: %int.right_shift_assign1 = ashr i32 %int.right_shift_assign, %b, !dbg !49 +// CHECK:STDOUT: store i32 %int.right_shift_assign1, ptr %a, align 4, !dbg !49 +// CHECK:STDOUT: ret void, !dbg !50 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CTestLogicalRightShift.Main(ptr %a, i32 %b) !dbg !51 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %int.right_shift_assign = load i32, ptr %a, align 4, !dbg !52 +// CHECK:STDOUT: %int.right_shift_assign1 = lshr i32 %int.right_shift_assign, %b, !dbg !52 +// CHECK:STDOUT: store i32 %int.right_shift_assign1, ptr %a, align 4, !dbg !52 +// CHECK:STDOUT: ret void, !dbg !53 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "compound_assign.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "TestSAdd", linkageName: "_CTestSAdd.Main", scope: null, file: !3, line: 5, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 5, column: 32, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 5, column: 1, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "TestSSub", linkageName: "_CTestSSub.Main", scope: null, file: !3, line: 8, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !10 = !DILocation(line: 8, column: 32, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 8, column: 1, scope: !9) +// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "TestSMul", linkageName: "_CTestSMul.Main", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 32, scope: !12) +// CHECK:STDOUT: !14 = !DILocation(line: 11, column: 1, scope: !12) +// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "TestSDiv", linkageName: "_CTestSDiv.Main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !16 = !DILocation(line: 14, column: 32, scope: !15) +// CHECK:STDOUT: !17 = !DILocation(line: 14, column: 1, scope: !15) +// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "TestSMod", linkageName: "_CTestSMod.Main", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !19 = !DILocation(line: 17, column: 32, scope: !18) +// CHECK:STDOUT: !20 = !DILocation(line: 17, column: 1, scope: !18) +// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "TestUAdd", linkageName: "_CTestUAdd.Main", scope: null, file: !3, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !22 = !DILocation(line: 20, column: 32, scope: !21) +// CHECK:STDOUT: !23 = !DILocation(line: 20, column: 1, scope: !21) +// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "TestUSub", linkageName: "_CTestUSub.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !25 = !DILocation(line: 23, column: 32, scope: !24) +// CHECK:STDOUT: !26 = !DILocation(line: 23, column: 1, scope: !24) +// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "TestUMul", linkageName: "_CTestUMul.Main", scope: null, file: !3, line: 26, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !28 = !DILocation(line: 26, column: 32, scope: !27) +// CHECK:STDOUT: !29 = !DILocation(line: 26, column: 1, scope: !27) +// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "TestUDiv", linkageName: "_CTestUDiv.Main", scope: null, file: !3, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !31 = !DILocation(line: 29, column: 32, scope: !30) +// CHECK:STDOUT: !32 = !DILocation(line: 29, column: 1, scope: !30) +// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "TestUMod", linkageName: "_CTestUMod.Main", scope: null, file: !3, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !34 = !DILocation(line: 32, column: 32, scope: !33) +// CHECK:STDOUT: !35 = !DILocation(line: 32, column: 1, scope: !33) +// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "TestAnd", linkageName: "_CTestAnd.Main", scope: null, file: !3, line: 35, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !37 = !DILocation(line: 35, column: 31, scope: !36) +// CHECK:STDOUT: !38 = !DILocation(line: 35, column: 1, scope: !36) +// CHECK:STDOUT: !39 = distinct !DISubprogram(name: "TestOr", linkageName: "_CTestOr.Main", scope: null, file: !3, line: 38, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !40 = !DILocation(line: 38, column: 30, scope: !39) +// CHECK:STDOUT: !41 = !DILocation(line: 38, column: 1, scope: !39) +// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "TestXor", linkageName: "_CTestXor.Main", scope: null, file: !3, line: 41, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !43 = !DILocation(line: 41, column: 31, scope: !42) +// CHECK:STDOUT: !44 = !DILocation(line: 41, column: 1, scope: !42) +// CHECK:STDOUT: !45 = distinct !DISubprogram(name: "TestLeftShift", linkageName: "_CTestLeftShift.Main", scope: null, file: !3, line: 44, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !46 = !DILocation(line: 44, column: 37, scope: !45) +// CHECK:STDOUT: !47 = !DILocation(line: 44, column: 1, scope: !45) +// CHECK:STDOUT: !48 = distinct !DISubprogram(name: "TestArithmeticRightShift", linkageName: "_CTestArithmeticRightShift.Main", scope: null, file: !3, line: 47, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !49 = !DILocation(line: 47, column: 48, scope: !48) +// CHECK:STDOUT: !50 = !DILocation(line: 47, column: 1, scope: !48) +// CHECK:STDOUT: !51 = distinct !DISubprogram(name: "TestLogicalRightShift", linkageName: "_CTestLogicalRightShift.Main", scope: null, file: !3, line: 50, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !52 = !DILocation(line: 50, column: 45, scope: !51) +// CHECK:STDOUT: !53 = !DILocation(line: 50, column: 1, scope: !51) // CHECK:STDOUT: ; ModuleID = 'mixed_shift.carbon' // CHECK:STDOUT: source_filename = "mixed_shift.carbon" // CHECK:STDOUT: diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index 47e5b1743fd9..5e1615766897 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -34,6 +34,9 @@ struct ValidateState { TypeId type_params[MaxTypeParams] = {TypeId::None, TypeId::None}; }; +template +auto Check(const File& sem_ir, ValidateState& state, TypeId type_id) -> bool; + // Constraint that a type is generic type parameter `I` of the builtin, // satisfying `TypeConstraint`. See ValidateSignature for details. template @@ -63,6 +66,20 @@ struct BuiltinType { } }; +// Constraint that a type is a pointer to another type. See ValidateSignature +// for details. +template +struct PointerTo { + static auto Check(const File& sem_ir, ValidateState& state, TypeId type_id) + -> bool { + if (!sem_ir.types().Is(type_id)) { + return false; + } + return SemIR::Check(sem_ir, state, + sem_ir.GetPointeeType(type_id)); + } +}; + // Constraint that a type is `()`, used as the return type of builtin functions // with no return value. struct NoReturn { @@ -219,6 +236,10 @@ using IntU = TypeParam<1, AnyInt>; // generic type parameter that is constrained to be a sized integer type. using SizedIntT = TypeParam<0, AnySizedInt>; +// Convenience name used in the builtin type signatures below for a second +// generic type parameter that is constrained to be a sized integer type. +using SizedIntU = TypeParam<1, AnySizedInt>; + // Convenience name used in the builtin type signatures below for a first // generic type parameter that is constrained to be an float type. using FloatT = TypeParam<0, AnyFloat>; @@ -337,10 +358,85 @@ constexpr BuiltinInfo IntXor = {"int.xor", constexpr BuiltinInfo IntLeftShift = { "int.left_shift", ValidateSignatureIntT>}; -// "int.left_shift": integer right shift. +// "int.right_shift": integer right shift. constexpr BuiltinInfo IntRightShift = { "int.right_shift", ValidateSignatureIntT>}; +// "int.sadd_assign": integer in-place addition. +constexpr BuiltinInfo IntSAddAssign = { + "int.sadd_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.ssub_assign": integer in-place subtraction. +constexpr BuiltinInfo IntSSubAssign = { + "int.ssub_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.smul_assign": integer in-place multiplication. +constexpr BuiltinInfo IntSMulAssign = { + "int.smul_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.sdiv_assign": integer in-place division. +constexpr BuiltinInfo IntSDivAssign = { + "int.sdiv_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.smod_assign": integer in-place modulo. +constexpr BuiltinInfo IntSModAssign = { + "int.smod_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.uadd_assign": unsigned integer in-place addition. +constexpr BuiltinInfo IntUAddAssign = { + "int.uadd_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.usub_assign": unsigned integer in-place subtraction. +constexpr BuiltinInfo IntUSubAssign = { + "int.usub_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.umul_assign": unsigned integer in-place multiplication. +constexpr BuiltinInfo IntUMulAssign = { + "int.umul_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.udiv_assign": unsigned integer in-place division. +constexpr BuiltinInfo IntUDivAssign = { + "int.udiv_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.mod_assign": integer in-place modulo. +constexpr BuiltinInfo IntUModAssign = { + "int.umod_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.and_assign": integer in-place bitwise and. +constexpr BuiltinInfo IntAndAssign = { + "int.and_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.or_assign": integer in-place bitwise or. +constexpr BuiltinInfo IntOrAssign = { + "int.or_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.xor_assign": integer in-place bitwise xor. +constexpr BuiltinInfo IntXorAssign = { + "int.xor_assign", + ValidateSignature, SizedIntT)->NoReturn>}; + +// "int.left_shift_assign": integer in-place left shift. +constexpr BuiltinInfo IntLeftShiftAssign = { + "int.left_shift_assign", + ValidateSignature, SizedIntU)->NoReturn>}; + +// "int.right_shift_assign": integer in-place right shift. +constexpr BuiltinInfo IntRightShiftAssign = { + "int.right_shift_assign", + ValidateSignature, SizedIntU)->NoReturn>}; + // "int.eq": integer equality comparison. constexpr BuiltinInfo IntEq = {"int.eq", ValidateSignatureBool>}; diff --git a/toolchain/sem_ir/builtin_function_kind.def b/toolchain/sem_ir/builtin_function_kind.def index 420d062b112c..db703bae56d1 100644 --- a/toolchain/sem_ir/builtin_function_kind.def +++ b/toolchain/sem_ir/builtin_function_kind.def @@ -68,6 +68,23 @@ CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntLessEq) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntGreater) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntGreaterEq) +// Integer compound assignment. +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntSAddAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntSSubAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntSMulAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntSDivAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntSModAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntUAddAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntUSubAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntUMulAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntUDivAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntUModAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntAndAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntOrAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntXorAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntLeftShiftAssign) +CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntRightShiftAssign) + // Float arithmetic. CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatNegate) CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatAdd)