Skip to content

Commit fe33428

Browse files
committedAug 1, 2022
Auto merge of #99476 - dpaoliello:rawdylibvectorcall, r=michaelwoerister
Add tests for raw-dylib with vectorcall, and fix vectorcall code generation * Adds tests for using `raw-dylib` (#58713) with `vectorcall`. * Fixed code generation for `vectorcall` (parameters have to be marked with `InReg`, just like `fastcall`). * Enabled running the `raw-dylib` `fastcall` tests when using MSVC (since I had to add support in the test for running MSVC-only tests since GCC doesn't support `vectorcall`).
2 parents c9e134e + 722d67d commit fe33428

File tree

8 files changed

+144
-30
lines changed

8 files changed

+144
-30
lines changed
 

‎compiler/rustc_metadata/src/native_libs.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,9 @@ impl<'tcx> Collector<'tcx> {
472472
Abi::Fastcall { .. } => {
473473
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
474474
}
475-
// Vectorcall is intentionally not supported at this time.
475+
Abi::Vectorcall { .. } => {
476+
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
477+
}
476478
_ => {
477479
self.tcx.sess.span_fatal(
478480
item.span,

‎compiler/rustc_target/src/abi/call/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
669669

670670
match &cx.target_spec().arch[..] {
671671
"x86" => {
672-
let flavor = if let spec::abi::Abi::Fastcall { .. } = abi {
673-
x86::Flavor::Fastcall
672+
let flavor = if let spec::abi::Abi::Fastcall { .. }
673+
| spec::abi::Abi::Vectorcall { .. } = abi
674+
{
675+
x86::Flavor::FastcallOrVectorcall
674676
} else {
675677
x86::Flavor::General
676678
};

‎compiler/rustc_target/src/abi/call/x86.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::spec::HasTargetSpec;
55
#[derive(PartialEq)]
66
pub enum Flavor {
77
General,
8-
Fastcall,
8+
FastcallOrVectorcall,
99
}
1010

1111
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
@@ -60,9 +60,9 @@ where
6060
}
6161
}
6262

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

6767
// Clang reference: lib/CodeGen/TargetInfo.cpp
6868
// See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()

‎src/test/run-make/raw-dylib-alt-calling-convention/Makefile

+10-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ ifdef IS_MSVC
1414
else
1515
$(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
1616
endif
17-
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
1817

18+
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
1919
ifdef RUSTC_BLESS_TEST
2020
cp "$(TMPDIR)"/output.txt output.txt
2121
else
2222
$(DIFF) output.txt "$(TMPDIR)"/output.txt
2323
endif
24+
25+
ifdef IS_MSVC
26+
"$(TMPDIR)"/driver true > "$(TMPDIR)"/output.msvc.txt
27+
ifdef RUSTC_BLESS_TEST
28+
cp "$(TMPDIR)"/output.msvc.txt output.msvc.txt
29+
else
30+
$(DIFF) output.msvc.txt "$(TMPDIR)"/output.msvc.txt
31+
endif
32+
endif
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
extern crate raw_dylib_alt_calling_convention_test;
22

33
fn main() {
4-
raw_dylib_alt_calling_convention_test::library_function();
4+
raw_dylib_alt_calling_convention_test::library_function(
5+
std::env::args().skip(1).next().map_or(
6+
false,
7+
|s| std::str::FromStr::from_str(&s).unwrap()));
58
}

‎src/test/run-make/raw-dylib-alt-calling-convention/extern.c

+55
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,58 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
121121
printf("fastcall_fn_9(%d, %.1f)\n", x, y);
122122
fflush(stdout);
123123
}
124+
125+
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
126+
#ifdef _MSC_VER
127+
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
128+
printf("vectorcall_fn_1(%d)\n", i);
129+
fflush(stdout);
130+
}
131+
132+
__declspec(dllexport) void __vectorcall vectorcall_fn_2(uint8_t i, float f) {
133+
printf("vectorcall_fn_2(%d, %.1f)\n", i, f);
134+
fflush(stdout);
135+
}
136+
137+
__declspec(dllexport) void __vectorcall vectorcall_fn_3(double d) {
138+
printf("vectorcall_fn_3(%.1f)\n", d);
139+
fflush(stdout);
140+
}
141+
142+
__declspec(dllexport) void __vectorcall vectorcall_fn_4(uint8_t i, uint8_t j, float f) {
143+
printf("vectorcall_fn_4(%d, %d, %.1f)\n", i, j, f);
144+
fflush(stdout);
145+
}
146+
147+
__declspec(dllexport) void __vectorcall vectorcall_fn_5(struct S s, int i) {
148+
printf("vectorcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
149+
fflush(stdout);
150+
}
151+
152+
__declspec(dllexport) void __vectorcall vectorcall_fn_6(struct S* s) {
153+
if (s) {
154+
printf("vectorcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
155+
} else {
156+
printf("vectorcall_fn_6(null)\n");
157+
}
158+
fflush(stdout);
159+
}
160+
161+
__declspec(dllexport) void __vectorcall vectorcall_fn_7(struct S2 s, int i) {
162+
printf("vectorcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
163+
fflush(stdout);
164+
}
165+
166+
__declspec(dllexport) void __vectorcall vectorcall_fn_8(struct S3 s, struct S3 t) {
167+
printf("vectorcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
168+
s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
169+
t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
170+
);
171+
fflush(stdout);
172+
}
173+
174+
__declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
175+
printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
176+
fflush(stdout);
177+
}
178+
#endif

‎src/test/run-make/raw-dylib-alt-calling-convention/lib.rs

+54-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(raw_dylib)]
2+
#![feature(abi_vectorcall)]
23

34
#[repr(C)]
45
#[derive(Clone)]
@@ -46,29 +47,60 @@ extern "fastcall" {
4647
fn fastcall_fn_9(x: u8, y: f64);
4748
}
4849

49-
pub fn library_function() {
50+
#[cfg(target_env = "msvc")]
51+
#[link(name = "extern", kind = "raw-dylib")]
52+
extern "vectorcall" {
53+
fn vectorcall_fn_1(i: i32);
54+
fn vectorcall_fn_2(c: u8, f: f32);
55+
fn vectorcall_fn_3(d: f64);
56+
fn vectorcall_fn_4(i: u8, j: u8, f: f32);
57+
fn vectorcall_fn_5(a: S, b: i32);
58+
fn vectorcall_fn_6(a: Option<&S>);
59+
fn vectorcall_fn_7(a: S2, b: i32);
60+
fn vectorcall_fn_8(a: S3, b: S3);
61+
fn vectorcall_fn_9(x: u8, y: f64);
62+
}
63+
64+
pub fn library_function(run_msvc_only: bool) {
5065
unsafe {
51-
stdcall_fn_1(14);
52-
stdcall_fn_2(16, 3.5);
53-
stdcall_fn_3(3.5);
54-
stdcall_fn_4(1, 2, 3.0);
55-
stdcall_fn_5(S { x: 1, y: 2 }, 16);
56-
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
57-
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
58-
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
59-
stdcall_fn_9(1, 3.0);
66+
if !run_msvc_only {
67+
stdcall_fn_1(14);
68+
stdcall_fn_2(16, 3.5);
69+
stdcall_fn_3(3.5);
70+
stdcall_fn_4(1, 2, 3.0);
71+
stdcall_fn_5(S { x: 1, y: 2 }, 16);
72+
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
73+
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
74+
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
75+
stdcall_fn_9(1, 3.0);
76+
77+
fastcall_fn_1(14);
78+
fastcall_fn_2(16, 3.5);
79+
fastcall_fn_3(3.5);
80+
fastcall_fn_4(1, 2, 3.0);
81+
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
82+
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
83+
fastcall_fn_9(1, 3.0);
84+
} else {
85+
// FIXME: 91167
86+
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
87+
// on i686-pc-windows-gnu; disabling these until the indicated issue is fixed.
88+
fastcall_fn_5(S { x: 1, y: 2 }, 16);
89+
fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
6090

61-
fastcall_fn_1(14);
62-
fastcall_fn_2(16, 3.5);
63-
fastcall_fn_3(3.5);
64-
fastcall_fn_4(1, 2, 3.0);
65-
// FIXME: 91167
66-
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
67-
// on i686-pc-windows-gnu; commenting these out until the indicated issue is fixed.
68-
//fastcall_fn_5(S { x: 1, y: 2 }, 16);
69-
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
70-
//fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
71-
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
72-
fastcall_fn_9(1, 3.0);
91+
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
92+
#[cfg(target_env = "msvc")]
93+
{
94+
vectorcall_fn_1(14);
95+
vectorcall_fn_2(16, 3.5);
96+
vectorcall_fn_3(3.5);
97+
vectorcall_fn_4(1, 2, 3.0);
98+
vectorcall_fn_5(S { x: 1, y: 2 }, 16);
99+
vectorcall_fn_6(Some(&S { x: 10, y: 12 }));
100+
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
101+
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
102+
vectorcall_fn_9(1, 3.0);
103+
}
104+
}
73105
}
74106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fastcall_fn_5(S { x: 1, y: 2 }, 16)
2+
fastcall_fn_7(S2 { x: 15, y: 16 }, 3)
3+
vectorcall_fn_1(14)
4+
vectorcall_fn_2(16, 3.5)
5+
vectorcall_fn_3(3.5)
6+
vectorcall_fn_4(1, 2, 3.0)
7+
vectorcall_fn_5(S { x: 1, y: 2 }, 16)
8+
vectorcall_fn_6(S { x: 10, y: 12 })
9+
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
10+
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
11+
vectorcall_fn_9(1, 3.0)

0 commit comments

Comments
 (0)