authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-19 19:21:49+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-19 20:48:00+02:00
log27c63bf433f27b06bed92111cbc96e8574de8d11
tree33a3ffae8217196b22d5fbe9786dee7a34bfbe7b
parent89f6ff177178dba4e66680227a02de7b4068123c

stage2: implement errunion_payload_ptr_set


12 files changed, 85 insertions(+), 2 deletions(-)

src/Air.zig+4
...@@ -429,6 +429,9 @@ pub const Inst = struct {...@@ -429,6 +429,9 @@ pub const Inst = struct {
429 /// *(E!T) -> E. If the value is not an error, undefined behavior.429 /// *(E!T) -> E. If the value is not an error, undefined behavior.
430 /// Uses the `ty_op` field.430 /// Uses the `ty_op` field.
431 unwrap_errunion_err_ptr,431 unwrap_errunion_err_ptr,
432 /// *(E!T) => *T. Sets the value to non-error with an undefined payload value.
433 /// Uses the `ty_op` field.
434 errunion_payload_ptr_set,
432 /// wrap from T to E!T435 /// wrap from T to E!T
433 /// Uses the `ty_op` field.436 /// Uses the `ty_op` field.
434 wrap_errunion_payload,437 wrap_errunion_payload,
...@@ -865,6 +868,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -865,6 +868,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
865 .optional_payload,868 .optional_payload,
866 .optional_payload_ptr,869 .optional_payload_ptr,
867 .optional_payload_ptr_set,870 .optional_payload_ptr_set,
871 .errunion_payload_ptr_set,
868 .wrap_optional,872 .wrap_optional,
869 .unwrap_errunion_payload,873 .unwrap_errunion_payload,
870 .unwrap_errunion_err,874 .unwrap_errunion_err,
src/Liveness.zig+1
...@@ -293,6 +293,7 @@ fn analyzeInst(...@@ -293,6 +293,7 @@ fn analyzeInst(
293 .optional_payload,293 .optional_payload,
294 .optional_payload_ptr,294 .optional_payload_ptr,
295 .optional_payload_ptr_set,295 .optional_payload_ptr_set,
296 .errunion_payload_ptr_set,
296 .wrap_optional,297 .wrap_optional,
297 .unwrap_errunion_payload,298 .unwrap_errunion_payload,
298 .unwrap_errunion_err,299 .unwrap_errunion_err,
src/Sema.zig+7-1
...@@ -1636,7 +1636,13 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1636,7 +1636,13 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1636 return sema.fail(block, src, "TODO coerce_result_ptr wrap_errunion_err", .{});1636 return sema.fail(block, src, "TODO coerce_result_ptr wrap_errunion_err", .{});
1637 },1637 },
1638 .wrap_errunion_payload => {1638 .wrap_errunion_payload => {
1639 return sema.fail(block, src, "TODO coerce_result_ptr wrap_errunion_payload", .{});1639 const ty_op = air_datas[trash_inst].ty_op;
1640 const payload_ty = sema.getTmpAir().typeOf(ty_op.operand);
1641 const ptr_payload_ty = try Type.ptr(sema.arena, .{
1642 .pointee_type = payload_ty,
1643 .@"addrspace" = addr_space,
1644 });
1645 new_ptr = try block.addTyOp(.errunion_payload_ptr_set, ptr_payload_ty, new_ptr);
1640 },1646 },
1641 else => {1647 else => {
1642 if (std.debug.runtime_safety) {1648 if (std.debug.runtime_safety) {
src/arch/aarch64/CodeGen.zig+7
...@@ -662,6 +662,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -662,6 +662,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
662 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),662 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
663 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),663 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
664 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),664 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
665 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
665666
666 .wrap_optional => try self.airWrapOptional(inst),667 .wrap_optional => try self.airWrapOptional(inst),
667 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),668 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
...@@ -1443,6 +1444,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1443,6 +1444,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
1443 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1444 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1444}1445}
14451446
1447fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
1448 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1449 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
1450 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1451}
1452
1446fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {1453fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1447 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1454 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1448 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1455 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
src/arch/arm/CodeGen.zig+7
...@@ -646,6 +646,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -646,6 +646,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
646 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),646 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
647 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),647 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
648 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),648 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
649 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
649650
650 .wrap_optional => try self.airWrapOptional(inst),651 .wrap_optional => try self.airWrapOptional(inst),
651 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),652 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
...@@ -1128,6 +1129,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1128,6 +1129,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
1128 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1129 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1129}1130}
11301131
1132fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
1133 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1134 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
1135 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1136}
1137
1131fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {1138fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1132 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1139 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1133 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1140 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
src/arch/riscv64/CodeGen.zig+7
...@@ -633,6 +633,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -633,6 +633,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
633 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),633 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
634 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),634 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
635 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),635 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
636 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
636637
637 .wrap_optional => try self.airWrapOptional(inst),638 .wrap_optional => try self.airWrapOptional(inst),
638 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),639 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
...@@ -1065,6 +1066,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1065,6 +1066,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
1065 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1066 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1066}1067}
10671068
1069fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
1070 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1071 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
1072 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1073}
1074
1068fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {1075fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1069 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1076 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1070 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1077 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
src/arch/wasm/CodeGen.zig+1
...@@ -1725,6 +1725,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1725,6 +1725,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1725 .atomic_rmw,1725 .atomic_rmw,
1726 .tag_name,1726 .tag_name,
1727 .error_name,1727 .error_name,
1728 .errunion_payload_ptr_set,
17281729
1729 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/102481730 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248
1730 // is implemented in the frontend before implementing them here in the wasm backend.1731 // is implemented in the frontend before implementing them here in the wasm backend.
src/arch/x86_64/CodeGen.zig+10
...@@ -727,6 +727,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -727,6 +727,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
727 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),727 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
728 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),728 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
729 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),729 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
730 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
730731
731 .wrap_optional => try self.airWrapOptional(inst),732 .wrap_optional => try self.airWrapOptional(inst),
732 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),733 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
...@@ -1406,6 +1407,15 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1406,6 +1407,15 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
1406 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1407 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1407}1408}
14081409
1410fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
1411 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1412 const result: MCValue = if (self.liveness.isUnused(inst))
1413 .dead
1414 else
1415 return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
1416 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1417}
1418
1409fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {1419fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1410 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1420 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1411 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1421 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
src/codegen/c.zig+7
...@@ -1753,6 +1753,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1753,6 +1753,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1753 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),1753 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
1754 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),1754 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
1755 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),1755 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),
1756 .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst),
1756 // zig fmt: on1757 // zig fmt: on
1757 };1758 };
1758 switch (result_value) {1759 switch (result_value) {
...@@ -3164,6 +3165,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3164,6 +3165,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
3164 try writer.writeAll("};\n");3165 try writer.writeAll("};\n");
3165 return local;3166 return local;
3166}3167}
3168
3167fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {3169fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3168 if (f.liveness.isUnused(inst)) return CValue.none;3170 if (f.liveness.isUnused(inst)) return CValue.none;
31693171
...@@ -3183,6 +3185,11 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3183,6 +3185,11 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3183 return local;3185 return local;
3184}3186}
31853187
3188fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
3189 _ = inst;
3190 return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{});
3191}
3192
3186fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {3193fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
3187 if (f.liveness.isUnused(inst))3194 if (f.liveness.isUnused(inst))
3188 return CValue.none;3195 return CValue.none;
src/codegen/llvm.zig+32
...@@ -2238,6 +2238,7 @@ pub const FuncGen = struct {...@@ -2238,6 +2238,7 @@ pub const FuncGen = struct {
2238 .unwrap_errunion_payload_ptr => try self.airErrUnionPayload(inst, true),2238 .unwrap_errunion_payload_ptr => try self.airErrUnionPayload(inst, true),
2239 .unwrap_errunion_err => try self.airErrUnionErr(inst, false),2239 .unwrap_errunion_err => try self.airErrUnionErr(inst, false),
2240 .unwrap_errunion_err_ptr => try self.airErrUnionErr(inst, true),2240 .unwrap_errunion_err_ptr => try self.airErrUnionErr(inst, true),
2241 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
22412242
2242 .wrap_optional => try self.airWrapOptional(inst),2243 .wrap_optional => try self.airWrapOptional(inst),
2243 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),2244 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
...@@ -3202,6 +3203,37 @@ pub const FuncGen = struct {...@@ -3202,6 +3203,37 @@ pub const FuncGen = struct {
3202 return self.builder.buildExtractValue(operand, 0, "");3203 return self.builder.buildExtractValue(operand, 0, "");
3203 }3204 }
32043205
3206 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3207 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3208 const operand = try self.resolveInst(ty_op.operand);
3209 const error_set_ty = self.air.typeOf(ty_op.operand).childType();
3210
3211 const error_ty = error_set_ty.errorUnionSet();
3212 const payload_ty = error_set_ty.errorUnionPayload();
3213 const non_error_val = try self.dg.genTypedValue(.{ .ty = error_ty, .val = Value.zero });
3214 if (!payload_ty.hasRuntimeBits()) {
3215 // We have a pointer to a i1. We need to set it to 1 and then return the same pointer.
3216 _ = self.builder.buildStore(non_error_val, operand);
3217 return operand;
3218 }
3219 const index_type = self.context.intType(32);
3220 {
3221 // First set the non-error value.
3222 const indices: [2]*const llvm.Value = .{
3223 index_type.constNull(), // dereference the pointer
3224 index_type.constNull(), // first field is the payload
3225 };
3226 const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
3227 _ = self.builder.buildStore(non_error_val, non_null_ptr);
3228 }
3229 // Then return the payload pointer.
3230 const indices: [2]*const llvm.Value = .{
3231 index_type.constNull(), // dereference the pointer
3232 index_type.constInt(1, .False), // second field is the payload
3233 };
3234 return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
3235 }
3236
3205 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {3237 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3206 if (self.liveness.isUnused(inst)) return null;3238 if (self.liveness.isUnused(inst)) return null;
32073239
src/print_air.zig+1
...@@ -189,6 +189,7 @@ const Writer = struct {...@@ -189,6 +189,7 @@ const Writer = struct {
189 .optional_payload,189 .optional_payload,
190 .optional_payload_ptr,190 .optional_payload_ptr,
191 .optional_payload_ptr_set,191 .optional_payload_ptr_set,
192 .errunion_payload_ptr_set,
192 .wrap_optional,193 .wrap_optional,
193 .unwrap_errunion_payload,194 .unwrap_errunion_payload,
194 .unwrap_errunion_err,195 .unwrap_errunion_err,
test/behavior.zig+1-1
...@@ -118,6 +118,7 @@ test {...@@ -118,6 +118,7 @@ test {
118 _ = @import("behavior/sizeof_and_typeof.zig");118 _ = @import("behavior/sizeof_and_typeof.zig");
119 _ = @import("behavior/switch.zig");119 _ = @import("behavior/switch.zig");
120 _ = @import("behavior/widening.zig");120 _ = @import("behavior/widening.zig");
121 _ = @import("behavior/bugs/1442.zig");
121122
122 if (builtin.zig_backend == .stage1) {123 if (builtin.zig_backend == .stage1) {
123 // Tests that only pass for the stage1 backend.124 // Tests that only pass for the stage1 backend.
...@@ -134,7 +135,6 @@ test {...@@ -134,7 +135,6 @@ test {
134 _ = @import("behavior/bugs/920.zig");135 _ = @import("behavior/bugs/920.zig");
135 _ = @import("behavior/bugs/1120.zig");136 _ = @import("behavior/bugs/1120.zig");
136 _ = @import("behavior/bugs/1421.zig");137 _ = @import("behavior/bugs/1421.zig");
137 _ = @import("behavior/bugs/1442.zig");
138 _ = @import("behavior/bugs/1607.zig");138 _ = @import("behavior/bugs/1607.zig");
139 _ = @import("behavior/bugs/1851.zig");139 _ = @import("behavior/bugs/1851.zig");
140 _ = @import("behavior/bugs/2114.zig");140 _ = @import("behavior/bugs/2114.zig");