Skip to content

Commit fadb2b4

Browse files
committed
cbe: prevent tautological-compare warnings in generated code
1 parent c5734ec commit fadb2b4

File tree

2 files changed

+103
-10
lines changed

2 files changed

+103
-10
lines changed

src/codegen/c.zig

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,60 @@ pub const CValue = union(enum) {
4848
payload_identifier: []const u8,
4949
/// Rendered with fmtCTypePoolString
5050
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+
}
51105
};
52106

53107
const BlockData = struct {
@@ -4219,17 +4273,23 @@ fn airCmpOp(
42194273
const writer = f.object.writer();
42204274
const local = try f.allocLocal(inst, inst_ty);
42214275
const v = try Vectorize.start(f, inst, writer, lhs_ty);
4276+
const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
42224277
try f.writeCValue(writer, local, .Other);
42234278
try v.elem(f, writer);
4224-
try writer.writeAll(" = ");
4225-
if (need_cast) try writer.writeAll("(void*)");
4226-
try f.writeCValue(writer, lhs, .Other);
4227-
try v.elem(f, writer);
4228-
try writer.writeAll(compareOperatorC(operator));
4229-
if (need_cast) try writer.writeAll("(void*)");
4230-
try f.writeCValue(writer, rhs, .Other);
4231-
try v.elem(f, writer);
4232-
try writer.writeAll(";\n");
4279+
try a.assign(f, writer);
4280+
if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
4281+
.lt, .neq, .gt => "false",
4282+
.lte, .eq, .gte => "true",
4283+
}) else {
4284+
if (need_cast) try writer.writeAll("(void*)");
4285+
try f.writeCValue(writer, lhs, .Other);
4286+
try v.elem(f, writer);
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);
42334293
try v.end(f, inst, writer);
42344294
42354295
return local;
@@ -4270,7 +4330,11 @@ fn airEquality(
42704330
try a.assign(f, writer);
42714331
42724332
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)) {
42744338
.basic, .pointer => {
42754339
try f.writeCValue(writer, lhs, .Other);
42764340
try writer.writeAll(compareOperatorC(operator));

test/behavior/fn.zig

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,3 +668,32 @@ test "address of function parameter is consistent in function addrspace" {
668668
};
669669
S.paramAddrMatch(1);
670670
}
671+
672+
test "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+
}

0 commit comments

Comments
 (0)