authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-19 13:29:02+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-19 15:41:22+00:00
log10d523f068ba0e2a0fcde1e03bc525d0be502bd0
treeb2dafd101564a7894744d2a8b18b7561ebd8a1f9
parent10256e1b81a52b62581dfe643618aba8dfc64b9e
signaturelock-open Commit is signed but in an unrecognized format.

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

2 files changed, 29 insertions(+), 7 deletions(-)

src/Air/Legalize.zig+1-1
...@@ -1593,7 +1593,7 @@ fn scalarizeBitcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!?...@@ -1593,7 +1593,7 @@ fn scalarizeBitcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!?
1593 const index_val = loop.block.addTyOp(l, .load, .usize, index_ptr).toRef();1593 const index_val = loop.block.addTyOp(l, .load, .usize, index_ptr).toRef();
1594 const bit_offset = loop.block.addBinOp(l, .mul, index_val, .fromValue(try pt.intValue(.usize, elem_bits))).toRef();1594 const bit_offset = loop.block.addBinOp(l, .mul, index_val, .fromValue(try pt.intValue(.usize, elem_bits))).toRef();
1595 const casted_bit_offset = loop.block.addTyOp(l, .intcast, shift_ty, bit_offset).toRef();1595 const casted_bit_offset = loop.block.addTyOp(l, .intcast, shift_ty, bit_offset).toRef();
1596 const shifted_uint = loop.block.addBinOp(l, .shr, index_val, casted_bit_offset).toRef();1596 const shifted_uint = loop.block.addBinOp(l, .shr, uint_val, casted_bit_offset).toRef();
1597 const elem_uint = loop.block.addTyOp(l, .trunc, elem_uint_ty, shifted_uint).toRef();1597 const elem_uint = loop.block.addTyOp(l, .trunc, elem_uint_ty, shifted_uint).toRef();
1598 const elem_val = loop.block.addBitCast(l, elem_ty, elem_uint);1598 const elem_val = loop.block.addBitCast(l, elem_ty, elem_uint);
1599 switch (dest_ty.zigTypeTag(zcu)) {1599 switch (dest_ty.zigTypeTag(zcu)) {
test/behavior/bitcast.zig+28-6
...@@ -394,12 +394,34 @@ test "bitcast vector to integer and back" {...@@ -394,12 +394,34 @@ test "bitcast vector to integer and back" {
394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
395 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;395 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
396 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;396 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
397 if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;397 if (builtin.cpu.arch.endian() == .big and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
398398
399 const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14;399 var vec: @Vector(16, bool) = @splat(true);
400 var x: @Vector(16, bool) = @splat(true);400 vec[1] = false;
401 x[1] = false;401
402 try expect(@as(u16, @bitCast(x)) == comptime @as(u16, @bitCast(@as(@Vector(16, bool), arr))));402 const int: u16 = @bitCast(vec);
403 try expect(int == 0b1111_1111_1111_1101);
404
405 const vec_again: @Vector(16, bool) = @bitCast(int);
406 try expect(vec_again[0]);
407 try expect(!vec_again[1]);
408 try expect(vec_again[2]);
409 try expect(vec_again[3]);
410 try expect(vec_again[4]);
411 try expect(vec_again[5]);
412 try expect(vec_again[6]);
413 try expect(vec_again[7]);
414 try expect(vec_again[8]);
415 try expect(vec_again[9]);
416 try expect(vec_again[10]);
417 try expect(vec_again[11]);
418 try expect(vec_again[12]);
419 try expect(vec_again[13]);
420 try expect(vec_again[14]);
421 try expect(vec_again[15]);
422
423 const int_again: u16 = @bitCast(vec_again);
424 try expect(int_again == 0b1111_1111_1111_1101);
403}425}
404426
405fn bitCastWrapper16(x: f16) u16 {427fn bitCastWrapper16(x: f16) u16 {