Skip to content

Commit 618c2cf

Browse files
committed
also fix and test fastcall
1 parent 39a69a9 commit 618c2cf

File tree

5 files changed

+61
-16
lines changed

5 files changed

+61
-16
lines changed

compiler/rustc_target/src/callconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
667667
}
668668
"x86_64" => match abi {
669669
spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
670-
spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(cx, self),
670+
spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(cx, self, abi),
671671
_ => {
672672
if cx.target_spec().is_like_windows {
673-
x86_win64::compute_abi_info(cx, self)
673+
x86_win64::compute_abi_info(cx, self, abi)
674674
} else {
675675
x86_64::compute_abi_info(cx, self)
676676
}

compiler/rustc_target/src/callconv/x86_win64.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use rustc_abi::{BackendRepr, Float, Primitive};
1+
use rustc_abi::{BackendRepr, ExternAbi, Float, Primitive};
22

3-
use super::Conv;
43
use crate::abi::call::{ArgAbi, FnAbi, Reg};
54
use crate::spec::HasTargetSpec;
65

76
// Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
87

9-
pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
8+
pub(crate) fn compute_abi_info<Ty>(
9+
cx: &impl HasTargetSpec,
10+
fn_abi: &mut FnAbi<'_, Ty>,
11+
abi: ExternAbi,
12+
) {
1013
let fixup = |a: &mut ArgAbi<'_, Ty>| {
1114
match a.layout.backend_repr {
1215
BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
@@ -47,7 +50,7 @@ pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'
4750
if cx.target_spec().os == "windows"
4851
&& cx.target_spec().env == "gnu"
4952
&& arg.layout.is_zst()
50-
&& fn_abi.conv == Conv::C
53+
&& matches!(abi, ExternAbi::C { .. })
5154
{
5255
arg.make_indirect_from_ignore();
5356
}

compiler/rustc_target/src/spec/mod.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -2813,12 +2813,17 @@ impl Target {
28132813
Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false },
28142814
Abi::EfiApi => Abi::C { unwind: false },
28152815

2816-
// See commentary in `is_abi_supported`.
2817-
Abi::Stdcall { .. } | Abi::Thiscall { .. } if self.arch == "x86" => abi,
2818-
Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => Abi::C { unwind },
2819-
Abi::Fastcall { .. } if self.arch == "x86" => abi,
2816+
// See commentary in `is_abi_supported`: we map these ABIs to "C" when they do not make sense.
2817+
Abi::Stdcall { .. } | Abi::Thiscall { .. } | Abi::Fastcall { .. }
2818+
if self.arch == "x86" =>
2819+
{
2820+
abi
2821+
}
28202822
Abi::Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi,
2821-
Abi::Fastcall { unwind } | Abi::Vectorcall { unwind } => Abi::C { unwind },
2823+
Abi::Stdcall { unwind }
2824+
| Abi::Thiscall { unwind }
2825+
| Abi::Fastcall { unwind }
2826+
| Abi::Vectorcall { unwind } => Abi::C { unwind },
28222827

28232828
// The Windows x64 calling convention we use for `extern "Rust"`
28242829
// <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions#register-volatility-and-preservation>

compiler/rustc_ty_utils/src/abi.rs

+34-5
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,10 @@ fn fn_sig_for_fn_abi<'tcx>(
267267

268268
#[inline]
269269
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv {
270+
let target = &tcx.sess.target;
271+
270272
use rustc_abi::ExternAbi::*;
271-
match tcx.sess.target.adjust_abi(abi, c_variadic) {
273+
match target.adjust_abi(abi, c_variadic) {
272274
RustIntrinsic | Rust | RustCall => Conv::Rust,
273275

274276
// This is intentionally not using `Conv::Cold`, as that has to preserve
@@ -279,10 +281,37 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv
279281
System { .. } => bug!("system abi should be selected elsewhere"),
280282
EfiApi => bug!("eficall abi should be selected elsewhere"),
281283

282-
Stdcall { .. } => Conv::X86Stdcall,
283-
Fastcall { .. } => Conv::X86Fastcall,
284-
Vectorcall { .. } => Conv::X86VectorCall,
285-
Thiscall { .. } => Conv::X86ThisCall,
284+
// See commentary in `is_abi_supported`: we map these to "C" on targets
285+
// where they do not make sense.
286+
Stdcall { .. } => {
287+
if target.arch == "x86" {
288+
Conv::X86Stdcall
289+
} else {
290+
Conv::C
291+
}
292+
}
293+
Fastcall { .. } => {
294+
if target.arch == "x86" {
295+
Conv::X86Fastcall
296+
} else {
297+
Conv::C
298+
}
299+
}
300+
Vectorcall { .. } => {
301+
if ["x86", "x86_64"].contains(&&target.arch[..]) {
302+
Conv::X86VectorCall
303+
} else {
304+
Conv::C
305+
}
306+
}
307+
Thiscall { .. } => {
308+
if target.arch == "x86" {
309+
Conv::X86ThisCall
310+
} else {
311+
Conv::C
312+
}
313+
}
314+
286315
C { .. } => Conv::C,
287316
Unadjusted => Conv::C,
288317
Win64 { .. } => Conv::X86_64Win64,

tests/codegen/abi-win64-zst.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//@ compile-flags: -Z merge-functions=disabled
2+
13
//@ revisions: linux
24
//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
35
//@[linux] needs-llvm-components: x86
@@ -31,6 +33,12 @@ extern "sysv64" fn pass_zst_sysv64(_: ()) {}
3133
#[no_mangle]
3234
extern "vectorcall" fn pass_zst_vectorcall(_: ()) {}
3335

36+
// windows-gnu: define void @pass_zst_fastcall()
37+
// windows-msvc: define void @pass_zst_fastcall()
38+
#[no_mangle]
39+
#[cfg(windows)] // "fastcall" is not valid on 64bit Linux
40+
extern "fastcall" fn pass_zst_fastcall(_: ()) {}
41+
3442
// For `extern "C"` functions, ZST are *not* ignored on windows-gnu.
3543
// That's likely an accident on their side but the ABI is what it is.
3644

0 commit comments

Comments
 (0)