diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-04-10 22:31:30 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-05-11 20:31:50 +0200 |
| commit | 78c44d63da14437fe0d64da92606a22d543b8169 (patch) | |
| tree | 0339a270a24cfcb600ed2a22efd1b1fff2b12881 /src/codegen | |
| parent | 0bae2caaf382dfb168ee404e3ffb717975f8289b (diff) | |
| download | zig-78c44d63da14437fe0d64da92606a22d543b8169.tar.gz zig-78c44d63da14437fe0d64da92606a22d543b8169.zip | |
spirv: lower air unwrap_error_union_err
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/spirv.zig | 30 |
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; |
