Open
Description
I tried this code, compiled on a PowerPC target with -O -Ctarget-feature=+altivec
(-O -Ctarget-feature=-vsx
is required instead if the chosen PowerPC target uses a default target CPU of pwr7
or later):
#![feature(stdarch_powerpc, powerpc_target_feature)]
#[cfg(target_arch = "powerpc64")]
use std::arch::powerpc64::{vector_float, vec_add};
#[cfg(target_arch = "powerpc")]
use std::arch::powerpc::{vector_float, vec_add};
use std::mem::transmute;
#[inline(never)]
fn print_vals(x: vector_float, i: usize, vals_i: u32) {
println!("x={x:?} i={i} vals[i]={vals_i}");
}
const ZERO: vector_float = unsafe { transmute([0, 0, 0, 0]) };
const INC: vector_float = unsafe { transmute([f32::MIN_POSITIVE / 128.0, f32::MIN_POSITIVE / 128.0, f32::MIN_POSITIVE / 128.0, f32::MIN_POSITIVE / 128.0]) };
const TARGET: u128 = unsafe { transmute([f32::MIN_POSITIVE, f32::MIN_POSITIVE, f32::MIN_POSITIVE, f32::MIN_POSITIVE]) };
#[inline(never)]
#[target_feature(enable = "altivec")]
pub unsafe fn evil(vals: &[u32; 300]) {
let mut x: vector_float = ZERO;
let mut i: usize = 0;
while unsafe { transmute::<vector_float, u128>(x) } != TARGET {
print_vals(x, i, vals[i]);
x = unsafe { vec_add(x, INC) };
x = unsafe { vec_add(x, INC) };
i += 2;
}
dbg!(unsafe { transmute::<vector_float, u128>(x) });
}
pub fn main() {
let mut vals: [u32; 300] = [0; 300];
for i in 0..300 { vals[i as usize] = i; }
unsafe { evil(&vals) };
}
#[cfg(not(target_feature = "altivec"))]
compile_error!("-Ctarget-feature=+altivec required");
#[cfg(target_feature = "vsx")]
compile_error!("-Ctarget-feature=-vsx required");
I expected to see this happen: The program does not segfault.
Instead, this happened: The program segfaults as LLVM optimisations presume that subnormals are not flushed to zero, whereas the altivec
instructions flush subnormals to zero. This only occurs when the vsx
feature is not enabled; the vsx
instructions do not flush subnormals and therefore do not have this issue.
This is the PowerPC equivalent of #129880.
Meta
rustc --version --verbose
:
rustc 1.82.0-nightly (a7399ba69 2024-08-31)
binary: rustc
commit-hash: a7399ba69d37b019677a9c47fe89ceb8dd82db2d
commit-date: 2024-08-31
host: x86_64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0
Metadata
Metadata
Assignees
Labels
Area: Floating point numbers and arithmeticCategory: This is a bug.Issue: Correct Rust code lowers to incorrect machine codeIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessTarget: PowerPC processorsMedium priorityRelevant to the compiler team, which will review and decide on the PR/issue.