spirv: air wrap_errunion_payload
This commit is contained in:
committed by
Andrew Kelley
parent
4f215a6d28
commit
8895025688
@@ -1734,6 +1734,7 @@ pub const DeclGen = struct {
|
||||
.unwrap_errunion_err => try self.airErrUnionErr(inst),
|
||||
.unwrap_errunion_payload => try self.airErrUnionPayload(inst),
|
||||
.wrap_errunion_err => try self.airWrapErrUnionErr(inst),
|
||||
.wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
|
||||
|
||||
.is_null => try self.airIsNull(inst, .is_null),
|
||||
.is_non_null => try self.airIsNull(inst, .is_non_null),
|
||||
@@ -3216,20 +3217,35 @@ pub const DeclGen = struct {
|
||||
}
|
||||
|
||||
const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
|
||||
var members = std.BoundedArray(IdRef, 2){};
|
||||
const payload_id = try self.spv.constUndef(payload_ty_ref);
|
||||
if (eu_layout.error_first) {
|
||||
members.appendAssumeCapacity(operand_id);
|
||||
members.appendAssumeCapacity(payload_id);
|
||||
// TODO: ABI padding?
|
||||
} else {
|
||||
members.appendAssumeCapacity(payload_id);
|
||||
members.appendAssumeCapacity(operand_id);
|
||||
// TODO: ABI padding?
|
||||
}
|
||||
|
||||
var members: [2]IdRef = undefined;
|
||||
members[eu_layout.errorFieldIndex()] = operand_id;
|
||||
members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref);
|
||||
|
||||
const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
|
||||
return try self.constructStruct(err_union_ty_ref, members.slice());
|
||||
return try self.constructStruct(err_union_ty_ref, &members);
|
||||
}
|
||||
|
||||
fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const err_union_ty = self.typeOfIndex(inst);
|
||||
const operand_id = try self.resolve(ty_op.operand);
|
||||
const payload_ty = self.typeOf(ty_op.operand);
|
||||
const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
|
||||
const eu_layout = self.errorUnionLayout(payload_ty);
|
||||
|
||||
if (!eu_layout.payload_has_bits) {
|
||||
return try self.constInt(err_ty_ref, 0);
|
||||
}
|
||||
|
||||
var members: [2]IdRef = undefined;
|
||||
members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0);
|
||||
members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id);
|
||||
|
||||
const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
|
||||
return try self.constructStruct(err_union_ty_ref, &members);
|
||||
}
|
||||
|
||||
fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
|
||||
|
||||
@@ -30,7 +30,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
|
||||
|
||||
test "error binary operator" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const a = errBinaryOperatorG(true) catch 3;
|
||||
const b = errBinaryOperatorG(false) catch 3;
|
||||
@@ -62,14 +61,12 @@ pub fn baz() anyerror!i32 {
|
||||
|
||||
test "error wrapping" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
try expect((baz() catch unreachable) == 15);
|
||||
}
|
||||
|
||||
test "unwrap simple value from error" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const i = unwrapSimpleValueFromErrorDo() catch unreachable;
|
||||
try expect(i == 13);
|
||||
@@ -80,7 +77,6 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize {
|
||||
|
||||
test "error return in assignment" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
doErrReturnInAssignment() catch unreachable;
|
||||
}
|
||||
@@ -103,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {
|
||||
test "widen cast integer payload of error union function call" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn errorable() !u64 {
|
||||
@@ -150,7 +145,6 @@ test "implicit cast to optional to error union to return result loc" {
|
||||
}
|
||||
|
||||
test "fn returning empty error set can be passed as fn returning any error" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
entry();
|
||||
comptime entry();
|
||||
}
|
||||
@@ -243,7 +237,6 @@ fn testExplicitErrorSetCast(set1: Set1) !void {
|
||||
|
||||
test "comptime test error for empty error set" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
try testComptimeTestErrorEmptySet(1234);
|
||||
try comptime testComptimeTestErrorEmptySet(1234);
|
||||
@@ -279,7 +272,6 @@ test "inferred empty error set comptime catch" {
|
||||
}
|
||||
|
||||
test "error inference with an empty set" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
const S = struct {
|
||||
const Struct = struct {
|
||||
pub fn func() (error{})!usize {
|
||||
@@ -334,7 +326,6 @@ fn quux_1() !i32 {
|
||||
|
||||
test "error: Zero sized error set returned with value payload crash" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
_ = try foo3(0);
|
||||
_ = try comptime foo3(0);
|
||||
@@ -434,7 +425,6 @@ test "nested error union function call in optional unwrap" {
|
||||
test "return function call to error set from error union function" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn errorable() anyerror!i32 {
|
||||
@@ -670,7 +660,6 @@ test "peer type resolution of two different error unions" {
|
||||
}
|
||||
|
||||
test "coerce error set to the current inferred error set" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
const S = struct {
|
||||
fn foo() !void {
|
||||
var a = false;
|
||||
@@ -862,8 +851,6 @@ fn non_errorable() void {
|
||||
}
|
||||
|
||||
test "catch within a function that calls no errorable functions" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
non_errorable();
|
||||
}
|
||||
|
||||
@@ -895,7 +882,6 @@ test "field access of anyerror results in smaller error set" {
|
||||
test "optional error union return type" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn foo() ?anyerror!u32 {
|
||||
|
||||
Reference in New Issue
Block a user