aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-09-19 20:26:30 +0200
committerAndrew Kelley <andrew@ziglang.org>2023-09-23 12:36:56 -0700
commit8895025688b599a7082669234d40b26001bd9ed0 (patch)
treed3e1083b5175c22fd5207338b11daff7ad5b4f21 /src/codegen/spirv.zig
parent4f215a6d2894182f90328e2aa213f92d8e479ec7 (diff)
downloadzig-8895025688b599a7082669234d40b26001bd9ed0.tar.gz
zig-8895025688b599a7082669234d40b26001bd9ed0.zip
spirv: air wrap_errunion_payload
Diffstat (limited to 'src/codegen/spirv.zig')
-rw-r--r--src/codegen/spirv.zig38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index c46be03548..aa5b56f58a 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -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);
+ }
+
+ 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.slice());
+ 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 {