From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_target/src/abi/call/aarch64.rs | 8 +++++++ compiler/rustc_target/src/abi/call/arm.rs | 8 +++++++ compiler/rustc_target/src/abi/call/csky.rs | 8 +++++++ compiler/rustc_target/src/abi/call/loongarch.rs | 8 +++++++ compiler/rustc_target/src/abi/call/m68k.rs | 4 ++++ compiler/rustc_target/src/abi/call/mips.rs | 4 ++++ compiler/rustc_target/src/abi/call/mod.rs | 32 ++++++++++++++++++------- compiler/rustc_target/src/abi/call/nvptx64.rs | 9 +++++++ compiler/rustc_target/src/abi/call/powerpc64.rs | 8 +++++++ compiler/rustc_target/src/abi/call/riscv.rs | 8 +++++++ compiler/rustc_target/src/abi/call/s390x.rs | 4 ++++ compiler/rustc_target/src/abi/call/sparc.rs | 4 ++++ compiler/rustc_target/src/abi/call/wasm.rs | 24 +++++++++++++++---- compiler/rustc_target/src/abi/call/x86.rs | 4 ++-- compiler/rustc_target/src/abi/call/x86_64.rs | 14 ++++++----- compiler/rustc_target/src/abi/call/x86_win64.rs | 4 ++-- 16 files changed, 129 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_target/src/abi/call') diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs index b4c7b0f12..f99f6a3b7 100644 --- a/compiler/rustc_target/src/abi/call/aarch64.rs +++ b/compiler/rustc_target/src/abi/call/aarch64.rs @@ -40,6 +40,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !ret.layout.is_sized() { + // Not touching this... + return; + } if !ret.layout.is_aggregate() { if kind == AbiKind::DarwinPCS { // On Darwin, when returning an i8/i16, it must be sign-extended to 32 bits, @@ -67,6 +71,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !arg.layout.is_aggregate() { if kind == AbiKind::DarwinPCS { // On Darwin, when passing an i8/i16, it must be sign-extended to 32 bits, diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs index 1923ea588..95f6691d4 100644 --- a/compiler/rustc_target/src/abi/call/arm.rs +++ b/compiler/rustc_target/src/abi/call/arm.rs @@ -30,6 +30,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !ret.layout.is_sized() { + // Not touching this... + return; + } if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; @@ -56,6 +60,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs index 706493b0a..8b4328db5 100644 --- a/compiler/rustc_target/src/abi/call/csky.rs +++ b/compiler/rustc_target/src/abi/call/csky.rs @@ -7,6 +7,10 @@ use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform}; fn classify_ret(arg: &mut ArgAbi<'_, Ty>) { + if !arg.layout.is_sized() { + // Not touching this... + return; + } // For return type, aggregate which <= 2*XLen will be returned in registers. // Otherwise, aggregate will be returned indirectly. if arg.layout.is_aggregate() { @@ -24,6 +28,10 @@ fn classify_ret(arg: &mut ArgAbi<'_, Ty>) { } fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { + if !arg.layout.is_sized() { + // Not touching this... + return; + } // For argument type, the first 4*XLen parts of aggregate will be passed // in registers, and the rest will be passed in stack. // So we can coerce to integers directly and let backend handle it correctly. diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs index e649d58bb..647b6500c 100644 --- a/compiler/rustc_target/src/abi/call/loongarch.rs +++ b/compiler/rustc_target/src/abi/call/loongarch.rs @@ -152,6 +152,10 @@ fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u6 where Ty: TyAbiInterface<'a, C> + Copy, { + if !arg.layout.is_sized() { + // Not touching this... + return false; // I guess? return value of this function is not documented + } if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) { match conv { FloatConv::Float(f) => { @@ -214,6 +218,10 @@ fn classify_arg<'a, Ty, C>( ) where Ty: TyAbiInterface<'a, C> + Copy, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !is_vararg { match should_use_fp_conv(cx, &arg.layout, xlen, flen) { Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { diff --git a/compiler/rustc_target/src/abi/call/m68k.rs b/compiler/rustc_target/src/abi/call/m68k.rs index 1d4649ed8..06697bdd8 100644 --- a/compiler/rustc_target/src/abi/call/m68k.rs +++ b/compiler/rustc_target/src/abi/call/m68k.rs @@ -9,6 +9,10 @@ fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { } fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if arg.layout.is_aggregate() { arg.make_indirect_byval(None); } else { diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs index edcd1bab8..57ccfe215 100644 --- a/compiler/rustc_target/src/abi/call/mips.rs +++ b/compiler/rustc_target/src/abi/call/mips.rs @@ -17,6 +17,10 @@ fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) where C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } let dl = cx.data_layout(); let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5efd171b9..e97309473 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -382,6 +382,7 @@ impl HomogeneousAggregate { } impl<'a, Ty> TyAndLayout<'a, Ty> { + /// Returns `true` if this is an aggregate type (including a ScalarPair!) fn is_aggregate(&self) -> bool { match self.abi { Abi::Uninhabited | Abi::Scalar(_) | Abi::Vector { .. } => false, @@ -422,7 +423,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { })) } - Abi::ScalarPair(..) | Abi::Aggregate { .. } => { + Abi::ScalarPair(..) | Abi::Aggregate { sized: true } => { // Helper for computing `homogeneous_aggregate`, allowing a custom // starting offset (used below for handling variants). let from_fields_at = @@ -520,6 +521,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ok(result) } } + Abi::Aggregate { sized: false } => Err(Heterogeneous), } } } @@ -555,8 +557,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs(&layout, b, a.size(cx).align_to(b.align(cx).abi)), ), Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), - // The `Aggregate` ABI should always be adjusted later. - Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()), + Abi::Aggregate { .. } => Self::indirect_pass_mode(&layout), }; ArgAbi { layout, mode } } @@ -580,14 +581,30 @@ impl<'a, Ty> ArgAbi<'a, Ty> { PassMode::Indirect { attrs, meta_attrs, on_stack: false } } + /// Pass this argument directly instead. Should NOT be used! + /// Only exists because of past ABI mistakes that will take time to fix + /// (see ). + pub fn make_direct_deprecated(&mut self) { + match self.mode { + PassMode::Indirect { .. } => { + self.mode = PassMode::Direct(ArgAttributes::new()); + } + PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => return, // already direct + _ => panic!("Tried to make {:?} direct", self.mode), + } + } + pub fn make_indirect(&mut self) { match self.mode { - PassMode::Direct(_) | PassMode::Pair(_, _) => {} - PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: false } => return, + PassMode::Direct(_) | PassMode::Pair(_, _) => { + self.mode = Self::indirect_pass_mode(&self.layout); + } + PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => { + // already indirect + return; + } _ => panic!("Tried to make {:?} indirect", self.mode), } - - self.mode = Self::indirect_pass_mode(&self.layout); } pub fn make_indirect_byval(&mut self, byval_align: Option) { @@ -836,7 +853,6 @@ impl<'a, Ty> FnAbi<'a, Ty> { wasm::compute_c_abi_info(cx, self) } } - "asmjs" => wasm::compute_c_abi_info(cx, self), "bpf" => bpf::compute_abi_info(self), arch => { return Err(AdjustForForeignAbiError::Unsupported { diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index 4abe51cd6..5c040ce9c 100644 --- a/compiler/rustc_target/src/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs @@ -4,12 +4,18 @@ use crate::abi::{HasDataLayout, TyAbiInterface}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); + } else { + // FIXME: this is wrong! Need to decide which ABI we really want here. + ret.make_direct_deprecated(); } } fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); + } else { + // FIXME: this is wrong! Need to decide which ABI we really want here. + arg.make_direct_deprecated(); } } @@ -30,6 +36,9 @@ where _ => unreachable!("Align is given as power of 2 no larger than 16 bytes"), }; arg.cast_to(Uniform { unit, total: Size::from_bytes(2 * align_bytes) }); + } else { + // FIXME: find a better way to do this. See https://github.com/rust-lang/rust/issues/117271. + arg.make_direct_deprecated(); } } diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs index 359bb8fc0..2d41f77e5 100644 --- a/compiler/rustc_target/src/abi/call/powerpc64.rs +++ b/compiler/rustc_target/src/abi/call/powerpc64.rs @@ -46,6 +46,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !ret.layout.is_sized() { + // Not touching this... + return; + } if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); return; @@ -89,6 +93,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs index 93a204563..cbde234d3 100644 --- a/compiler/rustc_target/src/abi/call/riscv.rs +++ b/compiler/rustc_target/src/abi/call/riscv.rs @@ -158,6 +158,10 @@ fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u6 where Ty: TyAbiInterface<'a, C> + Copy, { + if !arg.layout.is_sized() { + // Not touching this... + return false; // I guess? return value of this function is not documented + } if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) { match conv { FloatConv::Float(f) => { @@ -220,6 +224,10 @@ fn classify_arg<'a, Ty, C>( ) where Ty: TyAbiInterface<'a, C> + Copy, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !is_vararg { match should_use_fp_conv(cx, &arg.layout, xlen, flen) { Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs index ea2369281..1a2191082 100644 --- a/compiler/rustc_target/src/abi/call/s390x.rs +++ b/compiler/rustc_target/src/abi/call/s390x.rs @@ -17,6 +17,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 { arg.extend_integer_width_to(64); return; diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs index edcd1bab8..57ccfe215 100644 --- a/compiler/rustc_target/src/abi/call/sparc.rs +++ b/compiler/rustc_target/src/abi/call/sparc.rs @@ -17,6 +17,10 @@ fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) where C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } let dl = cx.data_layout(); let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs index 796b752ff..a7a2b314a 100644 --- a/compiler/rustc_target/src/abi/call/wasm.rs +++ b/compiler/rustc_target/src/abi/call/wasm.rs @@ -34,6 +34,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + if !arg.layout.is_sized() { + // Not touching this... + return; + } arg.extend_integer_width_to(32); if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { arg.make_indirect_byval(None); @@ -67,21 +71,33 @@ where /// Also see . pub fn compute_wasm_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if !fn_abi.ret.is_ignore() { - classify_ret(&mut fn_abi.ret); + classify_ret_wasm_abi(&mut fn_abi.ret); } for arg in fn_abi.args.iter_mut() { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg_wasm_abi(arg); } - fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { + fn classify_ret_wasm_abi(ret: &mut ArgAbi<'_, Ty>) { + if !ret.layout.is_sized() { + // Not touching this... + return; + } + // FIXME: this is bad! https://github.com/rust-lang/rust/issues/115666 + ret.make_direct_deprecated(); ret.extend_integer_width_to(32); } - fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { + fn classify_arg_wasm_abi(arg: &mut ArgAbi<'_, Ty>) { + if !arg.layout.is_sized() { + // Not touching this... + return; + } + // FIXME: this is bad! https://github.com/rust-lang/rust/issues/115666 + arg.make_direct_deprecated(); arg.extend_integer_width_to(32); } } diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index c27f1e6dd..e9aedc3d2 100644 --- a/compiler/rustc_target/src/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs @@ -14,7 +14,7 @@ where C: HasDataLayout + HasTargetSpec, { if !fn_abi.ret.is_ignore() { - if fn_abi.ret.layout.is_aggregate() { + if fn_abi.ret.layout.is_aggregate() && fn_abi.ret.layout.is_sized() { // Returning a structure. Most often, this will use // a hidden first argument. On some platforms, though, // small structs are returned as integers. @@ -50,7 +50,7 @@ where } for arg in fn_abi.args.iter_mut() { - if arg.is_ignore() { + if arg.is_ignore() || !arg.layout.is_sized() { continue; } diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index d1efe9776..6c34585a1 100644 --- a/compiler/rustc_target/src/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs @@ -153,9 +153,9 @@ fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option], size: Size) -> Option { +fn cast_target(cls: &[Option], size: Size) -> CastTarget { let mut i = 0; - let lo = reg_component(cls, &mut i, size)?; + let lo = reg_component(cls, &mut i, size).unwrap(); let offset = Size::from_bytes(8) * (i as u64); let mut target = CastTarget::from(lo); if size > offset { @@ -164,7 +164,7 @@ fn cast_target(cls: &[Option], size: Size) -> Option { } } assert_eq!(reg_component(cls, &mut i, Size::ZERO), None); - Some(target) + target } const MAX_INT_REGS: usize = 6; // RDI, RSI, RDX, RCX, R8, R9 @@ -179,6 +179,10 @@ where let mut sse_regs = MAX_SSE_REGS; let mut x86_64_arg_or_ret = |arg: &mut ArgAbi<'a, Ty>, is_arg: bool| { + if !arg.layout.is_sized() { + // Not touching this... + return; + } let mut cls_or_mem = classify_arg(cx, arg); if is_arg { @@ -227,9 +231,7 @@ where // split into sized chunks passed individually if arg.layout.is_aggregate() { let size = arg.layout.size; - if let Some(cast_target) = cast_target(cls, size) { - arg.cast_to(cast_target); - } + arg.cast_to(cast_target(cls, size)); } else { arg.extend_integer_width_to(32); } diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs index 1aaf0e511..90de1a42b 100644 --- a/compiler/rustc_target/src/abi/call/x86_win64.rs +++ b/compiler/rustc_target/src/abi/call/x86_win64.rs @@ -6,8 +6,8 @@ use crate::abi::Abi; pub fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { let fixup = |a: &mut ArgAbi<'_, Ty>| { match a.layout.abi { - Abi::Uninhabited => {} - Abi::ScalarPair(..) | Abi::Aggregate { .. } => match a.layout.size.bits() { + Abi::Uninhabited | Abi::Aggregate { sized: false } => {} + Abi::ScalarPair(..) | Abi::Aggregate { sized: true } => match a.layout.size.bits() { 8 => a.cast_to(Reg::i8()), 16 => a.cast_to(Reg::i16()), 32 => a.cast_to(Reg::i32()), -- cgit v1.2.3