Skip to content

Commit 2dfa840

Browse files
committed
Use pointers for the C definitions to resolve ABI inconsistencies
1 parent a764f33 commit 2dfa840

4 files changed

Lines changed: 31 additions & 21 deletions

File tree

ci/intrinsic-test.sh

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,4 @@ case "${TARGET}" in
5757
;;
5858
esac
5959

60-
case ${TARGET} in
61-
# FIXME: currently this needs enabling because the test functions don't have any `target_feature`attribute
62-
x86_64-*)
63-
export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+avx512f"
64-
;;
65-
armv7-* | aarch64*)
66-
export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+neon"
67-
;;
68-
esac
69-
7060
cargo test --manifest-path=rust_programs/Cargo.toml --target "${TARGET}" --profile "${PROFILE}" --no-fail-fast

crates/intrinsic-test/src/common/argument.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,21 @@ where
8787
pub fn as_non_imm_arglist_c(&self) -> String {
8888
self.iter()
8989
.filter(|arg| !arg.has_constraint())
90-
.format_with(", ", |arg, fmt| {
91-
fmt(&format_args!("{} {}", arg.to_c_type(), arg.name))
90+
.format_with("", |arg, fmt| {
91+
fmt(&format_args!(", const {}* {}", arg.to_c_type(), arg.name))
9292
})
9393
.to_string()
9494
}
9595

9696
pub fn as_non_imm_arglist_rust(&self) -> String {
9797
self.iter()
9898
.filter(|arg| !arg.has_constraint())
99-
.format_with(", ", |arg, fmt| {
100-
fmt(&format_args!("{}: {}", arg.name, arg.ty.rust_type()))
99+
.format_with("", |arg, fmt| {
100+
fmt(&format_args!(
101+
", {}: *const {}",
102+
arg.name,
103+
arg.ty.rust_type()
104+
))
101105
})
102106
.to_string()
103107
}
@@ -109,6 +113,7 @@ where
109113
if arg.has_constraint() {
110114
fmt(&imm_args.next().unwrap())
111115
} else {
116+
fmt(&"*")?;
112117
fmt(&arg.name)
113118
}
114119
})
@@ -124,6 +129,13 @@ where
124129
.join(", ")
125130
}
126131

132+
pub fn as_c_call_param_rust(&self) -> String {
133+
self.iter()
134+
.filter(|a| !a.has_constraint())
135+
.map(|arg| format!(", &raw const {} as _", arg.generate_name()))
136+
.join("")
137+
}
138+
127139
/// Creates a line for each argument that initializes an array for Rust from which `loads` argument
128140
/// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
129141
pub fn gen_arglists_rust(

crates/intrinsic-test/src/common/gen_c.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ pub fn write_wrapper_c<T: IntrinsicTypeDefinition>(
2424
writeln!(
2525
w,
2626
"
27-
{return_ty} {name}_wrapper{imm_arglist}({arglist}) {{
28-
return {name}({params});
27+
void {name}_wrapper{imm_arglist}({return_ty}* __dst{arglist}) {{
28+
*__dst = {name}({params});
2929
}}",
3030
return_ty = intrinsic.results.c_type(),
3131
name = intrinsic.name,

crates/intrinsic-test/src/common/gen_rust.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,13 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
136136

137137
// Each function (and each specialization) has its own type. Erase that type with a cast.
138138
let mut coerce = String::from("fn(");
139+
let mut c_coerce = String::from("fn(_, ");
139140
for _ in intrinsic.arguments.iter().filter(|a| !a.has_constraint()) {
140141
coerce += "_, ";
142+
c_coerce += "_, ";
141143
}
142144
coerce += ") -> _";
145+
c_coerce += ")";
143146

144147
if intrinsic
145148
.arguments
@@ -158,7 +161,7 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
158161
intrinsic.iter_specializations(|imm_values| {
159162
writeln!(
160163
w,
161-
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {coerce}),",
164+
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {c_coerce}),",
162165
const_args = imm_values.iter().join(","),
163166
c_const_args = imm_values.iter().join("_"),
164167
)
@@ -197,8 +200,12 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
197200
" for i in 0..{passes} {{",
198201
" unsafe {{",
199202
"{loaded_args}",
200-
" let __rust_return_value = rust({args});",
201-
" let __c_return_value = c({args});",
203+
" let __rust_return_value = rust({rust_args});",
204+
"",
205+
" let mut __c_return_value = std::mem::MaybeUninit::uninit();",
206+
" c(__c_return_value.as_mut_ptr(){c_args});",
207+
" let __c_return_value = __c_return_value.assume_init();",
208+
"",
202209
" assert_eq!({cast_prefix}__rust_return_value{cast_suffix}, {cast_prefix}__c_return_value{cast_suffix}, \"{{id}}\");",
203210
" }}",
204211
" }}",
@@ -207,7 +214,8 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
207214
loaded_args = intrinsic
208215
.arguments
209216
.load_values_rust(Indentation::default().nest_by(4)),
210-
args = intrinsic.arguments.as_call_param_rust(),
217+
rust_args = intrinsic.arguments.as_call_param_rust(),
218+
c_args = intrinsic.arguments.as_c_call_param_rust(),
211219
passes = passes,
212220
cast_prefix = cast_prefix,
213221
cast_suffix = cast_suffix,
@@ -256,7 +264,7 @@ pub fn write_bindings_rust<T: IntrinsicTypeDefinition>(
256264
intrinsic.iter_specializations(|imm_values| {
257265
writeln!(
258266
w,
259-
" fn {name}_wrapper{imm_arglist}({arglist}) -> {return_ty};",
267+
" fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});",
260268
return_ty = intrinsic.results.rust_type(),
261269
name = intrinsic.name,
262270
imm_arglist = imm_values

0 commit comments

Comments
 (0)