aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-04-10 22:31:30 +0200
committerRobin Voetter <robin@voetter.nl>2023-05-11 20:31:50 +0200
commit78c44d63da14437fe0d64da92606a22d543b8169 (patch)
tree0339a270a24cfcb600ed2a22efd1b1fff2b12881 /src/codegen
parent0bae2caaf382dfb168ee404e3ffb717975f8289b (diff)
downloadzig-78c44d63da14437fe0d64da92606a22d543b8169.tar.gz
zig-78c44d63da14437fe0d64da92606a22d543b8169.zip
spirv: lower air unwrap_error_union_err
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/spirv.zig30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index d4d8ed312e..ad500af772 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -402,7 +402,7 @@ pub const DeclGen = struct {
return result_id;
}
- fn genUndef(self: *DeclGen, ty_ref: SpvType.Ref) Error!IdRef {
+ fn constUndef(self: *DeclGen, ty_ref: SpvType.Ref) Error!IdRef {
const result_id = self.spv.allocId();
try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpUndef, .{ .id_result_type = self.typeId(ty_ref), .id_result = result_id });
return result_id;
@@ -1597,7 +1597,7 @@ pub const DeclGen = struct {
.block => try self.airBlock(inst),
.load => try self.airLoad(inst),
- .store => return self.airStore(inst),
+ .store => return self.airStore(inst),
.br => return self.airBr(inst),
.breakpoint => return,
@@ -1612,6 +1612,8 @@ pub const DeclGen = struct {
.switch_br => return self.airSwitchBr(inst),
.unreach => return self.airUnreach(),
+ .unwrap_errunion_err => try self.airErrUnionErr(inst),
+
.assembly => try self.airAssembly(inst),
.call => try self.airCall(inst, .auto),
@@ -2535,6 +2537,30 @@ pub const DeclGen = struct {
return try self.extractField(payload_ty_ref, err_union_id, eu_layout.payloadFieldIndex());
}
+ fn airErrUnionErr(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 operand_id = try self.resolve(ty_op.operand);
+ const err_union_ty = self.air.typeOf(ty_op.operand);
+ const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
+
+ if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+ // No error possible, so just return undefined.
+ return try self.constUndef(err_ty_ref);
+ }
+
+ const payload_ty = err_union_ty.errorUnionPayload();
+ const eu_layout = self.errorUnionLayout(payload_ty);
+
+ if (!eu_layout.payload_has_bits) {
+ // If no payload, error union is represented by error set.
+ return operand_id;
+ }
+
+ return try self.extractField(err_ty_ref, operand_id, eu_layout.errorFieldIndex());
+ }
+
fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const target = self.getTarget();
const pl_op = self.air.instructions.items(.data)[inst].pl_op;