authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-20 21:31:44-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-21 03:04:59-05:00
loga52dcdd3c5ebd3a1d5a0189ded830dadd253193c
tree80bd063b2e762914a87bde8a393281ce0864a06a
parent471f3c470fdeb00596ebd0d045a5b0dab737947d

CBE: fix bitwise not

Closes #13911

2 files changed, 18 insertions(+), 2 deletions(-)

src/codegen/c.zig+5-2
...@@ -3591,6 +3591,10 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3591,6 +3591,10 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3591}3591}
35923592
3593fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3593fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3594 const inst_ty = f.air.typeOfIndex(inst);
3595 if (inst_ty.tag() != .bool)
3596 return try airUnBuiltinCall(f, inst, "not", .Bits);
3597
3594 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3598 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
35953599
3596 if (f.liveness.isUnused(inst)) {3600 if (f.liveness.isUnused(inst)) {
...@@ -3602,11 +3606,10 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3602,11 +3606,10 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3602 try reap(f, inst, &.{ty_op.operand});3606 try reap(f, inst, &.{ty_op.operand});
36033607
3604 const writer = f.object.writer();3608 const writer = f.object.writer();
3605 const inst_ty = f.air.typeOfIndex(inst);
3606 const local = try f.allocLocal(inst, inst_ty);3609 const local = try f.allocLocal(inst, inst_ty);
3607 try f.writeCValue(writer, local, .Other);3610 try f.writeCValue(writer, local, .Other);
3608 try writer.writeAll(" = ");3611 try writer.writeAll(" = ");
3609 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');3612 try writer.writeByte('!');
3610 try f.writeCValue(writer, op, .Other);3613 try f.writeCValue(writer, op, .Other);
3611 try writer.writeAll(";\n");3614 try writer.writeAll(";\n");
36123615
test/behavior/math.zig+13
...@@ -532,6 +532,19 @@ fn testUnsignedNegationWrappingEval(x: u16) !void {...@@ -532,6 +532,19 @@ fn testUnsignedNegationWrappingEval(x: u16) !void {
532 try expect(neg == maxInt(u16));532 try expect(neg == maxInt(u16));
533}533}
534534
535test "negation wrapping" {
536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
538
539 try expectEqual(@as(u1, 1), negateWrap(u1, 1));
540}
541
542fn negateWrap(comptime T: type, x: T) T {
543 // This is specifically testing a safety-checked add, so
544 // special case minInt(T) which would overflow otherwise.
545 return if (x == minInt(T)) minInt(T) else ~x + 1;
546}
547
535test "unsigned 64-bit division" {548test "unsigned 64-bit division" {
536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO549 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO550 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO