authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-09-19 20:26:30+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-23 12:36:56-07:00
log8895025688b599a7082669234d40b26001bd9ed0
treed3e1083b5175c22fd5207338b11daff7ad5b4f21
parent4f215a6d2894182f90328e2aa213f92d8e479ec7

spirv: air wrap_errunion_payload


2 files changed, 27 insertions(+), 25 deletions(-)

src/codegen/spirv.zig+27-11
......@@ -1734,6 +1734,7 @@ pub const DeclGen = struct {
17341734 .unwrap_errunion_err => try self.airErrUnionErr(inst),
17351735 .unwrap_errunion_payload => try self.airErrUnionPayload(inst),
17361736 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
1737 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
17371738
17381739 .is_null => try self.airIsNull(inst, .is_null),
17391740 .is_non_null => try self.airIsNull(inst, .is_non_null),
......@@ -3216,20 +3217,35 @@ pub const DeclGen = struct {
32163217 }
32173218
32183219 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
3219 var members = std.BoundedArray(IdRef, 2){};
3220 const payload_id = try self.spv.constUndef(payload_ty_ref);
3221 if (eu_layout.error_first) {
3222 members.appendAssumeCapacity(operand_id);
3223 members.appendAssumeCapacity(payload_id);
3224 // TODO: ABI padding?
3225 } else {
3226 members.appendAssumeCapacity(payload_id);
3227 members.appendAssumeCapacity(operand_id);
3228 // TODO: ABI padding?
3220
3221 var members: [2]IdRef = undefined;
3222 members[eu_layout.errorFieldIndex()] = operand_id;
3223 members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref);
3224
3225 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
3226 return try self.constructStruct(err_union_ty_ref, &members);
3227 }
3228
3229 fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3230 if (self.liveness.isUnused(inst)) return null;
3231
3232 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3233 const err_union_ty = self.typeOfIndex(inst);
3234 const operand_id = try self.resolve(ty_op.operand);
3235 const payload_ty = self.typeOf(ty_op.operand);
3236 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
3237 const eu_layout = self.errorUnionLayout(payload_ty);
3238
3239 if (!eu_layout.payload_has_bits) {
3240 return try self.constInt(err_ty_ref, 0);
32293241 }
32303242
3243 var members: [2]IdRef = undefined;
3244 members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0);
3245 members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id);
3246
32313247 const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
3232 return try self.constructStruct(err_union_ty_ref, members.slice());
3248 return try self.constructStruct(err_union_ty_ref, &members);
32333249 }
32343250
32353251 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
test/behavior/error.zig-14
......@@ -30,7 +30,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
3030
3131test "error binary operator" {
3232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3433
3534 const a = errBinaryOperatorG(true) catch 3;
3635 const b = errBinaryOperatorG(false) catch 3;
......@@ -62,14 +61,12 @@ pub fn baz() anyerror!i32 {
6261
6362test "error wrapping" {
6463 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
65 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6664
6765 try expect((baz() catch unreachable) == 15);
6866}
6967
7068test "unwrap simple value from error" {
7169 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7370
7471 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
7572 try expect(i == 13);
......@@ -80,7 +77,6 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize {
8077
8178test "error return in assignment" {
8279 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
83 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8480
8581 doErrReturnInAssignment() catch unreachable;
8682}
......@@ -103,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {
10399test "widen cast integer payload of error union function call" {
104100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
105101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
107102
108103 const S = struct {
109104 fn errorable() !u64 {
......@@ -150,7 +145,6 @@ test "implicit cast to optional to error union to return result loc" {
150145}
151146
152147test "fn returning empty error set can be passed as fn returning any error" {
153 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
154148 entry();
155149 comptime entry();
156150}
......@@ -243,7 +237,6 @@ fn testExplicitErrorSetCast(set1: Set1) !void {
243237
244238test "comptime test error for empty error set" {
245239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
246 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
247240
248241 try testComptimeTestErrorEmptySet(1234);
249242 try comptime testComptimeTestErrorEmptySet(1234);
......@@ -279,7 +272,6 @@ test "inferred empty error set comptime catch" {
279272}
280273
281274test "error inference with an empty set" {
282 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
283275 const S = struct {
284276 const Struct = struct {
285277 pub fn func() (error{})!usize {
......@@ -334,7 +326,6 @@ fn quux_1() !i32 {
334326
335327test "error: Zero sized error set returned with value payload crash" {
336328 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
337 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
338329
339330 _ = try foo3(0);
340331 _ = try comptime foo3(0);
......@@ -434,7 +425,6 @@ test "nested error union function call in optional unwrap" {
434425test "return function call to error set from error union function" {
435426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
436427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
437 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
438428
439429 const S = struct {
440430 fn errorable() anyerror!i32 {
......@@ -670,7 +660,6 @@ test "peer type resolution of two different error unions" {
670660}
671661
672662test "coerce error set to the current inferred error set" {
673 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
674663 const S = struct {
675664 fn foo() !void {
676665 var a = false;
......@@ -862,8 +851,6 @@ fn non_errorable() void {
862851}
863852
864853test "catch within a function that calls no errorable functions" {
865 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
866
867854 non_errorable();
868855}
869856
......@@ -895,7 +882,6 @@ test "field access of anyerror results in smaller error set" {
895882test "optional error union return type" {
896883 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
897884 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
898 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
899885
900886 const S = struct {
901887 fn foo() ?anyerror!u32 {