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 {
33393339 const target = f.object.dg.module.getTarget();
33403340 if (inst_ty.bitSize(target) > 64) {}
33413341
3342 try writer.writeByte('(');
3343 try f.renderTypecast(writer, inst_ty);
3344 try writer.writeByte(')');
33423345 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
33433346 try f.writeCValue(writer, op, .Other);
33443347}
......@@ -3357,15 +3360,20 @@ fn airBinOp(
33573360 if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat())
33583361 return airBinBuiltinCall(f, inst, operation, info);
33593362
3363 const inst_ty = f.air.typeOfIndex(inst);
33603364 const lhs = try f.resolveInst(bin_op.lhs);
33613365 const rhs = try f.resolveInst(bin_op.rhs);
33623366
33633367 const writer = f.object.writer();
3368 try writer.writeByte('(');
3369 try f.renderTypecast(writer, inst_ty);
3370 try writer.writeAll(")(");
33643371 try f.writeCValue(writer, lhs, .Other);
33653372 try writer.writeByte(' ');
33663373 try writer.writeAll(operator);
33673374 try writer.writeByte(' ');
33683375 try f.writeCValue(writer, rhs, .Other);
3376 try writer.writeByte(')');
33693377}
33703378
33713379fn airCmpOp(
......@@ -3827,32 +3835,40 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
38273835}
38283836
38293837fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3830 const inst_ty = f.air.typeOfIndex(inst);
3838 const src_ty = f.air.typeOfIndex(inst);
38313839 // No IgnoreComptime until Sema stops giving us garbage Air.
38323840 // 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
38353843 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
38363844 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
38383856 const writer = f.object.writer();
3839 if (inst_ty.isPtrAtRuntime() and
3840 f.air.typeOf(ty_op.operand).isPtrAtRuntime())
3841 {
3842 const local = try f.allocLocal(inst_ty, .Const);
3857 if (src_ty.isPtrAtRuntime() and dest_ty.isPtrAtRuntime()) {
3858 const local = try f.allocLocal(src_ty, .Const);
38433859 try writer.writeAll(" = (");
3844 try f.renderTypecast(writer, inst_ty);
3860 try f.renderTypecast(writer, src_ty);
38453861 try writer.writeByte(')');
38463862 try f.writeCValue(writer, operand, .Other);
38473863 try writer.writeAll(";\n");
38483864 return local;
38493865 }
38503866
3851 const local = try f.allocLocal(inst_ty, .Mut);
3867 const local = try f.allocLocal(src_ty, .Mut);
38523868 try writer.writeAll(";\n");
38533869
38543870 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);
38563872 try writer.writeAll(" = ");
38573873 try f.writeCValue(writer, operand, .Initializer);
38583874 try writer.writeAll(";\n");
......@@ -3864,17 +3880,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
38643880 try writer.writeAll(", &");
38653881 try f.writeCValue(writer, operand_lval, .Other);
38663882 try writer.writeAll(", sizeof(");
3867 try f.renderTypecast(writer, inst_ty);
3883 try f.renderTypecast(writer, src_ty);
38683884 try writer.writeAll("));\n");
38693885
38703886 // Ensure padding bits have the expected value.
3871 if (inst_ty.isAbiInt()) {
3887 if (src_ty.isAbiInt()) {
38723888 try f.writeCValue(writer, local, .Other);
38733889 try writer.writeAll(" = zig_wrap_");
3874 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
3890 try f.object.dg.renderTypeForBuiltinFnName(writer, src_ty);
38753891 try writer.writeByte('(');
38763892 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);
38783894 try writer.writeAll(");\n");
38793895 }
38803896
test/behavior/math.zig-2
......@@ -357,8 +357,6 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int
357357}
358358
359359test "binary not" {
360 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
361
362360 try expect(comptime x: {
363361 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
364362 });