aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-12-03 19:20:15 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-12-04 15:57:40 -0700
commitf2e59e41c1ea3884a50e45f54a74c29f52954b24 (patch)
treea2fb870f95ddb3427b33016c345aa4e45479a740 /src/codegen
parent6c0a1417c6edb40cfc86e546c5c853a2d19c22f0 (diff)
downloadzig-f2e59e41c1ea3884a50e45f54a74c29f52954b24.tar.gz
zig-f2e59e41c1ea3884a50e45f54a74c29f52954b24.zip
CBE: fix various regressions caught by behavior tests
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig136
1 files changed, 85 insertions, 51 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 99ecd3d32f..372e89bac7 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -4096,9 +4096,7 @@ fn lowerTry(
const is_array = lowersToArray(payload_ty, target);
try reap(f, inst, &.{operand});
const local = try f.allocLocal(inst, result_ty);
- try f.writeCValue(writer, local, .Other);
if (is_array) {
- try writer.writeAll(";\n");
try writer.writeAll("memcpy(");
try f.writeCValue(writer, local, .FunctionArgument);
try writer.writeAll(", ");
@@ -4107,6 +4105,7 @@ fn lowerTry(
try f.renderTypecast(writer, payload_ty);
try writer.writeAll("));\n");
} else {
+ try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
if (operand_is_ptr or isByRef(payload_ty)) {
try writer.writeByte('&');
@@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
return CValue{ .undef = inst_ty };
}
+ const local = try f.allocLocal(inst, inst_ty);
+ try f.writeCValue(writer, local, .Other);
+
if (opt_ty.optionalReprIsPayload()) {
// the operand is just a regular pointer, no need to do anything special.
// *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
- return operand;
+ try writer.writeAll(" = ");
+ try f.writeCValue(writer, operand, .Other);
+ } else {
+ try writer.writeAll(" = &");
+ try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
}
-
- const local = try f.allocLocal(inst, inst_ty);
- try f.writeCValue(writer, local, .Other);
- try writer.writeAll(" = &");
- try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
try writer.writeAll(";\n");
return local;
}
@@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
const opt_ty = operand_ty.elemType();
+ const inst_ty = f.air.typeOfIndex(inst);
+
if (opt_ty.optionalReprIsPayload()) {
+ if (f.liveness.isUnused(inst)) {
+ return CValue.none;
+ }
+ const local = try f.allocLocal(inst, inst_ty);
// The payload and the optional are the same value.
// Setting to non-null will be done when the payload is set.
- return operand;
- }
-
- try f.writeCValueDeref(writer, operand);
- try writer.writeAll(".is_null = ");
- try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer);
- try writer.writeAll(";\n");
+ try f.writeCValue(writer, local, .Other);
+ try writer.writeAll(" = ");
+ try f.writeCValue(writer, operand, .Other);
+ try writer.writeAll(";\n");
+ return local;
+ } else {
+ try f.writeCValueDeref(writer, operand);
+ try writer.writeAll(".is_null = ");
+ try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer);
+ try writer.writeAll(";\n");
- const inst_ty = f.air.typeOfIndex(inst);
- const local = try f.allocLocal(inst, inst_ty);
- try f.writeCValue(writer, local, .Other);
- try writer.writeAll(" = &");
- try f.writeCValueDeref(writer, operand);
+ if (f.liveness.isUnused(inst)) {
+ return CValue.none;
+ }
- try writer.writeAll(".payload;\n");
- return local;
+ const local = try f.allocLocal(inst, inst_ty);
+ try f.writeCValue(writer, local, .Other);
+ try writer.writeAll(" = &");
+ try f.writeCValueDeref(writer, operand);
+ try writer.writeAll(".payload;\n");
+ return local;
+ }
}
fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
@@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
} else struct_byval;
const local = try f.allocLocal(inst, inst_ty);
- try f.writeCValue(writer, local, .Other);
try writer.writeAll("memcpy(&");
try f.writeCValue(writer, local, .FunctionArgument);
try writer.writeAll(", &");
@@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const inst_ty = f.air.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
const operand_ty = f.air.typeOf(ty_op.operand);
+ try reap(f, inst, &.{ty_op.operand});
const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
const error_ty = error_union_ty.errorUnionSet();
const payload_ty = error_union_ty.errorUnionPayload();
- if (!payload_ty.hasRuntimeBits()) return operand;
- try reap(f, inst, &.{ty_op.operand});
-
- const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
+ const writer = f.object.writer();
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
- if (!error_ty.errorSetIsEmpty())
- if (operand_is_ptr)
- try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
+
+ if (!payload_ty.hasRuntimeBits()) {
+ try f.writeCValue(writer, operand, .Other);
+ } else {
+ if (!error_ty.errorSetIsEmpty())
+ if (operand_is_ptr)
+ try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
+ else
+ try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
else
- try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
- else
- try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
+ try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
+ }
try writer.writeAll(";\n");
return local;
}
@@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
+ try reap(f, inst, &.{ty_op.operand});
const error_union_ty = f.air.typeOfIndex(inst);
const payload_ty = error_union_ty.errorUnionPayload();
- if (!payload_ty.hasRuntimeBits()) return operand;
+ const local = try f.allocLocal(inst, error_union_ty);
- try reap(f, inst, &.{ty_op.operand});
+ if (!payload_ty.hasRuntimeBits()) {
+ try f.writeCValue(writer, local, .Other);
+ try writer.writeAll(" = ");
+ try f.writeCValue(writer, operand, .Other);
+ try writer.writeAll(";\n");
+ return local;
+ }
- const local = try f.allocLocal(inst, error_union_ty);
{
// TODO: set the payload to undefined
//try f.writeCValue(writer, local, .Other);
@@ -5754,6 +5775,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try writer.writeAll(";\n");
}
+ if (f.liveness.isUnused(inst)) {
+ try freeLocal(f, inst, local.local, 0);
+ return CValue.none;
+ }
+
return local;
}
@@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
try writeMemoryOrder(writer, extra.ordering());
try writer.writeAll(");\n");
+ if (f.liveness.isUnused(inst)) {
+ try freeLocal(f, inst, local.local, 0);
+ return CValue.none;
+ }
+
return local;
}
@@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
- try f.writeCValue(writer, local, .Other);
- try writer.writeAll(" = (");
- try f.renderTypecast(writer, inst_ty);
- try writer.writeAll(")");
switch (inst_ty.zigTypeTag()) {
.Array, .Vector => {
const elem_ty = inst_ty.childType();
- try writer.writeByte('{');
- var empty = true;
- for (resolved_elements) |element| {
- if (!empty) try writer.writeAll(", ");
- try f.writeCValue(writer, element, .Initializer);
- empty = false;
+ for (resolved_elements) |element, i| {
+ try f.writeCValue(writer, local, .Other);
+ try writer.print("[{d}] = ", .{i});
+ try f.writeCValue(writer, element, .Other);
+ try writer.writeAll(";\n");
}
if (inst_ty.sentinel()) |sentinel| {
- if (!empty) try writer.writeAll(", ");
- try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer);
- empty = false;
+ try f.writeCValue(writer, local, .Other);
+ try writer.print("[{d}] = ", .{resolved_elements.len});
+ try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
+ try writer.writeAll(";\n");
}
- if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
- try writer.writeAll("};\n");
},
.Struct => switch (inst_ty.containerLayout()) {
.Auto, .Extern => {
+ try f.writeCValue(writer, local, .Other);
+ try writer.writeAll(" = (");
+ try f.renderTypecast(writer, inst_ty);
+ try writer.writeAll(")");
try writer.writeByte('{');
var empty = true;
for (elements) |element, index| {
@@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
}
},
.Packed => {
+ try f.writeCValue(writer, local, .Other);
+ try writer.writeAll(" = (");
+ try f.renderTypecast(writer, inst_ty);
+ try writer.writeAll(")");
const int_info = inst_ty.intInfo(target);
var bit_offset_ty_pl = Type.Payload.Bits{
@@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
}
const operand = try f.resolveInst(un_op);
+ try reap(f, inst, &.{un_op});
const operand_ty = f.air.typeOf(un_op);
const writer = f.object.writer();