Merge pull request #2122 from davidtwco/intrinsic-test-fmt

intrinsic-test: run rustfmt on generated sources
This commit is contained in:
Sayantan Chakraborty
2026-05-20 03:20:37 +00:00
committed by GitHub
6 changed files with 43 additions and 57 deletions
+1
View File
@@ -297,6 +297,7 @@ jobs:
rustup component add rust-src
echo "CARGO_UNSTABLE_BUILD_STD=std" >> $GITHUB_ENV
if: ${{ matrix.build_std }}
- run: rustup component add rustfmt
# Configure some env vars based on matrix configuration
- run: echo "PROFILE=${{ matrix.profile }}" >> $GITHUB_ENV
@@ -4,7 +4,6 @@
use super::constraint::Constraint;
use super::gen_rust::PASSES;
use super::indentation::Indentation;
use super::intrinsic_helpers::IntrinsicTypeDefinition;
/// An argument for the intrinsic.
@@ -149,37 +148,36 @@ pub fn as_c_call_param_rust(&self) -> String {
pub fn gen_arg_rust(
arg: &Argument<T>,
w: &mut impl std::io::Write,
indentation: Indentation,
loads: u32,
) -> std::io::Result<()> {
writeln!(
w,
"{indentation}static {name}: [{ty}; {load_size}] = {values};\n",
"static {name}: [{ty}; {load_size}] = {values};\n",
name = arg.rust_vals_array_name(),
ty = arg.ty.rust_scalar_type(),
load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
values = arg.ty.populate_random(indentation, loads)
values = arg.ty.populate_random(loads)
)
}
/// Creates a line for each argument that initializes the argument from array `[ARG]_VALS` at
/// an offset `i` using a load intrinsic, in Rust.
/// e.g `let a = vld1_u8(A_VALS.as_ptr().offset(i));`
pub fn load_values_rust(&self, indentation: Indentation) -> String {
pub fn load_values_rust(&self) -> String {
self.iter()
.filter(|&arg| !arg.has_constraint())
.enumerate()
.map(|(idx, arg)| {
if arg.is_simd() {
format!(
"{indentation}let {name} = {load}({vals_name}.as_ptr().add((i+{idx}) % {PASSES}) as _);\n",
"let {name} = {load}({vals_name}.as_ptr().add((i+{idx}) % {PASSES}) as _);\n",
name = arg.generate_name(),
vals_name = arg.rust_vals_array_name(),
load = arg.ty.get_load_function(),
)
} else {
format!(
"{indentation}let {name} = {vals_name}[(i+{idx}) % {PASSES}];\n",
"let {name} = {vals_name}[(i+{idx}) % {PASSES}];\n",
name = arg.generate_name(),
vals_name = arg.rust_vals_array_name(),
)
@@ -1,6 +1,7 @@
use std::process::Command;
use itertools::Itertools;
use super::indentation::Indentation;
use super::intrinsic_helpers::IntrinsicTypeDefinition;
use crate::common::argument::ArgumentList;
use crate::common::intrinsic::Intrinsic;
@@ -36,6 +37,22 @@ macro_rules! concatln {
};
}
/// Run rustfmt on the generated source code
pub fn run_rustfmt(source_path: &str) {
let output = Command::new("rustfmt")
.args([source_path])
.output()
.expect("failed to run rustfmt on generated sources");
if !output.status.success() {
panic!(
"failed to run rustfmt on generated sources:\nstdout:{stdout}\nstderr:{stderr}",
stdout = String::from_utf8_lossy(&output.stdout),
stderr = String::from_utf8_lossy(&output.stderr)
);
}
}
pub fn write_bin_cargo_toml(
w: &mut impl std::io::Write,
module_count: usize,
@@ -106,7 +123,7 @@ pub fn write_lib_rs<T: IntrinsicTypeDefinition>(
let name = arg.rust_vals_array_name().to_string();
if seen.insert(name) {
ArgumentList::gen_arg_rust(arg, w, Indentation::default(), PASSES)?;
ArgumentList::gen_arg_rust(arg, w, PASSES)?;
}
}
}
@@ -205,9 +222,7 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
" }}",
" }}",
),
loaded_args = intrinsic
.arguments
.load_values_rust(Indentation::default().nest_by(4)),
loaded_args = intrinsic.arguments.load_values_rust(),
rust_args = intrinsic.arguments.as_call_param_rust(),
c_args = intrinsic.arguments.as_c_call_param_rust(),
passes = passes,
@@ -287,9 +302,8 @@ pub fn write_build_rs(
i = i
)?;
let indentation = Indentation::default().nest_by(2);
for flag in COMMON_FLAGS.iter().chain(arch_flags) {
writeln!(w, "{indentation}\"{flag}\",")?;
writeln!(w, "\"{flag}\",")?;
}
write!(
@@ -1,26 +0,0 @@
//! Basic code formatting tools.
//!
//! We don't need perfect formatting for the generated tests, but simple indentation can make
//! debugging a lot easier.
#[derive(Copy, Clone, Debug, Default)]
pub struct Indentation(u32);
impl Indentation {
pub fn nested(self) -> Self {
Self(self.0 + 1)
}
pub fn nest_by(&self, additional_levels: u32) -> Self {
Self(self.0 + additional_levels)
}
}
impl std::fmt::Display for Indentation {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for _ in 0..self.0 {
write!(f, " ")?;
}
Ok(())
}
}
@@ -5,7 +5,6 @@
use itertools::Itertools as _;
use super::indentation::Indentation;
use super::values::value_for_array;
#[derive(Debug, PartialEq, Copy, Clone)]
@@ -154,7 +153,7 @@ pub fn is_ptr(&self) -> bool {
self.ptr
}
pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
pub fn populate_random(&self, loads: u32) -> String {
match self {
IntrinsicType {
bit_len: Some(bit_len @ (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 16 | 32 | 64)),
@@ -164,9 +163,8 @@ pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
vec_len,
..
} => {
let body_indentation = indentation.nested();
format!(
"[\n{body}\n{indentation}]",
"[\n{body}\n]",
body = (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1))
.format_with(",\n", |i, fmt| {
let src = value_for_array(*bit_len, i);
@@ -177,9 +175,9 @@ pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
let mask = !0u64 >> (64 - *bit_len);
let ones_compl = src ^ mask;
let twos_compl = ones_compl + 1;
fmt(&format_args!("{body_indentation}-{twos_compl:#x}"))
fmt(&format_args!("-{twos_compl:#x}"))
} else {
fmt(&format_args!("{body_indentation}{src:#x}"))
fmt(&format_args!("{src:#x}"))
}
})
)
@@ -192,11 +190,10 @@ pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
..
} => {
format!(
"[\n{body}\n{indentation}]",
"[\n{body}\n]",
body = (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1))
.format_with(",\n", |i, fmt| fmt(&format_args!(
"{indentation}f{bit_len}::from_bits({src:#x})",
indentation = indentation.nested(),
"f{bit_len}::from_bits({src:#x})",
src = value_for_array(*bit_len, i)
)))
)
@@ -208,10 +205,9 @@ pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
vec_len,
..
} => {
let body_indentation = indentation.nested();
let effective_bit_len = 32;
format!(
"[\n{body}\n{indentation}]",
"[\n{body}\n]",
body = (0..(vec_len.unwrap_or(1) * simd_len.unwrap_or(1) + loads - 1))
.format_with(",\n", |i, fmt| {
let src = value_for_array(effective_bit_len, i);
@@ -221,9 +217,9 @@ pub fn populate_random(&self, indentation: Indentation, loads: u32) -> String {
let mask = !0u64 >> (64 - effective_bit_len);
let ones_compl = src ^ mask;
let twos_compl = ones_compl + 1;
fmt(&format_args!("{body_indentation}-{twos_compl:#x}"))
fmt(&format_args!("-{twos_compl:#x}"))
} else {
fmt(&format_args!("{body_indentation}{src:#x}"))
fmt(&format_args!("{src:#x}"))
}
})
)
@@ -6,7 +6,9 @@
use crate::common::{
gen_c::write_wrapper_c,
gen_rust::{write_bin_cargo_toml, write_build_rs, write_lib_cargo_toml, write_lib_rs},
gen_rust::{
run_rustfmt, write_bin_cargo_toml, write_build_rs, write_lib_cargo_toml, write_lib_rs,
},
intrinsic::Intrinsic,
intrinsic_helpers::IntrinsicTypeDefinition,
};
@@ -19,7 +21,6 @@
mod gen_c;
mod gen_rust;
mod indentation;
mod values;
/// Architectures must support this trait
@@ -74,7 +75,7 @@ fn generate_rust_file(&self) {
let rust_filename = format!("rust_programs/mod_{i}/src/lib.rs");
trace!("generating `{rust_filename}`");
let mut file = File::create(rust_filename)?;
let mut file = File::create(&rust_filename)?;
write_lib_rs(
&mut file,
@@ -84,6 +85,7 @@ fn generate_rust_file(&self) {
i,
chunk,
)?;
run_rustfmt(&rust_filename);
let toml_filename = format!("rust_programs/mod_{i}/Cargo.toml");
trace!("generating `{toml_filename}`");
@@ -93,9 +95,10 @@ fn generate_rust_file(&self) {
let build_rs_filename = format!("rust_programs/mod_{i}/build.rs");
trace!("generating `{build_rs_filename}`");
let mut file = File::create(build_rs_filename).unwrap();
let mut file = File::create(&build_rs_filename).unwrap();
write_build_rs(&mut file, i, &arch_flags).unwrap();
run_rustfmt(&build_rs_filename);
Ok(())
})