authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-30 16:29:11+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-30 17:11:06+02:00
log11ec7109c3d882615c2d220a813100c7f193cc0a
treec1b91af2f32fc4f2de1e19414751c4489c2ea1ee
parent15cc83e27ae8a1740d9b7e2ec14044903979a832

cbe: do not memcpy identical integer types when bitcasting


2 files changed, 29 insertions(+), 15 deletions(-)

src/codegen/c.zig+29-13
...@@ -3339,6 +3339,9 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !void {...@@ -3339,6 +3339,9 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !void {
3339 const target = f.object.dg.module.getTarget();3339 const target = f.object.dg.module.getTarget();
3340 if (inst_ty.bitSize(target) > 64) {}3340 if (inst_ty.bitSize(target) > 64) {}
33413341
3342 try writer.writeByte('(');
3343 try f.renderTypecast(writer, inst_ty);
3344 try writer.writeByte(')');
3342 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');3345 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
3343 try f.writeCValue(writer, op, .Other);3346 try f.writeCValue(writer, op, .Other);
3344}3347}
...@@ -3357,15 +3360,20 @@ fn airBinOp(...@@ -3357,15 +3360,20 @@ fn airBinOp(
3357 if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat())3360 if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat())
3358 return airBinBuiltinCall(f, inst, operation, info);3361 return airBinBuiltinCall(f, inst, operation, info);
33593362
3363 const inst_ty = f.air.typeOfIndex(inst);
3360 const lhs = try f.resolveInst(bin_op.lhs);3364 const lhs = try f.resolveInst(bin_op.lhs);
3361 const rhs = try f.resolveInst(bin_op.rhs);3365 const rhs = try f.resolveInst(bin_op.rhs);
33623366
3363 const writer = f.object.writer();3367 const writer = f.object.writer();
3368 try writer.writeByte('(');
3369 try f.renderTypecast(writer, inst_ty);
3370 try writer.writeAll(")(");
3364 try f.writeCValue(writer, lhs, .Other);3371 try f.writeCValue(writer, lhs, .Other);
3365 try writer.writeByte(' ');3372 try writer.writeByte(' ');
3366 try writer.writeAll(operator);3373 try writer.writeAll(operator);
3367 try writer.writeByte(' ');3374 try writer.writeByte(' ');
3368 try f.writeCValue(writer, rhs, .Other);3375 try f.writeCValue(writer, rhs, .Other);
3376 try writer.writeByte(')');
3369}3377}
33703378
3371fn airCmpOp(3379fn airCmpOp(
...@@ -3827,32 +3835,40 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3827,32 +3835,40 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
3827}3835}
38283836
3829fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {3837fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3830 const inst_ty = f.air.typeOfIndex(inst);3838 const src_ty = f.air.typeOfIndex(inst);
3831 // No IgnoreComptime until Sema stops giving us garbage Air.3839 // No IgnoreComptime until Sema stops giving us garbage Air.
3832 // https://github.com/ziglang/zig/issues/134103840 // https://github.com/ziglang/zig/issues/13410
3833 if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBits()) return CValue.none;3841 if (f.liveness.isUnused(inst) or !src_ty.hasRuntimeBits()) return CValue.none;
38343842
3835 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3843 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3836 const operand = try f.resolveInstNoInline(ty_op.operand);3844 const operand = try f.resolveInstNoInline(ty_op.operand);
3845 const dest_ty = f.air.typeOf(ty_op.operand);
3846 const target = f.object.dg.module.getTarget();
3847
3848 if (dest_ty.isAbiInt() and src_ty.isAbiInt()) {
3849 const src_info = src_ty.intInfo(target);
3850 const dest_info = dest_ty.intInfo(target);
3851 if (std.meta.eql(src_info, dest_info)) {
3852 return operand;
3853 }
3854 }
38373855
3838 const writer = f.object.writer();3856 const writer = f.object.writer();
3839 if (inst_ty.isPtrAtRuntime() and3857 if (src_ty.isPtrAtRuntime() and dest_ty.isPtrAtRuntime()) {
3840 f.air.typeOf(ty_op.operand).isPtrAtRuntime())3858 const local = try f.allocLocal(src_ty, .Const);
3841 {
3842 const local = try f.allocLocal(inst_ty, .Const);
3843 try writer.writeAll(" = (");3859 try writer.writeAll(" = (");
3844 try f.renderTypecast(writer, inst_ty);3860 try f.renderTypecast(writer, src_ty);
3845 try writer.writeByte(')');3861 try writer.writeByte(')');
3846 try f.writeCValue(writer, operand, .Other);3862 try f.writeCValue(writer, operand, .Other);
3847 try writer.writeAll(";\n");3863 try writer.writeAll(";\n");
3848 return local;3864 return local;
3849 }3865 }
38503866
3851 const local = try f.allocLocal(inst_ty, .Mut);3867 const local = try f.allocLocal(src_ty, .Mut);
3852 try writer.writeAll(";\n");3868 try writer.writeAll(";\n");
38533869
3854 const operand_lval = if (operand == .constant) blk: {3870 const operand_lval = if (operand == .constant) blk: {
3855 const operand_local = try f.allocLocal(f.air.typeOf(ty_op.operand), .Const);3871 const operand_local = try f.allocLocal(dest_ty, .Const);
3856 try writer.writeAll(" = ");3872 try writer.writeAll(" = ");
3857 try f.writeCValue(writer, operand, .Initializer);3873 try f.writeCValue(writer, operand, .Initializer);
3858 try writer.writeAll(";\n");3874 try writer.writeAll(";\n");
...@@ -3864,17 +3880,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3864,17 +3880,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3864 try writer.writeAll(", &");3880 try writer.writeAll(", &");
3865 try f.writeCValue(writer, operand_lval, .Other);3881 try f.writeCValue(writer, operand_lval, .Other);
3866 try writer.writeAll(", sizeof(");3882 try writer.writeAll(", sizeof(");
3867 try f.renderTypecast(writer, inst_ty);3883 try f.renderTypecast(writer, src_ty);
3868 try writer.writeAll("));\n");3884 try writer.writeAll("));\n");
38693885
3870 // Ensure padding bits have the expected value.3886 // Ensure padding bits have the expected value.
3871 if (inst_ty.isAbiInt()) {3887 if (src_ty.isAbiInt()) {
3872 try f.writeCValue(writer, local, .Other);3888 try f.writeCValue(writer, local, .Other);
3873 try writer.writeAll(" = zig_wrap_");3889 try writer.writeAll(" = zig_wrap_");
3874 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);3890 try f.object.dg.renderTypeForBuiltinFnName(writer, src_ty);
3875 try writer.writeByte('(');3891 try writer.writeByte('(');
3876 try f.writeCValue(writer, local, .Other);3892 try f.writeCValue(writer, local, .Other);
3877 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);3893 try f.object.dg.renderBuiltinInfo(writer, src_ty, .Bits);
3878 try writer.writeAll(");\n");3894 try writer.writeAll(");\n");
3879 }3895 }
38803896
test/behavior/math.zig-2
...@@ -357,8 +357,6 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int...@@ -357,8 +357,6 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int
357}357}
358358
359test "binary not" {359test "binary not" {
360 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
361
362 try expect(comptime x: {360 try expect(comptime x: {
363 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;361 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
364 });362 });