Skip to content

std::simd scatter miscompilation #1439

@pnevyk

Description

@pnevyk

The example for Simd::scatter

#![feature(portable_simd)]

use std::simd::Simd;

fn main() {
    let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
    let idxs = Simd::from_array([9, 3, 0, 0]); // Note the duplicate index.
    let vals = Simd::from_array([-27, 82, -41, 124]);

    vals.scatter(&mut vec, idxs); // two logical writes means the last wins.
    assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]);
}

results in

thread 'main' panicked at src/main.rs:11:5:
assertion `left == right` failed
  left: [-1, -1, 12, -1, -1, 15, 16, 17, 18]
 right: [124, 11, 12, 82, 14, 15, 16, 17, 18]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
free(): invalid pointer
[1]    483914 IOT instruction (core dumped)  cargo run

Sort of a minimal reproducer is the following code:

#![feature(portable_simd)]

use std::simd::Simd;

fn main() {
    let mut vec: Vec<u8> = vec![0];
    let idxs = Simd::from_array([0]);
    let vals = Simd::from_array([1]);

    vals.scatter(&mut vec, idxs);
    assert_eq!(vec, vec![1]);
}

which results in

thread 'main' panicked at src/main.rs:11:5:
assertion `left == right` failed
  left: [255]
 right: [1]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

(Interestingly, the second example does not cause free(): invalid pointer error.)

Running the examples with standard LLVM backend works as expected.

$ rustc --version
rustc 1.77.0-nightly (d6d7a9386 2023-12-22)

If I can provide more information I will happily do so. I tried to get generated assembly using cargo-show-asm, but I got

error: Unknown option `-x86-asm-syntax`

Looking at the actual outputs, it seems that the problem manifests itself by scatter putting value -1 at index i and i + 1 for every (valid) i from the idxs vector.

// Only 0 and 3 indices are valid in the example.
let idxs = Simd::from_array([9, 3, 0, 0]);

//    index: 0,  1,  2,  3,  4,  5,  6,  7,  8
//   left: [-1, -1, 12, -1, -1, 15, 16, 17, 18]

I would be interested in trying to fix this bug if I get some pointers to where to start. I have some basic knowledge of compilers in general and cranelift in particular.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-core-archArea: Necessary for full core::arch supportC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions