Skip to content

Commit ddafbc9

Browse files
authored
Use direct passing for 32- and 64-bit unsigned integers. (#5980)
Previously we only avoided creating a thunk for signed integers. But the same logic also applies to the unsigned 32-bit and 64-bit types.
1 parent 74016d4 commit ddafbc9

File tree

4 files changed

+162
-123
lines changed

4 files changed

+162
-123
lines changed

toolchain/check/cpp_thunk.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ static auto IsThunkRequiredForType(Context& context, SemIR::TypeId type_id)
5353
return true;
5454
}
5555

56-
if (!context.types().IsSignedInt(type_id)) {
56+
auto int_info = context.types().TryGetIntTypeInfo(type_id);
57+
if (!int_info || !int_info->bit_width.has_value()) {
5758
return true;
5859
}
5960

60-
llvm::APInt bit_width =
61-
context.ints().Get(context.types().GetIntTypeInfo(type_id).bit_width);
61+
llvm::APInt bit_width = context.ints().Get(int_info->bit_width);
6262
return bit_width != 32 && bit_width != 64;
6363
}
6464

toolchain/check/import_cpp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ static auto MapBuiltinType(Context& context, SemIR::LocId loc_id,
10621062
MakeIntType(context, context.ints().Add(width), is_signed);
10631063
// Try to make sure signed integer of 32 or 64 bits are complete so we can
10641064
// check against them when deciding whether we need to generate a thunk.
1065-
if (is_signed && (width == 32 || width == 64)) {
1065+
if (width == 32 || width == 64) {
10661066
SemIR::TypeId type_id = type_expr.type_id;
10671067
if (!context.types().IsComplete(type_id)) {
10681068
TryToCompleteType(context, type_id, loc_id);

toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -470,52 +470,6 @@ fn F() {
470470
//@dump-sem-ir-end
471471
}
472472

473-
// ============================================================================
474-
// unsigned int param
475-
// ============================================================================
476-
477-
// --- unsigned_int_param.h
478-
479-
auto foo(unsigned int a) -> void;
480-
481-
// --- import_unsigned_int_param.carbon
482-
483-
library "[[@TEST_NAME]]";
484-
485-
import Cpp library "unsigned_int_param.h";
486-
487-
fn F() {
488-
//@dump-sem-ir-begin
489-
Cpp.foo(1);
490-
//@dump-sem-ir-end
491-
}
492-
493-
// --- fail_import_unsigned_int_param_overflow.carbon
494-
495-
library "[[@TEST_NAME]]";
496-
497-
import Cpp library "unsigned_int_param.h";
498-
499-
fn F() {
500-
Cpp.foo(0);
501-
502-
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+5]]:11: error: negative integer value -1 converted to unsigned type `u32` [NegativeIntInUnsignedType]
503-
// CHECK:STDERR: Cpp.foo(-1);
504-
// CHECK:STDERR: ^~
505-
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon: note: initializing function parameter [InCallToFunctionParam]
506-
// CHECK:STDERR:
507-
Cpp.foo(-1);
508-
509-
Cpp.foo(0x0_FFFF_FFFF);
510-
511-
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon:[[@LINE+5]]:11: error: integer value 4294967296 too large for type `u32` [IntTooLargeForType]
512-
// CHECK:STDERR: Cpp.foo(0x1_0000_0000);
513-
// CHECK:STDERR: ^~~~~~~~~~~~~
514-
// CHECK:STDERR: fail_import_unsigned_int_param_overflow.carbon: note: initializing function parameter [InCallToFunctionParam]
515-
// CHECK:STDERR:
516-
Cpp.foo(0x1_0000_0000);
517-
}
518-
519473
// ============================================================================
520474
// _BitInt(24) param
521475
// ============================================================================
@@ -1766,79 +1720,6 @@ fn F() {
17661720
// CHECK:STDOUT: <elided>
17671721
// CHECK:STDOUT: }
17681722
// CHECK:STDOUT:
1769-
// CHECK:STDOUT: --- import_unsigned_int_param.carbon
1770-
// CHECK:STDOUT:
1771-
// CHECK:STDOUT: constants {
1772-
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
1773-
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
1774-
// CHECK:STDOUT: %u32: type = class_type @UInt, @UInt(%int_32) [concrete]
1775-
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
1776-
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
1777-
// CHECK:STDOUT: %ptr.6fd: type = ptr_type %u32 [concrete]
1778-
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
1779-
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
1780-
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
1781-
// CHECK:STDOUT: %ImplicitAs.type.9b4: type = facet_type <@ImplicitAs, @ImplicitAs(%u32)> [concrete]
1782-
// CHECK:STDOUT: %ImplicitAs.Convert.type.92a: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%u32) [concrete]
1783-
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
1784-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.30e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
1785-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.d1a: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.30e = struct_value () [symbolic]
1786-
// CHECK:STDOUT: %ImplicitAs.impl_witness.ac5: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.bb8, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
1787-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.feb: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
1788-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.319: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.feb = struct_value () [concrete]
1789-
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.9b4 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.ac5) [concrete]
1790-
// CHECK:STDOUT: %.bd1: type = fn_type_with_self_type %ImplicitAs.Convert.type.92a, %ImplicitAs.facet [concrete]
1791-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.319 [concrete]
1792-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.319, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
1793-
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
1794-
// CHECK:STDOUT: %int_1.c1d: %u32 = int_value 1 [concrete]
1795-
// CHECK:STDOUT: %UInt.as.Destroy.impl.Op.type.308: type = fn_type @UInt.as.Destroy.impl.Op, @UInt.as.Destroy.impl(%int_32) [concrete]
1796-
// CHECK:STDOUT: %UInt.as.Destroy.impl.Op.e70: %UInt.as.Destroy.impl.Op.type.308 = struct_value () [concrete]
1797-
// CHECK:STDOUT: }
1798-
// CHECK:STDOUT:
1799-
// CHECK:STDOUT: imports {
1800-
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
1801-
// CHECK:STDOUT: .foo = %foo.decl
1802-
// CHECK:STDOUT: import Cpp//...
1803-
// CHECK:STDOUT: }
1804-
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
1805-
// CHECK:STDOUT: <elided>
1806-
// CHECK:STDOUT: } {
1807-
// CHECK:STDOUT: <elided>
1808-
// CHECK:STDOUT: }
1809-
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
1810-
// CHECK:STDOUT: <elided>
1811-
// CHECK:STDOUT: } {
1812-
// CHECK:STDOUT: <elided>
1813-
// CHECK:STDOUT: }
1814-
// CHECK:STDOUT: %Core.import_ref.c3d: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.30e) = import_ref Core//prelude/parts/uint, loc16_40, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.d1a)]
1815-
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.bb8 = impl_witness_table (%Core.import_ref.c3d), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
1816-
// CHECK:STDOUT: }
1817-
// CHECK:STDOUT:
1818-
// CHECK:STDOUT: fn @F() {
1819-
// CHECK:STDOUT: !entry:
1820-
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
1821-
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
1822-
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
1823-
// CHECK:STDOUT: %impl.elem0: %.bd1 = impl_witness_access constants.%ImplicitAs.impl_witness.ac5, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.319]
1824-
// CHECK:STDOUT: %bound_method.loc8_11.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
1825-
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
1826-
// CHECK:STDOUT: %bound_method.loc8_11.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
1827-
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %u32 = call %bound_method.loc8_11.2(%int_1) [concrete = constants.%int_1.c1d]
1828-
// CHECK:STDOUT: %.loc8_11.1: %u32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.c1d]
1829-
// CHECK:STDOUT: %.loc8_11.2: %u32 = converted %int_1, %.loc8_11.1 [concrete = constants.%int_1.c1d]
1830-
// CHECK:STDOUT: %.loc8_11.3: ref %u32 = temporary_storage
1831-
// CHECK:STDOUT: %.loc8_11.4: ref %u32 = temporary %.loc8_11.3, %.loc8_11.2
1832-
// CHECK:STDOUT: %addr.loc8_12: %ptr.6fd = addr_of %.loc8_11.4
1833-
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_12)
1834-
// CHECK:STDOUT: %UInt.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_11.3, constants.%UInt.as.Destroy.impl.Op.e70
1835-
// CHECK:STDOUT: <elided>
1836-
// CHECK:STDOUT: %bound_method.loc8_11.3: <bound method> = bound_method %.loc8_11.3, %UInt.as.Destroy.impl.Op.specific_fn
1837-
// CHECK:STDOUT: %addr.loc8_11: %ptr.6fd = addr_of %.loc8_11.3
1838-
// CHECK:STDOUT: %UInt.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8_11.3(%addr.loc8_11)
1839-
// CHECK:STDOUT: <elided>
1840-
// CHECK:STDOUT: }
1841-
// CHECK:STDOUT:
18421723
// CHECK:STDOUT: --- fail_todo_import_bit_int_24_param.carbon
18431724
// CHECK:STDOUT:
18441725
// CHECK:STDOUT: constants {

0 commit comments

Comments
 (0)