From c8507ac9ccc7f412ea38817014edc88cf0587a81 Mon Sep 17 00:00:00 2001 From: Goldstein Date: Thu, 25 Apr 2024 17:08:45 +0300 Subject: [PATCH 1/2] make Rust ABI return types up to two pointers in registers --- compiler/rustc_ty_utils/src/abi.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f0cea1f0baf38..d154ca86ac77c 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -9,7 +9,7 @@ use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_target::abi::call::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, - RiscvInterruptKind, + RiscvInterruptKind, Uniform, }; use rustc_target::abi::*; use rustc_target::spec::abi::Abi as SpecAbi; @@ -779,11 +779,23 @@ fn fn_abi_adjust_for_abi<'tcx>( assert!(is_indirect_not_on_stack, "{:?}", arg); let size = arg.layout.size; - if !arg.layout.is_unsized() && size <= Pointer(AddressSpace::DATA).size(cx) { - // We want to pass small aggregates as immediates, but using - // an LLVM aggregate type for this leads to bad optimizations, - // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { kind: RegKind::Integer, size }); + if !arg.layout.is_unsized() { + let data_pointer_size = Pointer(AddressSpace::DATA).size(cx); + if size <= data_pointer_size { + // We want to pass small aggregates as immediates, but using + // an LLVM aggregate type for this leads to bad optimizations, + // so we pick an appropriately sized integer type instead. + arg.cast_to(Reg { kind: RegKind::Integer, size }); + } else if size <= data_pointer_size * 2 && size.bytes() % 2 == 0 { + // Aggregates like `[usize; 2]` or (on 64-bit arch) `[u128; 1]` + // can be passed as a scalar pair. + let part_size = Size::from_bytes(size.bytes() / 2); + arg.cast_to(Uniform { + unit: Reg { kind: RegKind::Integer, size: part_size }, + total: size, + is_consecutive: false, + }); + } } // If we deduced that this parameter was read-only, add that to the attribute list now. From e10dae3ee896c100ec27361cc557f561a659ec5b Mon Sep 17 00:00:00 2001 From: Goldstein Date: Thu, 25 Apr 2024 17:39:01 +0300 Subject: [PATCH 2/2] weird --- compiler/rustc_ty_utils/src/abi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d154ca86ac77c..ed17be7f03a63 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -786,7 +786,7 @@ fn fn_abi_adjust_for_abi<'tcx>( // an LLVM aggregate type for this leads to bad optimizations, // so we pick an appropriately sized integer type instead. arg.cast_to(Reg { kind: RegKind::Integer, size }); - } else if size <= data_pointer_size * 2 && size.bytes() % 2 == 0 { + } else if size == data_pointer_size * 2 && size.bytes() % 2 == 0 { // Aggregates like `[usize; 2]` or (on 64-bit arch) `[u128; 1]` // can be passed as a scalar pair. let part_size = Size::from_bytes(size.bytes() / 2);