| author | |
| committer | |
| log | 637504176bd3b9a2374fc9f7f2e759ead35ac9b5 |
| tree | e8056df2b7e94d46b8c72f9b7150479e8019f91d |
| parent | 02c49f2911674a93be7591f3d9b47bd087c0586d |
Fixes: https://codeberg.org/ziglang/zig/issues/35969
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35996
Reviewed-by: mlugg <mlugg@mlugg.co.uk>3 files changed, 40 insertions(+), 1 deletions(-)
src/Sema.zig+6-1| ... | @@ -23547,7 +23547,9 @@ fn analyzeShuffle( | ... | @@ -23547,7 +23547,9 @@ fn analyzeShuffle( |
| 23547 | // `InternPool.Index` values using the known operands. | 23547 | // `InternPool.Index` values using the known operands. |
| 23548 | for (mask_shuffle_two, mask_ip_index) |in, *out| { | 23548 | for (mask_shuffle_two, mask_ip_index) |in, *out| { |
| 23549 | const val: Value = switch (in.unwrap()) { | 23549 | const val: Value = switch (in.unwrap()) { |
| 23550 | .undef => try pt.undefValue(elem_ty), | 23550 | // Special case zero bit types: there is no undefined value for OPV elements. |
| 23551 | // Only affects the case where `!a_rt and !b_rt` since `a_coerced` and `b_coerced`'s types are also OPV for OPV elements. | ||
| 23552 | .undef => try elem_ty.onePossibleValue(pt) orelse try pt.undefValue(elem_ty), | ||
| 23551 | .a_elem => |idx| try maybe_a_val.?.elemValue(pt, idx), | 23553 | .a_elem => |idx| try maybe_a_val.?.elemValue(pt, idx), |
| 23552 | .b_elem => |idx| try maybe_b_val.?.elemValue(pt, idx), | 23554 | .b_elem => |idx| try maybe_b_val.?.elemValue(pt, idx), |
| 23553 | }; | 23555 | }; |
| ... | @@ -23596,6 +23598,9 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -23596,6 +23598,9 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 23596 | const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src); | 23598 | const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src); |
| 23597 | const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src); | 23599 | const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src); |
| 23598 | 23600 | ||
| 23601 | // special case zero bit types | ||
| 23602 | if (try vec_ty.onePossibleValue(pt)) |opv| return .fromValue(opv); | ||
| 23603 | |||
| 23599 | const maybe_pred = sema.resolveValue(pred); | 23604 | const maybe_pred = sema.resolveValue(pred); |
| 23600 | const maybe_a = sema.resolveValue(a); | 23605 | const maybe_a = sema.resolveValue(a); |
| 23601 | const maybe_b = sema.resolveValue(b); | 23606 | const maybe_b = sema.resolveValue(b); |
test/behavior/select.zig+14| ... | @@ -31,6 +31,20 @@ fn selectVectors() !void { | ... | @@ -31,6 +31,20 @@ fn selectVectors() !void { |
| 31 | _ = .{ &x, &y, &z }; | 31 | _ = .{ &x, &y, &z }; |
| 32 | const xyz = @select(f32, x, y, z); | 32 | const xyz = @select(f32, x, y, z); |
| 33 | try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 })); | 33 | try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 })); |
| 34 | |||
| 35 | var vec_u0: @Vector(4, u0) = @splat(0); | ||
| 36 | var mask_u0 = @Vector(4, bool){ true, false, true, false }; | ||
| 37 | var mask_empty = @Vector(0, i32){}; | ||
| 38 | var vec_empty = @Vector(0, i32){}; | ||
| 39 | _ = .{ &vec_u0, &mask_u0, &mask_empty, &vec_empty }; | ||
| 40 | const sel_u0 = @select(u0, mask_u0, vec_u0, vec_u0); | ||
| 41 | const sel_u0_undefined = @select(u0, mask_u0, undefined, undefined); | ||
| 42 | comptime if (sel_u0[0] != 0) unreachable; | ||
| 43 | comptime if (sel_u0_undefined[1] != 0) unreachable; | ||
| 44 | const sel_empty = @select(i32, mask_empty, vec_empty, vec_empty); | ||
| 45 | const sel_empty_undefined = @select(i32, @Vector(0, bool){}, undefined, undefined); | ||
| 46 | comptime if (@as(u0, @bitCast(sel_empty)) != 0) unreachable; | ||
| 47 | comptime if (@as(u0, @bitCast(sel_empty_undefined)) != 0) unreachable; | ||
| 34 | } | 48 | } |
| 35 | 49 | ||
| 36 | test "@select arrays" { | 50 | test "@select arrays" { |
test/behavior/shuffle.zig+20| ... | @@ -170,3 +170,23 @@ test "@shuffle bool 2" { | ... | @@ -170,3 +170,23 @@ test "@shuffle bool 2" { |
| 170 | try S.doTheTest(); | 170 | try S.doTheTest(); |
| 171 | try comptime S.doTheTest(); | 171 | try comptime S.doTheTest(); |
| 172 | } | 172 | } |
| 173 | |||
| 174 | test "@shuffle u0" { | ||
| 175 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 176 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 177 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 178 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 179 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 180 | |||
| 181 | const S = struct { | ||
| 182 | fn doTheTest() !void { | ||
| 183 | var v: @Vector(4, u0) = @splat(0); | ||
| 184 | const mask = @Vector(4, i32){ undefined, 0, -1, 3 }; | ||
| 185 | _ = .{ &v, &mask }; | ||
| 186 | const res = @shuffle(u0, v, v, mask); | ||
| 187 | comptime if (!std.mem.eql(u0, &@as([4]u0, res), &[4]u0{ 0, 0, 0, 0 })) unreachable; | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | try S.doTheTest(); | ||
| 191 | try comptime S.doTheTest(); | ||
| 192 | } |