From 4d2766e3524129f0d7ec6ad34c4045150ad4f978 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 25 Jan 2021 18:48:49 +0100 Subject: [PATCH 1/7] Fix abi for wasm-bindgen --- compiler/rustc_middle/src/ty/layout.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index ef467ed6514..a6b7b393213 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2752,6 +2752,14 @@ where attrs }); + if target.arch == "wasm32" && target.os == "unknown" { + // wasm-bindgen depends on ABI details and is incompatible with the + // correct C ABI, so this is being kept around until wasm-bindgen + // can be fixed to work with the correct ABI. See #63649 for further + // discussion. + arg.mode = PassMode::Direct(ArgAttributes::new()); + } + if arg.layout.is_zst() { // For some forsaken reason, x86_64-pc-windows-gnu // doesn't ignore zero-sized struct arguments. From e7a056fe20f7ec5a475923ff2f4eda8ca9e1a74b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 25 Jan 2021 21:28:29 +0100 Subject: [PATCH 2/7] Share wasm-bindgen compat abi selection code --- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index a6b7b393213..2bec761b0e5 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2752,7 +2752,7 @@ where attrs }); - if target.arch == "wasm32" && target.os == "unknown" { + if call::use_wasm_bindgen_compat_abi(target) { // wasm-bindgen depends on ABI details and is incompatible with the // correct C ABI, so this is being kept around until wasm-bindgen // can be fixed to work with the correct ABI. See #63649 for further diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 2cbd52bf3e9..521aea6dd72 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -1,6 +1,6 @@ use crate::abi::{self, Abi, Align, FieldsShape, Size}; use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; -use crate::spec::{self, HasTargetSpec}; +use crate::spec::{self, HasTargetSpec, Target}; mod aarch64; mod amdgpu; @@ -631,9 +631,10 @@ impl<'a, Ty> FnAbi<'a, Ty> { "nvptx64" => nvptx64::compute_abi_info(self), "hexagon" => hexagon::compute_abi_info(self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), - "wasm32" => match cx.target_spec().os.as_str() { - "emscripten" | "wasi" => wasm32::compute_abi_info(cx, self), - _ => wasm32_bindgen_compat::compute_abi_info(self), + "wasm32" => if use_wasm_bindgen_compat_abi(cx.target_spec()) { + wasm32_bindgen_compat::compute_abi_info(self) + } else { + wasm32::compute_abi_info(cx, self) }, "asmjs" => wasm32::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), @@ -642,3 +643,14 @@ impl<'a, Ty> FnAbi<'a, Ty> { Ok(()) } } + +pub fn use_wasm_bindgen_compat_abi(target_spec: &Target) -> bool { + if target_spec.arch.as_str() == "wasm32" { + match target_spec.os.as_str() { + "emscripten" | "wasi" => false, + _ => true, + } + } else { + false + } +} From 36df9c55e595c33c27095e0b2a4822adfa2da0c6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 26 Jan 2021 11:09:06 +0100 Subject: [PATCH 3/7] Revert "Share wasm-bindgen compat abi selection code" This reverts commit e7a056fe20f7ec5a475923ff2f4eda8ca9e1a74b. --- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 20 ++++---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 2bec761b0e5..a6b7b393213 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2752,7 +2752,7 @@ where attrs }); - if call::use_wasm_bindgen_compat_abi(target) { + if target.arch == "wasm32" && target.os == "unknown" { // wasm-bindgen depends on ABI details and is incompatible with the // correct C ABI, so this is being kept around until wasm-bindgen // can be fixed to work with the correct ABI. See #63649 for further diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 521aea6dd72..2cbd52bf3e9 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -1,6 +1,6 @@ use crate::abi::{self, Abi, Align, FieldsShape, Size}; use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; -use crate::spec::{self, HasTargetSpec, Target}; +use crate::spec::{self, HasTargetSpec}; mod aarch64; mod amdgpu; @@ -631,10 +631,9 @@ impl<'a, Ty> FnAbi<'a, Ty> { "nvptx64" => nvptx64::compute_abi_info(self), "hexagon" => hexagon::compute_abi_info(self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), - "wasm32" => if use_wasm_bindgen_compat_abi(cx.target_spec()) { - wasm32_bindgen_compat::compute_abi_info(self) - } else { - wasm32::compute_abi_info(cx, self) + "wasm32" => match cx.target_spec().os.as_str() { + "emscripten" | "wasi" => wasm32::compute_abi_info(cx, self), + _ => wasm32_bindgen_compat::compute_abi_info(self), }, "asmjs" => wasm32::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), @@ -643,14 +642,3 @@ impl<'a, Ty> FnAbi<'a, Ty> { Ok(()) } } - -pub fn use_wasm_bindgen_compat_abi(target_spec: &Target) -> bool { - if target_spec.arch.as_str() == "wasm32" { - match target_spec.os.as_str() { - "emscripten" | "wasi" => false, - _ => true, - } - } else { - false - } -} From ecbc6610302c4269f3e3e903022d8a84d5537e59 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 26 Jan 2021 11:09:09 +0100 Subject: [PATCH 4/7] Revert "Fix abi for wasm-bindgen" This reverts commit 4d2766e3524129f0d7ec6ad34c4045150ad4f978. --- compiler/rustc_middle/src/ty/layout.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index a6b7b393213..ef467ed6514 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2752,14 +2752,6 @@ where attrs }); - if target.arch == "wasm32" && target.os == "unknown" { - // wasm-bindgen depends on ABI details and is incompatible with the - // correct C ABI, so this is being kept around until wasm-bindgen - // can be fixed to work with the correct ABI. See #63649 for further - // discussion. - arg.mode = PassMode::Direct(ArgAttributes::new()); - } - if arg.layout.is_zst() { // For some forsaken reason, x86_64-pc-windows-gnu // doesn't ignore zero-sized struct arguments. From 903c553f4a2fc8344edac0da565e6c1a7fad4b39 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 26 Jan 2021 11:31:37 +0100 Subject: [PATCH 5/7] Wasm-bindgen abi compat using cast_to --- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 11 ++++- .../src/abi/call/wasm32_bindgen_compat.rs | 45 ++++++++++++++++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index ef467ed6514..041c8c9281a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2860,7 +2860,7 @@ where return; } - if let Err(msg) = self.adjust_for_cabi(cx, abi) { + if let Err(msg) = self.adjust_for_cabi(cx, &cx.tcx().sess.target_features, abi) { cx.tcx().sess.fatal(&msg); } } diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 2cbd52bf3e9..fa6da9f85b9 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -53,6 +53,8 @@ pub enum PassMode { // Hack to disable non_upper_case_globals only for the bitflags! and not for the rest // of this module pub use attr_impl::ArgAttribute; +use rustc_data_structures::stable_set::FxHashSet; +use rustc_span::Symbol; #[allow(non_upper_case_globals)] #[allow(unused)] @@ -592,7 +594,12 @@ pub struct FnAbi<'a, Ty> { } impl<'a, Ty> FnAbi<'a, Ty> { - pub fn adjust_for_cabi(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String> + pub fn adjust_for_cabi( + &mut self, + cx: &C, + target_features: &FxHashSet, + abi: spec::abi::Abi, + ) -> Result<(), String> where Ty: TyAndLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout + HasTargetSpec, @@ -633,7 +640,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" => match cx.target_spec().os.as_str() { "emscripten" | "wasi" => wasm32::compute_abi_info(cx, self), - _ => wasm32_bindgen_compat::compute_abi_info(self), + _ => wasm32_bindgen_compat::compute_abi_info(cx, target_features, self), }, "asmjs" => wasm32::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), diff --git a/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs index 59571fd9d48..d73240a614e 100644 --- a/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs +++ b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs @@ -5,25 +5,58 @@ // can be fixed to work with the correct ABI. See #63649 for further // discussion. -use crate::abi::call::{ArgAbi, FnAbi}; +use rustc_data_structures::stable_set::FxHashSet; +use rustc_span::Symbol; -fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { +use crate::abi::call::{ArgAbi, FnAbi, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; + +fn classify_ret<'a, Ty, C>(cx: &C, target_features: &FxHashSet, ret: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + if ret.layout.is_aggregate() { + if let Some(unit) = ret.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { + let size = ret.layout.size; + if unit.size == size || target_features.contains(&Symbol::intern("multivalue")) { + ret.cast_to(Uniform { unit, total: size }); + } + } + } ret.extend_integer_width_to(32); } -fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + if arg.layout.is_aggregate() { + if let Some(unit) = arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { + let size = arg.layout.size; + arg.cast_to(Uniform { unit, total: size }); + } + } arg.extend_integer_width_to(32); } -pub fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { +pub fn compute_abi_info<'a, Ty, C>( + cx: &C, + target_features: &FxHashSet, + fn_abi: &mut FnAbi<'a, Ty>, +) where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ if !fn_abi.ret.is_ignore() { - classify_ret(&mut fn_abi.ret); + classify_ret(cx, target_features, &mut fn_abi.ret); } for arg in &mut fn_abi.args { if arg.is_ignore() { continue; } - classify_arg(arg); + classify_arg(cx, arg); } } From eb99ea51421a142099f0670156f4ee5353013da9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 26 Jan 2021 13:38:59 +0100 Subject: [PATCH 6/7] Revert "Wasm-bindgen abi compat using cast_to" This reverts commit 903c553f4a2fc8344edac0da565e6c1a7fad4b39. --- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 11 +---- .../src/abi/call/wasm32_bindgen_compat.rs | 45 +++---------------- 3 files changed, 9 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 041c8c9281a..ef467ed6514 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2860,7 +2860,7 @@ where return; } - if let Err(msg) = self.adjust_for_cabi(cx, &cx.tcx().sess.target_features, abi) { + if let Err(msg) = self.adjust_for_cabi(cx, abi) { cx.tcx().sess.fatal(&msg); } } diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index fa6da9f85b9..2cbd52bf3e9 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -53,8 +53,6 @@ pub enum PassMode { // Hack to disable non_upper_case_globals only for the bitflags! and not for the rest // of this module pub use attr_impl::ArgAttribute; -use rustc_data_structures::stable_set::FxHashSet; -use rustc_span::Symbol; #[allow(non_upper_case_globals)] #[allow(unused)] @@ -594,12 +592,7 @@ pub struct FnAbi<'a, Ty> { } impl<'a, Ty> FnAbi<'a, Ty> { - pub fn adjust_for_cabi( - &mut self, - cx: &C, - target_features: &FxHashSet, - abi: spec::abi::Abi, - ) -> Result<(), String> + pub fn adjust_for_cabi(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String> where Ty: TyAndLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout + HasTargetSpec, @@ -640,7 +633,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" => match cx.target_spec().os.as_str() { "emscripten" | "wasi" => wasm32::compute_abi_info(cx, self), - _ => wasm32_bindgen_compat::compute_abi_info(cx, target_features, self), + _ => wasm32_bindgen_compat::compute_abi_info(self), }, "asmjs" => wasm32::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), diff --git a/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs index d73240a614e..59571fd9d48 100644 --- a/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs +++ b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs @@ -5,58 +5,25 @@ // can be fixed to work with the correct ABI. See #63649 for further // discussion. -use rustc_data_structures::stable_set::FxHashSet; -use rustc_span::Symbol; +use crate::abi::call::{ArgAbi, FnAbi}; -use crate::abi::call::{ArgAbi, FnAbi, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; - -fn classify_ret<'a, Ty, C>(cx: &C, target_features: &FxHashSet, ret: &mut ArgAbi<'a, Ty>) -where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, -{ - if ret.layout.is_aggregate() { - if let Some(unit) = ret.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { - let size = ret.layout.size; - if unit.size == size || target_features.contains(&Symbol::intern("multivalue")) { - ret.cast_to(Uniform { unit, total: size }); - } - } - } +fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { ret.extend_integer_width_to(32); } -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, -{ - if arg.layout.is_aggregate() { - if let Some(unit) = arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { - let size = arg.layout.size; - arg.cast_to(Uniform { unit, total: size }); - } - } +fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { arg.extend_integer_width_to(32); } -pub fn compute_abi_info<'a, Ty, C>( - cx: &C, - target_features: &FxHashSet, - fn_abi: &mut FnAbi<'a, Ty>, -) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, -{ +pub fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { if !fn_abi.ret.is_ignore() { - classify_ret(cx, target_features, &mut fn_abi.ret); + classify_ret(&mut fn_abi.ret); } for arg in &mut fn_abi.args { if arg.is_ignore() { continue; } - classify_arg(cx, arg); + classify_arg(arg); } } From c1c06f3e3f7bbe7336709f2b4749e969b44c0dbb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 26 Jan 2021 13:42:40 +0100 Subject: [PATCH 7/7] Use PassMode::Direct for Abi::Aggregate by default --- compiler/rustc_middle/src/ty/layout.rs | 7 +++---- compiler/rustc_target/src/abi/call/mod.rs | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index ef467ed6514..4ce908bdd64 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2843,10 +2843,9 @@ where let max_by_val_size = Pointer.size(cx) * 2; let size = arg.layout.size; - let is_indirect_not_on_stack = - matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); - assert!(is_indirect_not_on_stack, "{:?}", arg); - if !arg.layout.is_unsized() && size <= max_by_val_size { + if arg.layout.is_unsized() || size > max_by_val_size { + arg.make_indirect(); + } else { // We want to pass small aggregates as immediates, but using // a LLVM aggregate type for this leads to bad optimizations, // so we pick an appropriately sized integer type instead. diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 2cbd52bf3e9..aa1c31bda54 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -32,7 +32,7 @@ pub enum PassMode { Ignore, /// Pass the argument directly. /// - /// The argument has a layout abi of `Scalar` or `Vector`. + /// The argument has a layout abi of `Scalar`, `Vector` or in rare cases `Aggregate`. Direct(ArgAttributes), /// Pass a pair's elements directly in two arguments. /// @@ -453,7 +453,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs(&layout, b, a.value.size(cx).align_to(b.value.align(cx).abi)), ), Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), - Abi::Aggregate { .. } => Self::indirect_pass_mode(&layout), + Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()), }; ArgAbi { layout, pad: None, mode } }