Skip to content

Commit c4b138f

Browse files
committed
Use pointers for the C definitions to resolve ABI inconsistencies
1 parent fc1b81d commit c4b138f

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
@@ -88,17 +88,21 @@ where
8888
pub fn as_non_imm_arglist_c(&self) -> String {
8989
self.iter()
9090
.filter(|arg| !arg.has_constraint())
91-
.format_with(", ", |arg, fmt| {
92-
fmt(&format_args!("{} {}", arg.to_c_type(), arg.name))
91+
.format_with("", |arg, fmt| {
92+
fmt(&format_args!(", const {}* {}", arg.to_c_type(), arg.name))
9393
})
9494
.to_string()
9595
}
9696

9797
pub fn as_non_imm_arglist_rust(&self) -> String {
9898
self.iter()
9999
.filter(|arg| !arg.has_constraint())
100-
.format_with(", ", |arg, fmt| {
101-
fmt(&format_args!("{}: {}", arg.name, arg.ty.rust_type()))
100+
.format_with("", |arg, fmt| {
101+
fmt(&format_args!(
102+
", {}: *const {}",
103+
arg.name,
104+
arg.ty.rust_type()
105+
))
102106
})
103107
.to_string()
104108
}
@@ -110,6 +114,7 @@ where
110114
if arg.has_constraint() {
111115
fmt(&imm_args.next().unwrap())
112116
} else {
117+
fmt(&"*")?;
113118
fmt(&arg.name)
114119
}
115120
})
@@ -125,6 +130,13 @@ where
125130
.join(", ")
126131
}
127132

133+
pub fn as_c_call_param_rust(&self) -> String {
134+
self.iter()
135+
.filter(|a| !a.has_constraint())
136+
.map(|arg| format!(", &raw const {} as _", arg.generate_name()))
137+
.join("")
138+
}
139+
128140
/// Creates a line for each argument that initializes an array for Rust from which `loads` argument
129141
/// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
130142
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
@@ -130,10 +130,13 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
130130

131131
// Each function (and each specialization) has its own type. Erase that type with a cast.
132132
let mut coerce = String::from("fn(");
133+
let mut c_coerce = String::from("fn(_, ");
133134
for _ in intrinsic.arguments.iter().filter(|a| !a.has_constraint()) {
134135
coerce += "_, ";
136+
c_coerce += "_, ";
135137
}
136138
coerce += ") -> _";
139+
c_coerce += ")";
137140

138141
if intrinsic
139142
.arguments
@@ -152,7 +155,7 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
152155
intrinsic.iter_specializations(|imm_values| {
153156
writeln!(
154157
w,
155-
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {coerce}),",
158+
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {c_coerce}),",
156159
const_args = imm_values.iter().join(","),
157160
c_const_args = imm_values.iter().join("_"),
158161
)
@@ -191,8 +194,12 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
191194
" for i in 0..{passes} {{",
192195
" unsafe {{",
193196
"{loaded_args}",
194-
" let __rust_return_value = rust({args});",
195-
" let __c_return_value = c({args});",
197+
" let __rust_return_value = rust({rust_args});",
198+
"",
199+
" let mut __c_return_value = std::mem::MaybeUninit::uninit();",
200+
" c(__c_return_value.as_mut_ptr(){c_args});",
201+
" let __c_return_value = __c_return_value.assume_init();",
202+
"",
196203
" assert_eq!({cast_prefix}__rust_return_value{cast_suffix}, {cast_prefix}__c_return_value{cast_suffix}, \"{{id}}\");",
197204
" }}",
198205
" }}",
@@ -201,7 +208,8 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
201208
loaded_args = intrinsic
202209
.arguments
203210
.load_values_rust(Indentation::default().nest_by(4)),
204-
args = intrinsic.arguments.as_call_param_rust(),
211+
rust_args = intrinsic.arguments.as_call_param_rust(),
212+
c_args = intrinsic.arguments.as_c_call_param_rust(),
205213
passes = passes,
206214
cast_prefix = cast_prefix,
207215
cast_suffix = cast_suffix,
@@ -250,7 +258,7 @@ pub fn write_bindings_rust<T: IntrinsicTypeDefinition>(
250258
intrinsic.iter_specializations(|imm_values| {
251259
writeln!(
252260
w,
253-
" fn {name}_wrapper{imm_arglist}({arglist}) -> {return_ty};",
261+
" fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});",
254262
return_ty = intrinsic.results.rust_type(),
255263
name = intrinsic.name,
256264
imm_arglist = imm_values

0 commit comments

Comments
 (0)