From 3b25e7b83d808d0055c1d95f87648fd2ba4dd3a3 Mon Sep 17 00:00:00 2001 From: Khyber Sen Date: Tue, 22 Jul 2025 10:14:02 -0700 Subject: [PATCH 1/2] transpile: switch `__builtin_arm_yield` from `spin_loop` to `__yield` `__yield` is the more direct, unstable equivalent of `__builtin_arm_yield`. Fixes 1st half of . --- c2rust-transpile/src/translator/builtins.rs | 27 ++++++++++++++----- c2rust-transpile/src/translator/simd.rs | 7 +++++ .../snapshots/arch-specific/dummy2.aarch64.rs | 9 ------- .../tests/snapshots/arch-specific/dummy2.c | 0 .../snapshots/arch-specific/dummy2.x86_64.rs | 9 ------- .../snapshots/arch-specific/spin.aarch64.rs | 18 +++++++++++++ .../snapshots/{ => arch-specific}/spin.c | 0 .../{spin.rs => arch-specific/spin.x86_64.rs} | 0 ...snapshots__transpile-aarch64@dummy2.c.snap | 14 ---------- .../snapshots__transpile-aarch64@spin.c.snap | 23 ++++++++++++++++ .../snapshots__transpile-x86_64@dummy2.c.snap | 14 ---------- ...> snapshots__transpile-x86_64@spin.c.snap} | 4 +-- 12 files changed, 71 insertions(+), 54 deletions(-) delete mode 100644 c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs delete mode 100644 c2rust-transpile/tests/snapshots/arch-specific/dummy2.c delete mode 100644 c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs create mode 100644 c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs rename c2rust-transpile/tests/snapshots/{ => arch-specific}/spin.c (100%) rename c2rust-transpile/tests/snapshots/{spin.rs => arch-specific/spin.x86_64.rs} (100%) delete mode 100644 c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap create mode 100644 c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap delete mode 100644 c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap rename c2rust-transpile/tests/snapshots/{snapshots__transpile@spin.c.snap => snapshots__transpile-x86_64@spin.c.snap} (70%) diff --git a/c2rust-transpile/src/translator/builtins.rs b/c2rust-transpile/src/translator/builtins.rs index f90513b4bf..2ea281c277 100644 --- a/c2rust-transpile/src/translator/builtins.rs +++ b/c2rust-transpile/src/translator/builtins.rs @@ -380,14 +380,9 @@ impl<'c> Translation<'c> { }) } - "__builtin_ia32_pause" | "__builtin_arm_yield" => { + "__builtin_ia32_pause" => { // `spin_loop()` is implemented as `_mm_pause()` (the `pause` instruction) on `x86`/`x86_64`, // but it's the safe and cross-platform version of it, so prefer it. - // On `arm`, it's implemented as `yield`, although on `aarch64`, - // it's implemented as `isb` instead as this is more efficient. - // See . - // `core::arch::aarch64::__yield()` could be used instead, - // but it's unstable (`#![feature(stdarch_arm_hints)]`), so it's not ideal. let spin_loop = mk().abs_path_expr(vec!["core", "hint", "spin_loop"]); let call = mk().call_expr(spin_loop, vec![]); self.convert_side_effects_expr( @@ -397,6 +392,26 @@ impl<'c> Translation<'c> { ) } + "__builtin_arm_yield" => { + let fn_name = "__yield"; + self.use_feature("stdsimd"); + // TODO See #1298. + // In Rust 1.7, `#![feature(stdsimd)]` was removed and split into (at least): + // `#![feature("stdarch_arm_hints")]` and + // `#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]`. + // self.use_feature("stdarch_arm_hints"); + // self.use_feature("stdarch_arm_neon_intrinsics"); // TODO need to add `cfg_attr` support. + self.import_arch_function("arm", fn_name); + self.import_arch_function("aarch64", fn_name); + let ident = mk().ident_expr(fn_name); + let call = mk().call_expr(ident, vec![]); + self.convert_side_effects_expr( + ctx, + WithStmts::new_val(call), + "Builtin is not supposed to be used", + ) + } + // SIMD builtins: "__builtin_ia32_aeskeygenassist128" => { self.convert_simd_builtin(ctx, "_mm_aeskeygenassist_si128", args) diff --git a/c2rust-transpile/src/translator/simd.rs b/c2rust-transpile/src/translator/simd.rs index 0363b0ff66..d203bf451a 100644 --- a/c2rust-transpile/src/translator/simd.rs +++ b/c2rust-transpile/src/translator/simd.rs @@ -147,6 +147,13 @@ impl<'c> Translation<'c> { }) } + /// Import a function from [`core::arch`] with a `#[cfg(target_arch = "{arch_name})]`. + pub fn import_arch_function(&self, arch_name: &str, name: &str) { + self.with_cur_file_item_store(|item_store| { + add_arch_use(item_store, arch_name, name); + }); + } + /// Determine if a particular function name is an SIMD primitive. If so an appropriate /// use statement is generated, `true` is returned, and no further processing will need to be done. pub fn import_simd_function(&self, name: &str) -> TranslationResult { diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs deleted file mode 100644 index d5e9115dc0..0000000000 --- a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.c b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.c deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs deleted file mode 100644 index d5e9115dc0..0000000000 --- a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs b/c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs new file mode 100644 index 0000000000..439aec9679 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs @@ -0,0 +1,18 @@ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#![feature(stdsimd)] +#[cfg(target_arch = "arm")] +pub use core::arch::arm::__yield; +#[cfg(target_arch = "aarch64")] +pub use core::arch::aarch64::__yield; +#[no_mangle] +pub unsafe extern "C" fn spin() { + __yield(); +} diff --git a/c2rust-transpile/tests/snapshots/spin.c b/c2rust-transpile/tests/snapshots/arch-specific/spin.c similarity index 100% rename from c2rust-transpile/tests/snapshots/spin.c rename to c2rust-transpile/tests/snapshots/arch-specific/spin.c diff --git a/c2rust-transpile/tests/snapshots/spin.rs b/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs similarity index 100% rename from c2rust-transpile/tests/snapshots/spin.rs rename to c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap deleted file mode 100644 index 622e760b20..0000000000 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap +++ /dev/null @@ -1,14 +0,0 @@ ---- -source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/arch-specific/dummy2.aarch64.rs -input_file: c2rust-transpile/tests/snapshots/arch-specific/dummy2.c ---- -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap new file mode 100644 index 0000000000..43cf7cfef3 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap @@ -0,0 +1,23 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: cat tests/snapshots/arch-specific/spin.aarch64.rs +input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#![feature(stdsimd)] +#[cfg(target_arch = "arm")] +pub use core::arch::arm::__yield; +#[cfg(target_arch = "aarch64")] +pub use core::arch::aarch64::__yield; +#[no_mangle] +pub unsafe extern "C" fn spin() { + __yield(); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap deleted file mode 100644 index 0f13405b66..0000000000 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap +++ /dev/null @@ -1,14 +0,0 @@ ---- -source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/arch-specific/dummy2.x86_64.rs -input_file: c2rust-transpile/tests/snapshots/arch-specific/dummy2.c ---- -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap similarity index 70% rename from c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap rename to c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap index 3fcad2fc11..ea718a38ef 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap @@ -1,7 +1,7 @@ --- source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/spin.rs -input_file: c2rust-transpile/tests/snapshots/spin.c +expression: cat tests/snapshots/arch-specific/spin.x86_64.rs +input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c --- #![allow( dead_code, From a1d24cb3186d61c63e52b011111ef5b53c575a63 Mon Sep 17 00:00:00 2001 From: Khyber Sen Date: Mon, 21 Jul 2025 04:16:05 -0700 Subject: [PATCH 2/2] transpile: revert `__builtin_ia32_pause` from `spin_loop` to `_mm_pause` `_mm_pause` is the more direct, unstable equivalent of `__builtin_ia2_pause`. Fixes 2nd half of . --- c2rust-transpile/src/translator/builtins.rs | 8 ++++---- .../tests/snapshots/arch-specific/spin.x86_64.rs | 7 ++++++- .../snapshots/snapshots__transpile-x86_64@spin.c.snap | 7 ++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/c2rust-transpile/src/translator/builtins.rs b/c2rust-transpile/src/translator/builtins.rs index 2ea281c277..f13bd5f8cb 100644 --- a/c2rust-transpile/src/translator/builtins.rs +++ b/c2rust-transpile/src/translator/builtins.rs @@ -381,10 +381,10 @@ impl<'c> Translation<'c> { } "__builtin_ia32_pause" => { - // `spin_loop()` is implemented as `_mm_pause()` (the `pause` instruction) on `x86`/`x86_64`, - // but it's the safe and cross-platform version of it, so prefer it. - let spin_loop = mk().abs_path_expr(vec!["core", "hint", "spin_loop"]); - let call = mk().call_expr(spin_loop, vec![]); + let fn_name = "_mm_pause"; + self.import_simd_function(fn_name)?; + let ident = mk().ident_expr(fn_name); + let call = mk().call_expr(ident, vec![]); self.convert_side_effects_expr( ctx, WithStmts::new_val(call), diff --git a/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs b/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs index 756149372c..5174834bba 100644 --- a/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs +++ b/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs @@ -7,7 +7,12 @@ unused_assignments, unused_mut )] +#![feature(stdsimd)] +#[cfg(target_arch = "x86")] +pub use core::arch::x86::_mm_pause; +#[cfg(target_arch = "x86_64")] +pub use core::arch::x86_64::_mm_pause; #[no_mangle] pub unsafe extern "C" fn spin() { - ::core::hint::spin_loop(); + _mm_pause(); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap index ea718a38ef..3821a93e89 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap @@ -12,7 +12,12 @@ input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c unused_assignments, unused_mut )] +#![feature(stdsimd)] +#[cfg(target_arch = "x86")] +pub use core::arch::x86::_mm_pause; +#[cfg(target_arch = "x86_64")] +pub use core::arch::x86_64::_mm_pause; #[no_mangle] pub unsafe extern "C" fn spin() { - ::core::hint::spin_loop(); + _mm_pause(); }