Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for raw-dylib with vectorcall, and fix vectorcall code generation #99476

Merged
merged 1 commit into from
Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,9 @@ impl<'tcx> Collector<'tcx> {
Abi::Fastcall { .. } => {
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
}
// Vectorcall is intentionally not supported at this time.
Abi::Vectorcall { .. } => {
dpaoliello marked this conversation as resolved.
Show resolved Hide resolved
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
}
_ => {
self.tcx.sess.span_fatal(
item.span,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {

match &cx.target_spec().arch[..] {
"x86" => {
let flavor = if let spec::abi::Abi::Fastcall { .. } = abi {
x86::Flavor::Fastcall
let flavor = if let spec::abi::Abi::Fastcall { .. }
| spec::abi::Abi::Vectorcall { .. } = abi
{
x86::Flavor::FastcallOrVectorcall
} else {
x86::Flavor::General
};
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_target/src/abi/call/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::spec::HasTargetSpec;
#[derive(PartialEq)]
pub enum Flavor {
General,
Fastcall,
FastcallOrVectorcall,
}

pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
Expand Down Expand Up @@ -60,9 +60,9 @@ where
}
}

if flavor == Flavor::Fastcall {
if flavor == Flavor::FastcallOrVectorcall {
// Mark arguments as InReg like clang does it,
// so our fastcall is compatible with C/C++ fastcall.
// so our fastcall/vectorcall is compatible with C/C++ fastcall/vectorcall.

// Clang reference: lib/CodeGen/TargetInfo.cpp
// See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()
Expand Down
11 changes: 10 additions & 1 deletion src/test/run-make/raw-dylib-alt-calling-convention/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@ ifdef IS_MSVC
else
$(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
endif
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt

"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
ifdef RUSTC_BLESS_TEST
cp "$(TMPDIR)"/output.txt output.txt
else
$(DIFF) output.txt "$(TMPDIR)"/output.txt
endif

ifdef IS_MSVC
"$(TMPDIR)"/driver true > "$(TMPDIR)"/output.msvc.txt
ifdef RUSTC_BLESS_TEST
cp "$(TMPDIR)"/output.msvc.txt output.msvc.txt
else
$(DIFF) output.msvc.txt "$(TMPDIR)"/output.msvc.txt
endif
endif
5 changes: 4 additions & 1 deletion src/test/run-make/raw-dylib-alt-calling-convention/driver.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
extern crate raw_dylib_alt_calling_convention_test;

fn main() {
raw_dylib_alt_calling_convention_test::library_function();
raw_dylib_alt_calling_convention_test::library_function(
std::env::args().skip(1).next().map_or(
false,
|s| std::str::FromStr::from_str(&s).unwrap()));
}
55 changes: 55 additions & 0 deletions src/test/run-make/raw-dylib-alt-calling-convention/extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,58 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
printf("fastcall_fn_9(%d, %.1f)\n", x, y);
fflush(stdout);
}

// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#ifdef _MSC_VER
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
printf("vectorcall_fn_1(%d)\n", i);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_2(uint8_t i, float f) {
printf("vectorcall_fn_2(%d, %.1f)\n", i, f);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_3(double d) {
printf("vectorcall_fn_3(%.1f)\n", d);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_4(uint8_t i, uint8_t j, float f) {
printf("vectorcall_fn_4(%d, %d, %.1f)\n", i, j, f);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_5(struct S s, int i) {
printf("vectorcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_6(struct S* s) {
if (s) {
printf("vectorcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
} else {
printf("vectorcall_fn_6(null)\n");
}
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_7(struct S2 s, int i) {
printf("vectorcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_8(struct S3 s, struct S3 t) {
printf("vectorcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
fflush(stdout);
}
#endif
76 changes: 54 additions & 22 deletions src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(raw_dylib)]
#![feature(abi_vectorcall)]

#[repr(C)]
#[derive(Clone)]
Expand Down Expand Up @@ -46,29 +47,60 @@ extern "fastcall" {
fn fastcall_fn_9(x: u8, y: f64);
}

pub fn library_function() {
#[cfg(target_env = "msvc")]
#[link(name = "extern", kind = "raw-dylib")]
extern "vectorcall" {
fn vectorcall_fn_1(i: i32);
fn vectorcall_fn_2(c: u8, f: f32);
fn vectorcall_fn_3(d: f64);
fn vectorcall_fn_4(i: u8, j: u8, f: f32);
fn vectorcall_fn_5(a: S, b: i32);
fn vectorcall_fn_6(a: Option<&S>);
fn vectorcall_fn_7(a: S2, b: i32);
fn vectorcall_fn_8(a: S3, b: S3);
fn vectorcall_fn_9(x: u8, y: f64);
}

pub fn library_function(run_msvc_only: bool) {
unsafe {
stdcall_fn_1(14);
stdcall_fn_2(16, 3.5);
stdcall_fn_3(3.5);
stdcall_fn_4(1, 2, 3.0);
stdcall_fn_5(S { x: 1, y: 2 }, 16);
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
stdcall_fn_9(1, 3.0);
if !run_msvc_only {
stdcall_fn_1(14);
stdcall_fn_2(16, 3.5);
stdcall_fn_3(3.5);
stdcall_fn_4(1, 2, 3.0);
stdcall_fn_5(S { x: 1, y: 2 }, 16);
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
stdcall_fn_9(1, 3.0);

fastcall_fn_1(14);
fastcall_fn_2(16, 3.5);
fastcall_fn_3(3.5);
fastcall_fn_4(1, 2, 3.0);
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
fastcall_fn_9(1, 3.0);
} else {
// FIXME: 91167
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
// on i686-pc-windows-gnu; disabling these until the indicated issue is fixed.
fastcall_fn_5(S { x: 1, y: 2 }, 16);
fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
dpaoliello marked this conversation as resolved.
Show resolved Hide resolved

fastcall_fn_1(14);
fastcall_fn_2(16, 3.5);
fastcall_fn_3(3.5);
fastcall_fn_4(1, 2, 3.0);
// FIXME: 91167
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
// on i686-pc-windows-gnu; commenting these out until the indicated issue is fixed.
//fastcall_fn_5(S { x: 1, y: 2 }, 16);
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
//fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
fastcall_fn_9(1, 3.0);
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#[cfg(target_env = "msvc")]
{
vectorcall_fn_1(14);
vectorcall_fn_2(16, 3.5);
vectorcall_fn_3(3.5);
vectorcall_fn_4(1, 2, 3.0);
vectorcall_fn_5(S { x: 1, y: 2 }, 16);
vectorcall_fn_6(Some(&S { x: 10, y: 12 }));
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
vectorcall_fn_9(1, 3.0);
}
}
}
}
11 changes: 11 additions & 0 deletions src/test/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fastcall_fn_5(S { x: 1, y: 2 }, 16)
fastcall_fn_7(S2 { x: 15, y: 16 }, 3)
vectorcall_fn_1(14)
vectorcall_fn_2(16, 3.5)
vectorcall_fn_3(3.5)
vectorcall_fn_4(1, 2, 3.0)
vectorcall_fn_5(S { x: 1, y: 2 }, 16)
vectorcall_fn_6(S { x: 10, y: 12 })
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
vectorcall_fn_9(1, 3.0)