Performing @intCast on @Vector sometimes gives wrong results

I am having the following issue with @Vector and casting:

  • if I just perform a @intCast from i32 to u8, it works, as you can see in the first test.
  • if I perform an operation on the i32 (@select) and then cast, I don’t get what I expect
const std = @import("std");

test "vector intCast(i32->u8) simple" {
    const N = 8;
    var buf: [N]u8 = undefined;

    const v_i32: @Vector(N, i32) = .{ 1, 2, 3, 4, 5, 6, 7, 8 };
    const v_u8: @Vector(N, u8) = @intCast(v_i32);

    buf[0..][0..N].* = v_u8;

    const expected = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
    try std.testing.expectEqualSlices(u8, &expected, &buf);
}

test "vector intCast(i32->u8) with @select" {
    const N = 8;
    var buf: [N]u8 = undefined;

    var v_i32: @Vector(N, i32) = .{ 1, 2, 3, 4, 5, 6, 7, 8 };
    // clamp the vector between 0-255
    // but it's already in range, so it shouldn't modify
    const zero: @Vector(N, i32) = @splat(0);
    const maxv: @Vector(N, i32) = @splat(255);
    v_i32 = @select(i32, v_i32 < zero, zero, v_i32);
    v_i32 = @select(i32, v_i32 > maxv, maxv, v_i32);

    const v_u8: @Vector(N, u8) = @intCast(v_i32);
    buf[0..][0..N].* = v_u8; // store after cast

    const expected = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
    try std.testing.expectEqualSlices(u8, &expected, &buf);

    // Expected:    { 1, 2, 3, 4, 5, 6, 7, 8 }
    // Actual v_u8: { 1, 2, 3, 4, 1, 2, 3, 4 }
}

Am I missing something or is this a bug?
I am on 0.16.0-dev.235+377a8b2a3

Its a bug in x86-64 backend. With llvm backend enabled tests pass

andrewkraevskii@pop-os:~/projects/sandbox$ zig test main.zig
slices differ. first difference occurs at index 4 (0x4)

============ expected this output: =============  len: 8 (0x8)

01 02 03 04 05 06 07 08                           ........

============= instead found this: ==============  len: 8 (0x8)

01 02 03 04 01 02 03 04                           ........

================================================

2/2 main.test.vector intCast(i32->u8) with @select...FAIL (TestExpectedEqual)
/home/andrewkraevskii/.zvm/master/lib/std/testing.zig:376:5: 0x1022885 in expectEqualSlices__anon_605 (std.zig)
    return error.TestExpectedEqual;
    ^
/home/andrewkraevskii/projects/sandbox/main.zig:32:5: 0x111a656 in test.vector intCast(i32->u8) with @select (main.zig)
    try std.testing.expectEqualSlices(u8, &expected, &buf);
    ^
1 passed; 0 skipped; 1 failed.
error: the following test command failed with exit code 1:
.zig-cache/o/01dfdbc70bbb20cb28328ac3eeca0e70/test --seed=0x60b5378c
andrewkraevskii@pop-os:~/projects/sandbox$ zig test main.zig -fllvm
All 2 tests passed.

It has some known issues related to vectors but this one seems distinct from them.

2 Likes

Thanks for confirming, I will open an issue, then.

The issue:

has been fixed: