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 {
429429 /// *(E!T) -> E. If the value is not an error, undefined behavior.
430430 /// Uses the `ty_op` field.
431431 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,
432435 /// wrap from T to E!T
433436 /// Uses the `ty_op` field.
434437 wrap_errunion_payload,
......@@ -865,6 +868,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
865868 .optional_payload,
866869 .optional_payload_ptr,
867870 .optional_payload_ptr_set,
871 .errunion_payload_ptr_set,
868872 .wrap_optional,
869873 .unwrap_errunion_payload,
870874 .unwrap_errunion_err,
src/Liveness.zig+1
......@@ -293,6 +293,7 @@ fn analyzeInst(
293293 .optional_payload,
294294 .optional_payload_ptr,
295295 .optional_payload_ptr_set,
296 .errunion_payload_ptr_set,
296297 .wrap_optional,
297298 .unwrap_errunion_payload,
298299 .unwrap_errunion_err,
src/Sema.zig+7-1
......@@ -1636,7 +1636,13 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
16361636 return sema.fail(block, src, "TODO coerce_result_ptr wrap_errunion_err", .{});
16371637 },
16381638 .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);
16401646 },
16411647 else => {
16421648 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 {
662662 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
663663 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
664664 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
665 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
665666
666667 .wrap_optional => try self.airWrapOptional(inst),
667668 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
......@@ -1443,6 +1444,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
14431444 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14441445}
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
14461453fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
14471454 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
14481455 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 {
646646 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
647647 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
648648 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
649 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
649650
650651 .wrap_optional => try self.airWrapOptional(inst),
651652 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
......@@ -1128,6 +1129,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
11281129 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
11291130}
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
11311138fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
11321139 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
11331140 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 {
633633 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
634634 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
635635 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
636 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
636637
637638 .wrap_optional => try self.airWrapOptional(inst),
638639 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
......@@ -1065,6 +1066,12 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
10651066 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
10661067}
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
10681075fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
10691076 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
10701077 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 {
17251725 .atomic_rmw,
17261726 .tag_name,
17271727 .error_name,
1728 .errunion_payload_ptr_set,
17281729
17291730 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248
17301731 // 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 {
727727 .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst),
728728 .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst),
729729 .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst),
730 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
730731
731732 .wrap_optional => try self.airWrapOptional(inst),
732733 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
......@@ -1406,6 +1407,15 @@ fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
14061407 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14071408}
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
14091419fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
14101420 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
14111421 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
17531753 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
17541754 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
17551755 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),
1756 .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst),
17561757 // zig fmt: on
17571758 };
17581759 switch (result_value) {
......@@ -3164,6 +3165,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
31643165 try writer.writeAll("};\n");
31653166 return local;
31663167}
3168
31673169fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
31683170 if (f.liveness.isUnused(inst)) return CValue.none;
31693171
......@@ -3183,6 +3185,11 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
31833185 return local;
31843186}
31853187
3188fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
3189 _ = inst;
3190 return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{});
3191}
3192
31863193fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
31873194 if (f.liveness.isUnused(inst))
31883195 return CValue.none;
src/codegen/llvm.zig+32
......@@ -2238,6 +2238,7 @@ pub const FuncGen = struct {
22382238 .unwrap_errunion_payload_ptr => try self.airErrUnionPayload(inst, true),
22392239 .unwrap_errunion_err => try self.airErrUnionErr(inst, false),
22402240 .unwrap_errunion_err_ptr => try self.airErrUnionErr(inst, true),
2241 .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst),
22412242
22422243 .wrap_optional => try self.airWrapOptional(inst),
22432244 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
......@@ -3202,6 +3203,37 @@ pub const FuncGen = struct {
32023203 return self.builder.buildExtractValue(operand, 0, "");
32033204 }
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
32053237 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
32063238 if (self.liveness.isUnused(inst)) return null;
32073239
src/print_air.zig+1
......@@ -189,6 +189,7 @@ const Writer = struct {
189189 .optional_payload,
190190 .optional_payload_ptr,
191191 .optional_payload_ptr_set,
192 .errunion_payload_ptr_set,
192193 .wrap_optional,
193194 .unwrap_errunion_payload,
194195 .unwrap_errunion_err,
test/behavior.zig+1-1
......@@ -118,6 +118,7 @@ test {
118118 _ = @import("behavior/sizeof_and_typeof.zig");
119119 _ = @import("behavior/switch.zig");
120120 _ = @import("behavior/widening.zig");
121 _ = @import("behavior/bugs/1442.zig");
121122
122123 if (builtin.zig_backend == .stage1) {
123124 // Tests that only pass for the stage1 backend.
......@@ -134,7 +135,6 @@ test {
134135 _ = @import("behavior/bugs/920.zig");
135136 _ = @import("behavior/bugs/1120.zig");
136137 _ = @import("behavior/bugs/1421.zig");
137 _ = @import("behavior/bugs/1442.zig");
138138 _ = @import("behavior/bugs/1607.zig");
139139 _ = @import("behavior/bugs/1851.zig");
140140 _ = @import("behavior/bugs/2114.zig");