authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 19:20:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
logf2e59e41c1ea3884a50e45f54a74c29f52954b24
treea2fb870f95ddb3427b33016c345aa4e45479a740
parent6c0a1417c6edb40cfc86e546c5c853a2d19c22f0

CBE: fix various regressions caught by behavior tests


1 files changed, 85 insertions(+), 51 deletions(-)

src/codegen/c.zig+85-51
...@@ -4096,9 +4096,7 @@ fn lowerTry(...@@ -4096,9 +4096,7 @@ fn lowerTry(
4096 const is_array = lowersToArray(payload_ty, target);4096 const is_array = lowersToArray(payload_ty, target);
4097 try reap(f, inst, &.{operand});4097 try reap(f, inst, &.{operand});
4098 const local = try f.allocLocal(inst, result_ty);4098 const local = try f.allocLocal(inst, result_ty);
4099 try f.writeCValue(writer, local, .Other);
4100 if (is_array) {4099 if (is_array) {
4101 try writer.writeAll(";\n");
4102 try writer.writeAll("memcpy(");4100 try writer.writeAll("memcpy(");
4103 try f.writeCValue(writer, local, .FunctionArgument);4101 try f.writeCValue(writer, local, .FunctionArgument);
4104 try writer.writeAll(", ");4102 try writer.writeAll(", ");
...@@ -4107,6 +4105,7 @@ fn lowerTry(...@@ -4107,6 +4105,7 @@ fn lowerTry(
4107 try f.renderTypecast(writer, payload_ty);4105 try f.renderTypecast(writer, payload_ty);
4108 try writer.writeAll("));\n");4106 try writer.writeAll("));\n");
4109 } else {4107 } else {
4108 try f.writeCValue(writer, local, .Other);
4110 try writer.writeAll(" = ");4109 try writer.writeAll(" = ");
4111 if (operand_is_ptr or isByRef(payload_ty)) {4110 if (operand_is_ptr or isByRef(payload_ty)) {
4112 try writer.writeByte('&');4111 try writer.writeByte('&');
...@@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4849 return CValue{ .undef = inst_ty };4848 return CValue{ .undef = inst_ty };
4850 }4849 }
48514850
4851 const local = try f.allocLocal(inst, inst_ty);
4852 try f.writeCValue(writer, local, .Other);
4853
4852 if (opt_ty.optionalReprIsPayload()) {4854 if (opt_ty.optionalReprIsPayload()) {
4853 // the operand is just a regular pointer, no need to do anything special.4855 // the operand is just a regular pointer, no need to do anything special.
4854 // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C4856 // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
4855 return operand;4857 try writer.writeAll(" = ");
4858 try f.writeCValue(writer, operand, .Other);
4859 } else {
4860 try writer.writeAll(" = &");
4861 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
4856 }4862 }
4857
4858 const local = try f.allocLocal(inst, inst_ty);
4859 try f.writeCValue(writer, local, .Other);
4860 try writer.writeAll(" = &");
4861 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
4862 try writer.writeAll(";\n");4863 try writer.writeAll(";\n");
4863 return local;4864 return local;
4864}4865}
...@@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
48724873
4873 const opt_ty = operand_ty.elemType();4874 const opt_ty = operand_ty.elemType();
48744875
4876 const inst_ty = f.air.typeOfIndex(inst);
4877
4875 if (opt_ty.optionalReprIsPayload()) {4878 if (opt_ty.optionalReprIsPayload()) {
4879 if (f.liveness.isUnused(inst)) {
4880 return CValue.none;
4881 }
4882 const local = try f.allocLocal(inst, inst_ty);
4876 // The payload and the optional are the same value.4883 // The payload and the optional are the same value.
4877 // Setting to non-null will be done when the payload is set.4884 // Setting to non-null will be done when the payload is set.
4878 return operand;4885 try f.writeCValue(writer, local, .Other);
4879 }4886 try writer.writeAll(" = ");
48804887 try f.writeCValue(writer, operand, .Other);
4881 try f.writeCValueDeref(writer, operand);4888 try writer.writeAll(";\n");
4882 try writer.writeAll(".is_null = ");4889 return local;
4883 try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer);4890 } else {
4884 try writer.writeAll(";\n");4891 try f.writeCValueDeref(writer, operand);
4892 try writer.writeAll(".is_null = ");
4893 try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer);
4894 try writer.writeAll(";\n");
48854895
4886 const inst_ty = f.air.typeOfIndex(inst);4896 if (f.liveness.isUnused(inst)) {
4887 const local = try f.allocLocal(inst, inst_ty);4897 return CValue.none;
4888 try f.writeCValue(writer, local, .Other);4898 }
4889 try writer.writeAll(" = &");
4890 try f.writeCValueDeref(writer, operand);
48914899
4892 try writer.writeAll(".payload;\n");4900 const local = try f.allocLocal(inst, inst_ty);
4893 return local;4901 try f.writeCValue(writer, local, .Other);
4902 try writer.writeAll(" = &");
4903 try f.writeCValueDeref(writer, operand);
4904 try writer.writeAll(".payload;\n");
4905 return local;
4906 }
4894}4907}
48954908
4896fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {4909fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5164 } else struct_byval;5177 } else struct_byval;
51655178
5166 const local = try f.allocLocal(inst, inst_ty);5179 const local = try f.allocLocal(inst, inst_ty);
5167 try f.writeCValue(writer, local, .Other);
5168 try writer.writeAll("memcpy(&");5180 try writer.writeAll("memcpy(&");
5169 try f.writeCValue(writer, local, .FunctionArgument);5181 try f.writeCValue(writer, local, .FunctionArgument);
5170 try writer.writeAll(", &");5182 try writer.writeAll(", &");
...@@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5230 const inst_ty = f.air.typeOfIndex(inst);5242 const inst_ty = f.air.typeOfIndex(inst);
5231 const operand = try f.resolveInst(ty_op.operand);5243 const operand = try f.resolveInst(ty_op.operand);
5232 const operand_ty = f.air.typeOf(ty_op.operand);5244 const operand_ty = f.air.typeOf(ty_op.operand);
5245 try reap(f, inst, &.{ty_op.operand});
52335246
5234 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;5247 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
5235 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;5248 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5236 const error_ty = error_union_ty.errorUnionSet();5249 const error_ty = error_union_ty.errorUnionSet();
5237 const payload_ty = error_union_ty.errorUnionPayload();5250 const payload_ty = error_union_ty.errorUnionPayload();
5238 if (!payload_ty.hasRuntimeBits()) return operand;
5239 try reap(f, inst, &.{ty_op.operand});
5240
5241 const writer = f.object.writer();
5242 const local = try f.allocLocal(inst, inst_ty);5251 const local = try f.allocLocal(inst, inst_ty);
5252 const writer = f.object.writer();
5243 try f.writeCValue(writer, local, .Other);5253 try f.writeCValue(writer, local, .Other);
5244 try writer.writeAll(" = ");5254 try writer.writeAll(" = ");
5245 if (!error_ty.errorSetIsEmpty())5255
5246 if (operand_is_ptr)5256 if (!payload_ty.hasRuntimeBits()) {
5247 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })5257 try f.writeCValue(writer, operand, .Other);
5258 } else {
5259 if (!error_ty.errorSetIsEmpty())
5260 if (operand_is_ptr)
5261 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
5262 else
5263 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
5248 else5264 else
5249 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })5265 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
5250 else5266 }
5251 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
5252 try writer.writeAll(";\n");5267 try writer.writeAll(";\n");
5253 return local;5268 return local;
5254}5269}
...@@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
53455360
5346 const writer = f.object.writer();5361 const writer = f.object.writer();
5347 const operand = try f.resolveInst(ty_op.operand);5362 const operand = try f.resolveInst(ty_op.operand);
5363 try reap(f, inst, &.{ty_op.operand});
5348 const error_union_ty = f.air.typeOfIndex(inst);5364 const error_union_ty = f.air.typeOfIndex(inst);
5349 const payload_ty = error_union_ty.errorUnionPayload();5365 const payload_ty = error_union_ty.errorUnionPayload();
5350 if (!payload_ty.hasRuntimeBits()) return operand;5366 const local = try f.allocLocal(inst, error_union_ty);
53515367
5352 try reap(f, inst, &.{ty_op.operand});5368 if (!payload_ty.hasRuntimeBits()) {
5369 try f.writeCValue(writer, local, .Other);
5370 try writer.writeAll(" = ");
5371 try f.writeCValue(writer, operand, .Other);
5372 try writer.writeAll(";\n");
5373 return local;
5374 }
53535375
5354 const local = try f.allocLocal(inst, error_union_ty);
5355 {5376 {
5356 // TODO: set the payload to undefined5377 // TODO: set the payload to undefined
5357 //try f.writeCValue(writer, local, .Other);5378 //try f.writeCValue(writer, local, .Other);
...@@ -5754,6 +5775,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -5754,6 +5775,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
5754 try writer.writeAll(";\n");5775 try writer.writeAll(";\n");
5755 }5776 }
57565777
5778 if (f.liveness.isUnused(inst)) {
5779 try freeLocal(f, inst, local.local, 0);
5780 return CValue.none;
5781 }
5782
5757 return local;5783 return local;
5758}5784}
57595785
...@@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
5790 try writeMemoryOrder(writer, extra.ordering());5816 try writeMemoryOrder(writer, extra.ordering());
5791 try writer.writeAll(");\n");5817 try writer.writeAll(");\n");
57925818
5819 if (f.liveness.isUnused(inst)) {
5820 try freeLocal(f, inst, local.local, 0);
5821 return CValue.none;
5822 }
5823
5793 return local;5824 return local;
5794}5825}
57955826
...@@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
62226253
6223 const writer = f.object.writer();6254 const writer = f.object.writer();
6224 const local = try f.allocLocal(inst, inst_ty);6255 const local = try f.allocLocal(inst, inst_ty);
6225 try f.writeCValue(writer, local, .Other);
6226 try writer.writeAll(" = (");
6227 try f.renderTypecast(writer, inst_ty);
6228 try writer.writeAll(")");
6229 switch (inst_ty.zigTypeTag()) {6256 switch (inst_ty.zigTypeTag()) {
6230 .Array, .Vector => {6257 .Array, .Vector => {
6231 const elem_ty = inst_ty.childType();6258 const elem_ty = inst_ty.childType();
6232 try writer.writeByte('{');6259 for (resolved_elements) |element, i| {
6233 var empty = true;6260 try f.writeCValue(writer, local, .Other);
6234 for (resolved_elements) |element| {6261 try writer.print("[{d}] = ", .{i});
6235 if (!empty) try writer.writeAll(", ");6262 try f.writeCValue(writer, element, .Other);
6236 try f.writeCValue(writer, element, .Initializer);6263 try writer.writeAll(";\n");
6237 empty = false;
6238 }6264 }
6239 if (inst_ty.sentinel()) |sentinel| {6265 if (inst_ty.sentinel()) |sentinel| {
6240 if (!empty) try writer.writeAll(", ");6266 try f.writeCValue(writer, local, .Other);
6241 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer);6267 try writer.print("[{d}] = ", .{resolved_elements.len});
6242 empty = false;6268 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6269 try writer.writeAll(";\n");
6243 }6270 }
6244 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
6245 try writer.writeAll("};\n");
6246 },6271 },
6247 .Struct => switch (inst_ty.containerLayout()) {6272 .Struct => switch (inst_ty.containerLayout()) {
6248 .Auto, .Extern => {6273 .Auto, .Extern => {
6274 try f.writeCValue(writer, local, .Other);
6275 try writer.writeAll(" = (");
6276 try f.renderTypecast(writer, inst_ty);
6277 try writer.writeAll(")");
6249 try writer.writeByte('{');6278 try writer.writeByte('{');
6250 var empty = true;6279 var empty = true;
6251 for (elements) |element, index| {6280 for (elements) |element, index| {
...@@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6291 }6320 }
6292 },6321 },
6293 .Packed => {6322 .Packed => {
6323 try f.writeCValue(writer, local, .Other);
6324 try writer.writeAll(" = (");
6325 try f.renderTypecast(writer, inst_ty);
6326 try writer.writeAll(")");
6294 const int_info = inst_ty.intInfo(target);6327 const int_info = inst_ty.intInfo(target);
62956328
6296 var bit_offset_ty_pl = Type.Payload.Bits{6329 var bit_offset_ty_pl = Type.Payload.Bits{
...@@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
6468 }6501 }
64696502
6470 const operand = try f.resolveInst(un_op);6503 const operand = try f.resolveInst(un_op);
6504 try reap(f, inst, &.{un_op});
6471 const operand_ty = f.air.typeOf(un_op);6505 const operand_ty = f.air.typeOf(un_op);
64726506
6473 const writer = f.object.writer();6507 const writer = f.object.writer();