commit 10d523f068ba0e2a0fcde1e03bc525d0be502bd0 (tree)
parent 10256e1b81a52b62581dfe643618aba8dfc64b9e
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date: Thu, 19 Mar 2026 13:29:02 +0000
Air.Legalize: fix typo in bitcast legalization
A typo meant that the legalization of vector `@bitCast` was literally
just not considering the operand. Oops!
We had a behavior test which should have caught this, but it wasn't
really testing the right thing, so failed to do so. I've updated it to
test what it's supposed to test, so it fails before this patch and
passes after this patch.
Resolves: https://github.com/ziglang/zig/issues/26008
Diffstat:
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig
@@ -1593,7 +1593,7 @@ fn scalarizeBitcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!?
const index_val = loop.block.addTyOp(l, .load, .usize, index_ptr).toRef();
const bit_offset = loop.block.addBinOp(l, .mul, index_val, .fromValue(try pt.intValue(.usize, elem_bits))).toRef();
const casted_bit_offset = loop.block.addTyOp(l, .intcast, shift_ty, bit_offset).toRef();
- const shifted_uint = loop.block.addBinOp(l, .shr, index_val, casted_bit_offset).toRef();
+ const shifted_uint = loop.block.addBinOp(l, .shr, uint_val, casted_bit_offset).toRef();
const elem_uint = loop.block.addTyOp(l, .trunc, elem_uint_ty, shifted_uint).toRef();
const elem_val = loop.block.addBitCast(l, elem_ty, elem_uint);
switch (dest_ty.zigTypeTag(zcu)) {
diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig
@@ -394,12 +394,34 @@ test "bitcast vector to integer and back" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
- if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
-
- const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14;
- var x: @Vector(16, bool) = @splat(true);
- x[1] = false;
- try expect(@as(u16, @bitCast(x)) == comptime @as(u16, @bitCast(@as(@Vector(16, bool), arr))));
+ if (builtin.cpu.arch.endian() == .big and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
+
+ var vec: @Vector(16, bool) = @splat(true);
+ vec[1] = false;
+
+ const int: u16 = @bitCast(vec);
+ try expect(int == 0b1111_1111_1111_1101);
+
+ const vec_again: @Vector(16, bool) = @bitCast(int);
+ try expect(vec_again[0]);
+ try expect(!vec_again[1]);
+ try expect(vec_again[2]);
+ try expect(vec_again[3]);
+ try expect(vec_again[4]);
+ try expect(vec_again[5]);
+ try expect(vec_again[6]);
+ try expect(vec_again[7]);
+ try expect(vec_again[8]);
+ try expect(vec_again[9]);
+ try expect(vec_again[10]);
+ try expect(vec_again[11]);
+ try expect(vec_again[12]);
+ try expect(vec_again[13]);
+ try expect(vec_again[14]);
+ try expect(vec_again[15]);
+
+ const int_again: u16 = @bitCast(vec_again);
+ try expect(int_again == 0b1111_1111_1111_1101);
}
fn bitCastWrapper16(x: f16) u16 {