authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-12-07 09:18:22-05:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-08 10:53:50+00:00
logbd0ace5c4e898d7b7370e0704b08c62f0b6020c5
tree4bfd4ad2000df626a11a4bb92f9dcf5bc1d9c5f7
parent03f5b967f0d0dcdcb850061613cdb0793e2d8be2
signaturelock-open Commit is signed but in an unrecognized format.

cbe: prevent tautological-compare warnings in generated code


2 files changed, 103 insertions(+), 10 deletions(-)

src/codegen/c.zig+74-10
...@@ -48,6 +48,60 @@ pub const CValue = union(enum) {...@@ -48,6 +48,60 @@ pub const CValue = union(enum) {
48 payload_identifier: []const u8,48 payload_identifier: []const u8,
49 /// Rendered with fmtCTypePoolString49 /// Rendered with fmtCTypePoolString
50 ctype_pool_string: CType.Pool.String,50 ctype_pool_string: CType.Pool.String,
51
52 fn eql(lhs: CValue, rhs: CValue) bool {
53 return switch (lhs) {
54 .none => rhs == .none,
55 .new_local, .local => |lhs_local| switch (rhs) {
56 .new_local, .local => |rhs_local| lhs_local == rhs_local,
57 else => false,
58 },
59 .local_ref => |lhs_local| switch (rhs) {
60 .local_ref => |rhs_local| lhs_local == rhs_local,
61 else => false,
62 },
63 .constant => |lhs_val| switch (rhs) {
64 .constant => |rhs_val| lhs_val.toIntern() == rhs_val.toIntern(),
65 else => false,
66 },
67 .arg => |lhs_arg_index| switch (rhs) {
68 .arg => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
69 else => false,
70 },
71 .arg_array => |lhs_arg_index| switch (rhs) {
72 .arg_array => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
73 else => false,
74 },
75 .field => |lhs_field_index| switch (rhs) {
76 .field => |rhs_field_index| lhs_field_index == rhs_field_index,
77 else => false,
78 },
79 .nav => |lhs_nav| switch (rhs) {
80 .nav => |rhs_nav| lhs_nav == rhs_nav,
81 else => false,
82 },
83 .nav_ref => |lhs_nav| switch (rhs) {
84 .nav_ref => |rhs_nav| lhs_nav == rhs_nav,
85 else => false,
86 },
87 .undef => |lhs_ty| switch (rhs) {
88 .undef => |rhs_ty| lhs_ty.toIntern() == rhs_ty.toIntern(),
89 else => false,
90 },
91 .identifier => |lhs_id| switch (rhs) {
92 .identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
93 else => false,
94 },
95 .payload_identifier => |lhs_id| switch (rhs) {
96 .payload_identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
97 else => false,
98 },
99 .ctype_pool_string => |lhs_str| switch (rhs) {
100 .ctype_pool_string => |rhs_str| lhs_str.index == rhs_str.index,
101 else => false,
102 },
103 };
104 }
51};105};
52106
53const BlockData = struct {107const BlockData = struct {
...@@ -4219,17 +4273,23 @@ fn airCmpOp(...@@ -4219,17 +4273,23 @@ fn airCmpOp(
4219 const writer = f.object.writer();4273 const writer = f.object.writer();
4220 const local = try f.allocLocal(inst, inst_ty);4274 const local = try f.allocLocal(inst, inst_ty);
4221 const v = try Vectorize.start(f, inst, writer, lhs_ty);4275 const v = try Vectorize.start(f, inst, writer, lhs_ty);
4276 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
4222 try f.writeCValue(writer, local, .Other);4277 try f.writeCValue(writer, local, .Other);
4223 try v.elem(f, writer);4278 try v.elem(f, writer);
4224 try writer.writeAll(" = ");4279 try a.assign(f, writer);
4225 if (need_cast) try writer.writeAll("(void*)");4280 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
4226 try f.writeCValue(writer, lhs, .Other);4281 .lt, .neq, .gt => "false",
4227 try v.elem(f, writer);4282 .lte, .eq, .gte => "true",
4228 try writer.writeAll(compareOperatorC(operator));4283 }) else {
4229 if (need_cast) try writer.writeAll("(void*)");4284 if (need_cast) try writer.writeAll("(void*)");
4230 try f.writeCValue(writer, rhs, .Other);4285 try f.writeCValue(writer, lhs, .Other);
4231 try v.elem(f, writer);4286 try v.elem(f, writer);
4232 try writer.writeAll(";\n");4287 try writer.writeAll(compareOperatorC(operator));
4288 if (need_cast) try writer.writeAll("(void*)");
4289 try f.writeCValue(writer, rhs, .Other);
4290 try v.elem(f, writer);
4291 }
4292 try a.end(f, writer);
4233 try v.end(f, inst, writer);4293 try v.end(f, inst, writer);
42344294
4235 return local;4295 return local;
...@@ -4270,7 +4330,11 @@ fn airEquality(...@@ -4270,7 +4330,11 @@ fn airEquality(
4270 try a.assign(f, writer);4330 try a.assign(f, writer);
42714331
4272 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);4332 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
4273 switch (operand_ctype.info(ctype_pool)) {4333 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
4334 .lt, .lte, .gte, .gt => unreachable,
4335 .neq => "false",
4336 .eq => "true",
4337 }) else switch (operand_ctype.info(ctype_pool)) {
4274 .basic, .pointer => {4338 .basic, .pointer => {
4275 try f.writeCValue(writer, lhs, .Other);4339 try f.writeCValue(writer, lhs, .Other);
4276 try writer.writeAll(compareOperatorC(operator));4340 try writer.writeAll(compareOperatorC(operator));
test/behavior/fn.zig+29
...@@ -668,3 +668,32 @@ test "address of function parameter is consistent in function addrspace" {...@@ -668,3 +668,32 @@ test "address of function parameter is consistent in function addrspace" {
668 };668 };
669 S.paramAddrMatch(1);669 S.paramAddrMatch(1);
670}670}
671
672test "function parameter self equality" {
673 const S = struct {
674 fn equal(x: u32) bool {
675 return x == x;
676 }
677 fn notEqual(x: u32) bool {
678 return x != x;
679 }
680 fn lessThan(x: u32) bool {
681 return x < x;
682 }
683 fn lessThanOrEqual(x: u32) bool {
684 return x <= x;
685 }
686 fn greaterThan(x: u32) bool {
687 return x > x;
688 }
689 fn greaterThanOrEqual(x: u32) bool {
690 return x >= x;
691 }
692 };
693 try expect(S.equal(42));
694 try expect(!S.notEqual(42));
695 try expect(!S.lessThan(42));
696 try expect(S.lessThanOrEqual(42));
697 try expect(!S.greaterThan(42));
698 try expect(S.greaterThanOrEqual(42));
699}