diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-09-19 20:09:15 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-09-23 12:36:56 -0700 |
| commit | 48ab11639ab54914043cc8011587fe3be47a0e1f (patch) | |
| tree | 3005cc7cf8bd9edf13486e3cd60d959007855f09 /src/codegen/spirv.zig | |
| parent | b845c9d5326bc83691edcb483ac44793b88afe75 (diff) | |
| download | zig-48ab11639ab54914043cc8011587fe3be47a0e1f.tar.gz zig-48ab11639ab54914043cc8011587fe3be47a0e1f.zip | |
spirv: air is_err, is_non_err
Diffstat (limited to 'src/codegen/spirv.zig')
| -rw-r--r-- | src/codegen/spirv.zig | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 9d44b8eb8f..da8fbb8556 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1736,6 +1736,8 @@ pub const DeclGen = struct { .is_null => try self.airIsNull(inst, .is_null), .is_non_null => try self.airIsNull(inst, .is_non_null), + .is_err => try self.airIsErr(inst, .is_err), + .is_non_err => try self.airIsErr(inst, .is_non_err), .optional_payload => try self.airUnwrapOptional(inst), .wrap_optional => try self.airWrapOptional(inst), @@ -3276,6 +3278,42 @@ pub const DeclGen = struct { }; } + fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + + const mod = self.module; + const un_op = self.air.instructions.items(.data)[inst].un_op; + const operand_id = try self.resolve(un_op); + const err_union_ty = self.typeOf(un_op); + + if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { + return try self.constBool(pred == .is_non_err, .direct); + } + + const payload_ty = err_union_ty.errorUnionPayload(mod); + const eu_layout = self.errorUnionLayout(payload_ty); + const bool_ty_ref = try self.resolveType(Type.bool, .direct); + const err_ty_ref = try self.resolveType(Type.anyerror, .direct); + + const error_id = if (!eu_layout.payload_has_bits) + operand_id + else + try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex()); + + const result_id = self.spv.allocId(); + const operands = .{ + .id_result_type = self.typeId(bool_ty_ref), + .id_result = result_id, + .operand_1 = error_id, + .operand_2 = try self.constInt(err_ty_ref, 0), + }; + switch (pred) { + .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands), + .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands), + } + return result_id; + } + fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; |
