authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-07-24 19:48:55+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-07-24 20:05:41+02:00
log30376a82b2c1b13047ff3b48391fcda44183e129
treec8c30217017f3003303b077230fd02a798335151
parent5d98abd5703607884844e8b8165dcc2238389c57
signature Commit is signed but in an unrecognized format.

Re-enable switch test cases and fix regressions


2 files changed, 98 insertions(+), 72 deletions(-)

src/codegen/wasm.zig+38-10
......@@ -1084,6 +1084,42 @@ pub const Context = struct {
10841084 }
10851085 }
10861086
1087 /// Returns a `Value` as a signed 32 bit value.
1088 /// It's illegale to provide a value with a type that cannot be represented
1089 /// as an integer value.
1090 fn valueAsI32(self: Context, val: Value, ty: Type) i32 {
1091 switch (ty.zigTypeTag()) {
1092 .Enum => {
1093 if (val.castTag(.enum_field_index)) |field_index| {
1094 switch (ty.tag()) {
1095 .enum_simple => return @bitCast(i32, field_index.data),
1096 .enum_full, .enum_nonexhaustive => {
1097 const enum_full = ty.cast(Type.Payload.EnumFull).?.data;
1098 if (enum_full.values.count() != 0) {
1099 const tag_val = enum_full.values.keys()[field_index.data];
1100 return self.valueAsI32(tag_val, enum_full.tag_ty);
1101 } else return @bitCast(i32, field_index.data);
1102 },
1103 else => unreachable,
1104 }
1105 } else {
1106 var int_tag_buffer: Type.Payload.Bits = undefined;
1107 const int_tag_ty = ty.intTagType(&int_tag_buffer);
1108 return self.valueAsI32(val, int_tag_ty);
1109 }
1110 },
1111 .Int => switch (ty.intInfo(self.target).signedness) {
1112 .signed => return @truncate(i32, val.toSignedInt()),
1113 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt())),
1114 },
1115 .ErrorSet => {
1116 const error_index = self.global_error_set.get(val.getError().?).?;
1117 return @bitCast(i32, error_index);
1118 },
1119 else => unreachable, // Programmer called this function for an illegal type
1120 }
1121 }
1122
10871123 fn airBlock(self: *Context, inst: Air.Inst.Index) InnerError!WValue {
10881124 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
10891125 const block_ty = try self.genBlockType(self.air.getRefType(ty_pl.ty));
......@@ -1307,15 +1343,7 @@ pub const Context = struct {
13071343
13081344 for (items) |ref, i| {
13091345 const item_val = self.air.value(ref).?;
1310 const int_val: i32 = blk: {
1311 if (target_ty.intInfo(self.target).signedness == .signed) {
1312 // safe to truncate the values as we only use them when
1313 // the target's bits is 32 or lower.
1314 break :blk @truncate(i32, item_val.toSignedInt());
1315 }
1316
1317 break :blk @bitCast(i32, @truncate(u32, item_val.toUnsignedInt()));
1318 };
1346 const int_val = self.valueAsI32(item_val, target_ty);
13191347 if (int_val < lowest) {
13201348 lowest = int_val;
13211349 }
......@@ -1334,7 +1362,7 @@ pub const Context = struct {
13341362 // When the target is an integer size larger than u32, we have no way to use the value
13351363 // as an index, therefore we also use an if/else-chain for those cases.
13361364 // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.
1337 const is_sparse = target_ty.intInfo(self.target).bits > 32 or highest - lowest > 50;
1365 const is_sparse = highest - lowest > 50 or target_ty.bitSize(self.target) > 32;
13381366
13391367 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
13401368 const has_else_body = else_body.len != 0;
test/stage2/wasm.zig+60-62
......@@ -479,68 +479,66 @@ pub fn addCases(ctx: *TestContext) !void {
479479 , "30\n");
480480 }
481481
482 // This test case is disabled until the codegen for switch is reworked
483 // to take advantage of br_table rather than a series of br_if opcodes.
484 //{
485 // var case = ctx.exe("wasm switch", wasi);
486
487 // case.addCompareOutput(
488 // \\pub export fn _start() u32 {
489 // \\ var val: u32 = 1;
490 // \\ var a: u32 = switch (val) {
491 // \\ 0, 1 => 2,
492 // \\ 2 => 3,
493 // \\ 3 => 4,
494 // \\ else => 5,
495 // \\ };
496 // \\
497 // \\ return a;
498 // \\}
499 // , "2\n");
500
501 // case.addCompareOutput(
502 // \\pub export fn _start() u32 {
503 // \\ var val: u32 = 2;
504 // \\ var a: u32 = switch (val) {
505 // \\ 0, 1 => 2,
506 // \\ 2 => 3,
507 // \\ 3 => 4,
508 // \\ else => 5,
509 // \\ };
510 // \\
511 // \\ return a;
512 // \\}
513 // , "3\n");
514
515 // case.addCompareOutput(
516 // \\pub export fn _start() u32 {
517 // \\ var val: u32 = 10;
518 // \\ var a: u32 = switch (val) {
519 // \\ 0, 1 => 2,
520 // \\ 2 => 3,
521 // \\ 3 => 4,
522 // \\ else => 5,
523 // \\ };
524 // \\
525 // \\ return a;
526 // \\}
527 // , "5\n");
528
529 // case.addCompareOutput(
530 // \\const MyEnum = enum { One, Two, Three };
531 // \\
532 // \\pub export fn _start() u32 {
533 // \\ var val: MyEnum = .Two;
534 // \\ var a: u32 = switch (val) {
535 // \\ .One => 1,
536 // \\ .Two => 2,
537 // \\ .Three => 3,
538 // \\ };
539 // \\
540 // \\ return a;
541 // \\}
542 // , "2\n");
543 //}
482 {
483 var case = ctx.exe("wasm switch", wasi);
484
485 case.addCompareOutput(
486 \\pub export fn _start() u32 {
487 \\ var val: u32 = 1;
488 \\ var a: u32 = switch (val) {
489 \\ 0, 1 => 2,
490 \\ 2 => 3,
491 \\ 3 => 4,
492 \\ else => 5,
493 \\ };
494 \\
495 \\ return a;
496 \\}
497 , "2\n");
498
499 case.addCompareOutput(
500 \\pub export fn _start() u32 {
501 \\ var val: u32 = 2;
502 \\ var a: u32 = switch (val) {
503 \\ 0, 1 => 2,
504 \\ 2 => 3,
505 \\ 3 => 4,
506 \\ else => 5,
507 \\ };
508 \\
509 \\ return a;
510 \\}
511 , "3\n");
512
513 case.addCompareOutput(
514 \\pub export fn _start() u32 {
515 \\ var val: u32 = 10;
516 \\ var a: u32 = switch (val) {
517 \\ 0, 1 => 2,
518 \\ 2 => 3,
519 \\ 3 => 4,
520 \\ else => 5,
521 \\ };
522 \\
523 \\ return a;
524 \\}
525 , "5\n");
526
527 case.addCompareOutput(
528 \\const MyEnum = enum { One, Two, Three };
529 \\
530 \\pub export fn _start() u32 {
531 \\ var val: MyEnum = .Two;
532 \\ var a: u32 = switch (val) {
533 \\ .One => 1,
534 \\ .Two => 2,
535 \\ .Three => 3,
536 \\ };
537 \\
538 \\ return a;
539 \\}
540 , "2\n");
541 }
544542
545543 {
546544 var case = ctx.exe("wasm error unions", wasi);