mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add builtins for compound assignment operators. (#5335)
Provide builtins for compound assignments instead of defining them in the prelude as a use of a binary operator and an assignment. This allows us to lower compound assignment directly to LLVM operations instead of producing a function call. In the short term this also allows us to define a type-generic compound assignment in the prelude.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<SemIR::TypeId> 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<const SemIR::InstId>(
|
||||
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());
|
||||
|
||||
+11
-11
@@ -56,7 +56,7 @@ let c: array(i32, ConvertToU32(3))* = &a;
|
||||
// CHECK:STDOUT: %bound_method.c6f: <bound method> = 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> = 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:
|
||||
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
+1
-1
@@ -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 <unexpected>.inst1161: %ptr.6cf]() [from "a.carbon"];
|
||||
// CHECK:STDOUT: fn @G[addr <unexpected>.inst1395: %ptr.6cf]() [from "a.carbon"];
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+10
-10
@@ -30,7 +30,7 @@ fn F(N:! i32, a: array(i32, N)*);
|
||||
// CHECK:STDOUT: %bound_method: <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> = 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:
|
||||
|
||||
+20
-20
@@ -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
|
||||
|
||||
@@ -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, <unexpected>.inst1083.loc27_14
|
||||
// CHECK:STDOUT: %x: %i32 = bind_name x, <unexpected>.inst1317.loc27_14
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %y.patt: %i32 = binding_pattern y
|
||||
// CHECK:STDOUT: %.loc37: %i32 = var_pattern %y.patt
|
||||
|
||||
+4
-4
@@ -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: <witness> = 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> = 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: <witness> = 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> = bound_method %int_4, %Op.553 [concrete]
|
||||
// CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %struct> [concrete]
|
||||
|
||||
@@ -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: <witness> = 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> = bound_method %int_10, %Op.bba [concrete]
|
||||
// CHECK:STDOUT: %int_-10.06d: Core.IntLiteral = int_value -10 [concrete]
|
||||
|
||||
@@ -895,7 +895,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <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: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// 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:
|
||||
|
||||
@@ -33,7 +33,7 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <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
|
||||
|
||||
+10
-10
@@ -35,7 +35,7 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <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
|
||||
|
||||
+18
-18
@@ -39,7 +39,7 @@ var a: i32* = a_ref;
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <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> = 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 <none>
|
||||
// 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: }
|
||||
|
||||
+3
-3
@@ -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: <witness> = 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: <witness> = 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: <witness> = 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 {
|
||||
|
||||
@@ -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: <witness> = 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> = bound_method %int_10, %Op.bba [concrete]
|
||||
// CHECK:STDOUT: %int_-10: Core.IntLiteral = int_value -10 [concrete]
|
||||
|
||||
+3
-3
@@ -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: <witness> = 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: <witness> = 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: <witness> = 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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
+152
-106
@@ -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<SemIR::Call>(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<llvm::Value*> 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));
|
||||
|
||||
+240
@@ -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:
|
||||
|
||||
@@ -34,6 +34,9 @@ struct ValidateState {
|
||||
TypeId type_params[MaxTypeParams] = {TypeId::None, TypeId::None};
|
||||
};
|
||||
|
||||
template <typename TypeConstraint>
|
||||
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 <int I, typename TypeConstraint>
|
||||
@@ -63,6 +66,20 @@ struct BuiltinType {
|
||||
}
|
||||
};
|
||||
|
||||
// Constraint that a type is a pointer to another type. See ValidateSignature
|
||||
// for details.
|
||||
template <typename PointeeT>
|
||||
struct PointerTo {
|
||||
static auto Check(const File& sem_ir, ValidateState& state, TypeId type_id)
|
||||
-> bool {
|
||||
if (!sem_ir.types().Is<SemIR::PointerType>(type_id)) {
|
||||
return false;
|
||||
}
|
||||
return SemIR::Check<PointeeT>(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", ValidateSignature<auto(IntT, IntU)->IntT>};
|
||||
|
||||
// "int.left_shift": integer right shift.
|
||||
// "int.right_shift": integer right shift.
|
||||
constexpr BuiltinInfo IntRightShift = {
|
||||
"int.right_shift", ValidateSignature<auto(IntT, IntU)->IntT>};
|
||||
|
||||
// "int.sadd_assign": integer in-place addition.
|
||||
constexpr BuiltinInfo IntSAddAssign = {
|
||||
"int.sadd_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.ssub_assign": integer in-place subtraction.
|
||||
constexpr BuiltinInfo IntSSubAssign = {
|
||||
"int.ssub_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.smul_assign": integer in-place multiplication.
|
||||
constexpr BuiltinInfo IntSMulAssign = {
|
||||
"int.smul_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.sdiv_assign": integer in-place division.
|
||||
constexpr BuiltinInfo IntSDivAssign = {
|
||||
"int.sdiv_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.smod_assign": integer in-place modulo.
|
||||
constexpr BuiltinInfo IntSModAssign = {
|
||||
"int.smod_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.uadd_assign": unsigned integer in-place addition.
|
||||
constexpr BuiltinInfo IntUAddAssign = {
|
||||
"int.uadd_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.usub_assign": unsigned integer in-place subtraction.
|
||||
constexpr BuiltinInfo IntUSubAssign = {
|
||||
"int.usub_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.umul_assign": unsigned integer in-place multiplication.
|
||||
constexpr BuiltinInfo IntUMulAssign = {
|
||||
"int.umul_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.udiv_assign": unsigned integer in-place division.
|
||||
constexpr BuiltinInfo IntUDivAssign = {
|
||||
"int.udiv_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.mod_assign": integer in-place modulo.
|
||||
constexpr BuiltinInfo IntUModAssign = {
|
||||
"int.umod_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.and_assign": integer in-place bitwise and.
|
||||
constexpr BuiltinInfo IntAndAssign = {
|
||||
"int.and_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.or_assign": integer in-place bitwise or.
|
||||
constexpr BuiltinInfo IntOrAssign = {
|
||||
"int.or_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.xor_assign": integer in-place bitwise xor.
|
||||
constexpr BuiltinInfo IntXorAssign = {
|
||||
"int.xor_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntT)->NoReturn>};
|
||||
|
||||
// "int.left_shift_assign": integer in-place left shift.
|
||||
constexpr BuiltinInfo IntLeftShiftAssign = {
|
||||
"int.left_shift_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntU)->NoReturn>};
|
||||
|
||||
// "int.right_shift_assign": integer in-place right shift.
|
||||
constexpr BuiltinInfo IntRightShiftAssign = {
|
||||
"int.right_shift_assign",
|
||||
ValidateSignature<auto(PointerTo<SizedIntT>, SizedIntU)->NoReturn>};
|
||||
|
||||
// "int.eq": integer equality comparison.
|
||||
constexpr BuiltinInfo IntEq = {"int.eq",
|
||||
ValidateSignature<auto(IntT, IntU)->Bool>};
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user