From 10d523f068ba0e2a0fcde1e03bc525d0be502bd0 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Thu, 19 Mar 2026 13:29:02 +0000 Subject: [PATCH] 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 --- src/Air/Legalize.zig | 2 +- test/behavior/bitcast.zig | 32 +++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig index 3c3a5d013f..3dcab20435 100644 --- 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 index 910356e360..a8f8bcb022 100644 --- 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; + if (builtin.cpu.arch.endian() == .big 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)))); + 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 {