Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32-bit ARM NEON intrinsics are unsound due to subnormal flushing #129880

Open
RalfJung opened this issue Sep 2, 2024 · 1 comment
Open

32-bit ARM NEON intrinsics are unsound due to subnormal flushing #129880

RalfJung opened this issue Sep 2, 2024 · 1 comment
Labels
A-floating-point Area: Floating point numbers and arithmetic I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Sep 2, 2024

This is the ARM NEON version of #114479. Example by @beetrees, to be compiled with --target armv7-unknown-linux-gnueabihf -O -Ctarget-feature=+neon:

#![feature(stdarch_arm_neon_intrinsics)]

use std::arch::arm::{float32x2_t, vadd_f32};
use std::mem::transmute;

#[inline(never)]
fn print_vals(x: float32x2_t, i: usize, vals_i: u32) {
    println!("x={x:?} i={i} vals[i]={vals_i}");
}

const ZERO: float32x2_t = unsafe { transmute([0, 0]) };
const INC: float32x2_t = unsafe { transmute([f32::MIN_POSITIVE / 128.0, f32::MIN_POSITIVE / 128.0]) };
const TARGET: [u32; 2] = unsafe { transmute([f32::MIN_POSITIVE, f32::MIN_POSITIVE]) };

#[inline(never)]
pub fn evil(vals: &[u32; 300]) {
    let mut x: float32x2_t = ZERO;
    let mut i: usize = 0;
    while unsafe { transmute::<float32x2_t, [u32; 2]>(x) } != TARGET {
        print_vals(x, i, vals[i]);
        x = unsafe { vadd_f32(x, INC) };
        x = unsafe { vadd_f32(x, INC) };
        i += 2;
    }
}

pub fn main() {
    let mut vals: [u32; 300] = [0; 300];
    for i in 0..300 { vals[i as usize] = i; }
    evil(&vals);
}

#[cfg(not(target_feature = "neon"))]
compile_error!("-Ctarget-feature=+neon required");

LLVM's optimizations assume they can calculate what that loop does, and that it follows IEEE semantics. But LLVM's codegen produces code that does not have IEEE semantics, and instead flushes subnormals to zero. 💥

This almost surely also affects the unstable std::simd on ARM.

@RalfJung RalfJung added O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness A-floating-point Area: Floating point numbers and arithmetic labels Sep 2, 2024
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Sep 2, 2024
@RalfJung RalfJung changed the title ARM NEON intrinsics are unsound due to subnormal flushing 32-bit ARM NEON intrinsics are unsound due to subnormal flushing Sep 2, 2024
@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 2, 2024
@apiraino
Copy link
Contributor

apiraino commented Sep 3, 2024

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium

@rustbot rustbot added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Sep 3, 2024
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-floating-point Area: Floating point numbers and arithmetic I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants