compiler: implement better shuffle AIR

Runtime `@shuffle` has two cases which backends generally want to handle
differently for efficiency:

* One runtime vector operand; some result elements may be comptime-known
* Two runtime vector operands; some result elements may be undefined

The latter case happens if both vectors given to `@shuffle` are
runtime-known and they are both used (i.e. the mask refers to them).
Otherwise, if the result is not entirely comptime-known, we are in the
former case. `Sema` now diffentiates these two cases in the AIR so that
backends can easily handle them however they want to. Note that this
*doesn't* really involve Sema doing any more work than it would
otherwise need to, so there's not really a negative here!

Most existing backends have their lowerings for `@shuffle` migrated in
this commit. The LLVM backend uses new lowerings suggested by Jacob as
ones which it will handle effectively. The x86_64 backend has not yet
been migrated; for now there's a panic in there. Jacob will implement
that before this is merged anywhere.
This commit is contained in:
mlugg
2025-05-26 05:07:13 +01:00
parent b48d6ff619
commit add2976a9b
18 changed files with 755 additions and 321 deletions

View File

@@ -1,14 +1,20 @@
export fn entry() void {
const v: @Vector(4, u32) = [4]u32{ 10, 11, 12, 13 };
const x: @Vector(4, u32) = [4]u32{ 14, 15, 16, 17 };
const z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
_ = z;
export fn foo() void {
// Here, the bad index ('7') is not less than 'b.len', so the error shouldn't have a note suggesting a negative index.
const a: @Vector(4, u32) = .{ 10, 11, 12, 13 };
const b: @Vector(4, u32) = .{ 14, 15, 16, 17 };
_ = @shuffle(u32, a, b, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
}
export fn bar() void {
// Here, the bad index ('7') *is* less than 'b.len', so the error *should* have a note suggesting a negative index.
const a: @Vector(4, u32) = .{ 10, 11, 12, 13 };
const b: @Vector(9, u32) = .{ 14, 15, 16, 17, 18, 19, 20, 21, 22 };
_ = @shuffle(u32, a, b, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 });
}
// error
// backend=stage2
// target=native
//
// :4:41: error: mask index '4' has out-of-bounds selection
// :4:29: note: selected index '7' out of bounds of '@Vector(4, u32)'
// :4:32: note: selections from the second vector are specified with negative numbers
// :5:35: error: mask element at index '4' selects out-of-bounds index
// :5:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here
// :11:35: error: mask element at index '4' selects out-of-bounds index
// :11:23: note: index '7' exceeds bounds of '@Vector(4, u32)' given here
// :11:26: note: use '~@as(u32, 7)' to index into second vector given here