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!?
15931593 const index_val = loop.block.addTyOp(l, .load, .usize, index_ptr).toRef();
15941594 const bit_offset = loop.block.addBinOp(l, .mul, index_val, .fromValue(try pt.intValue(.usize, elem_bits))).toRef();
15951595 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();
15971597 const elem_uint = loop.block.addTyOp(l, .trunc, elem_uint_ty, shifted_uint).toRef();
15981598 const elem_val = loop.block.addBitCast(l, elem_ty, elem_uint);
15991599 switch (dest_ty.zigTypeTag(zcu)) {
test/behavior/bitcast.zig+28-6
......@@ -394,12 +394,34 @@ test "bitcast vector to integer and back" {
394394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
395395 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
396396 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;
398
399 const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14;
400 var x: @Vector(16, bool) = @splat(true);
401 x[1] = false;
402 try expect(@as(u16, @bitCast(x)) == comptime @as(u16, @bitCast(@as(@Vector(16, bool), arr))));
397 if (builtin.cpu.arch.endian() == .big and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
398
399 var vec: @Vector(16, bool) = @splat(true);
400 vec[1] = false;
401
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);
403425}
404426
405427fn bitCastWrapper16(x: f16) u16 {