Skip to content

proposal: do not pack SIMD vectors #18652

@Snektron

Description

@Snektron

Currently, @Vector(N, T) is packed together. For example:

export fn square() u32 {
    return @bitSizeOf(@Vector(11, u3));
}

returns 33. This seems counter intuitive to me for several reasons:

  • [N]T is not packed either.
  • I see no good reason for vectors to be packed.
  • The performance impact is highly questionable. For instance, consider
    export fn square(num: u32) u32 {
        return @reduce(.Add, @as(@Vector(11, u3), @bitCast(@as(u33, num))));
    }
    This generates an excessive amount of bit shifts

In my opinion, vectors should essentially be a bag of scalars that you want to perform the same operation on, and not provide any layout guarantees at all. This would enable compilers to lower @Vector(11, u3) to @Vector(11, u8), and omit these expensive shifts (and a whole lot of headaches).

An important edge case here are @Vector(N, bool) and @Vector(N, u1). I suspect the reason why the above are packed at all, is to provide the guarantee that those are backed by an integer (and that all operations on it are bitwise). This makes sense to me, and I don't think that we should remove that. I see three main paths forward:

  • Make only @Vector(N, bool) be guaranteed to be backed by uN, and allow @bitcasting between these.
  • Make only @Vector(N, bool) and @Vector(N, u1) be backed by uN, and allow @bitcasting between these.
  • Add no such guarantee at all (leave it up to the backend), and provide utilities (functions or built-ins) to between uN and vectors.

In all cases, I think we only need to remove the capability to bitcast between vectors and integers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    optimizationproposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions