Skip to content

Document endian-dependent behavior, if any #393

@gnzlbg

Description

@gnzlbg

@sunfish raised the point that we should specify how portable packed SIMD vector types behave with respect to the endianness of the architecture.

The order of the elements within a vector depends on the endianness of the machine. This could not only affect the results one gets from the indexed operations (extract,store,replace) and memory load and stores, but also the results of bit casts, for example, when bit-casting i8x16toi16x8thei8s might be ordered differently inside each i16` lanes on big endian machines, affecting the results.

The weird thing is that the portable vector type tests are running on PowerPC64 and PowerPC64el and all 3000 tests currently pass. These tests are pretty generic, so maybe we are unlucky and these tests are not hitting any endianness issues.

Or maybe LLVM handles this for us already somehow? We should add a couple of tests that we expect to break in either big-endian or little-endian and see what happens.

If LLVM handles this for us, we should investigate what exactly LLVM does and document that.


If LLVM does not handle this for us, there are many ways about how to proceed:

  • make endianness machine specific: this would make the vector types not
    portable anymore, because asserts like those above would fail or pass dependin
    on endianness.

  • renumber indices: if extract, store, and replace would take compile-time
    indices, we could easily re-number them in big-endian machines to make the
    asserts in the code above pass.

but IMO we should figure out if LLVM handles this for us first before spending time thinking about any hypothetical solutions. If someone has access to real big-endian hardware, it would be nice if that person could run stdsimd tests and report if whatever tests we come up with here pass or break.


IIUC, the following asserts might pass/fail depending on endianness:

let v = i32x4::new(0, 1, 2, 3);
assert_eq!(v.extract(0), 0); // OK in LE - ERROR in BE
assert_eq!(v.extract(3), 0); // ERROR in LE - OK in BE

let x = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
let t: i16x8 = x.into_bits(); // mem::transmute 
let t_el = i16x8::new(256, 770, 1284, 1798, 2312, 2826, 3340, 3854);
assert_eq!(t, t_el); // OK LE; ERROR: BE

cc @hsivonen who is more familiar with these issues than I am

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions