Skip to content

Commit 3e47a71

Browse files
spirv: implement switch case handling for ranges and enable tests
1 parent ddd366b commit 3e47a71

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

src/codegen/spirv.zig

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6267,8 +6267,14 @@ const NavGen = struct {
62676267
var num_conditions: u32 = 0;
62686268
var it = switch_br.iterateCases();
62696269
while (it.next()) |case| {
6270-
if (case.ranges.len > 0) return self.todo("switch with ranges", .{});
62716270
num_conditions += @intCast(case.items.len);
6271+
for (case.ranges) |range| {
6272+
const start_val = (try self.air.value(range[0], pt)) orelse unreachable;
6273+
const end_val = (try self.air.value(range[1], pt)) orelse unreachable;
6274+
const start_u64 = start_val.toUnsignedInt(zcu);
6275+
const end_u64 = end_val.toUnsignedInt(zcu);
6276+
num_conditions += @intCast(end_u64 - start_u64 + 1);
6277+
}
62726278
}
62736279
break :blk num_conditions;
62746280
};
@@ -6322,6 +6328,23 @@ const NavGen = struct {
63226328
self.func.body.writeOperand(spec.LiteralContextDependentNumber, int_lit);
63236329
self.func.body.writeOperand(IdRef, label);
63246330
}
6331+
6332+
for (case.ranges) |range| {
6333+
const start_val = (try self.air.value(range[0], pt)) orelse unreachable;
6334+
const end_val = (try self.air.value(range[1], pt)) orelse unreachable;
6335+
const start_u64 = start_val.toUnsignedInt(zcu);
6336+
const end_u64 = end_val.toUnsignedInt(zcu);
6337+
6338+
for (start_u64..end_u64 + 1) |i| {
6339+
const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) {
6340+
1 => .{ .uint32 = @intCast(i) },
6341+
2 => .{ .uint64 = i },
6342+
else => unreachable,
6343+
};
6344+
self.func.body.writeOperand(spec.LiteralContextDependentNumber, int_lit);
6345+
self.func.body.writeOperand(IdRef, label);
6346+
}
6347+
}
63256348
}
63266349
}
63276350

test/behavior/switch.zig

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const maxInt = std.math.maxInt;
99

1010
test "switch with numbers" {
1111
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1312

1413
try testSwitchWithNumbers(13);
1514
}
@@ -25,7 +24,6 @@ fn testSwitchWithNumbers(x: u32) !void {
2524

2625
test "switch with all ranges" {
2726
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
28-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
2927

3028
try expect(testSwitchWithAllRanges(50, 3) == 1);
3129
try expect(testSwitchWithAllRanges(101, 0) == 2);
@@ -46,7 +44,6 @@ test "switch arbitrary int size" {
4644
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4745
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4846
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
49-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
5047
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
5148

5249
if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
@@ -61,6 +58,8 @@ test "switch arbitrary int size" {
6158
try expect(testSwitchArbInt(i64, maxInt(i64)) == 2);
6259
try expect(testSwitchArbInt(i64, -1000) == 3);
6360

61+
if (builtin.zig_backend == .stage2_spirv) return; // TODO composite integers
62+
6463
try expect(testSwitchArbInt(u128, 0) == 0);
6564
try expect(testSwitchArbInt(u128, 12) == 1);
6665
try expect(testSwitchArbInt(u128, maxInt(u128)) == 2);
@@ -216,7 +215,6 @@ test "undefined.u0" {
216215

217216
test "switch with disjoint range" {
218217
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
219-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
220218

221219
var q: u8 = 0;
222220
_ = &q;
@@ -228,8 +226,6 @@ test "switch with disjoint range" {
228226
}
229227

230228
test "switch variable for range and multiple prongs" {
231-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
232-
233229
const S = struct {
234230
fn doTheTest() !void {
235231
try doTheSwitch(16);
@@ -321,7 +317,6 @@ fn testSwitchEnumPtrCapture() !void {
321317

322318
test "switch handles all cases of number" {
323319
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
324-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
325320

326321
try testSwitchHandleAllCases();
327322
try comptime testSwitchHandleAllCases();
@@ -544,7 +539,6 @@ test "switch prongs with error set cases make a new error set type for capture v
544539

545540
test "return result loc and then switch with range implicit casted to error union" {
546541
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
547-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
548542

549543
const S = struct {
550544
fn doTheTest() !void {
@@ -764,7 +758,6 @@ test "switch capture copies its payload" {
764758

765759
test "capture of integer forwards the switch condition directly" {
766760
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
767-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
768761

769762
const S = struct {
770763
fn foo(x: u8) !void {
@@ -953,7 +946,6 @@ test "peer type resolution on switch captures ignores unused payload bits" {
953946
test "switch prong captures range" {
954947
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
955948
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
956-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
957949

958950
const S = struct {
959951
fn a(b: []u3, c: u3) void {
@@ -1016,8 +1008,6 @@ test "block error return trace index is reset between prongs" {
10161008
}
10171009

10181010
test "labeled switch with break" {
1019-
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1020-
10211011
var six: u32 = undefined;
10221012
six = 6;
10231013

0 commit comments

Comments
 (0)