cbe: prevent tautological-compare warnings in generated code

This commit is contained in:
Jacob Young 2024-12-07 09:18:22 -05:00 committed by mlugg
parent 03f5b967f0
commit bd0ace5c4e
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
2 changed files with 103 additions and 10 deletions

View File

@ -48,6 +48,60 @@ pub const CValue = union(enum) {
payload_identifier: []const u8,
/// Rendered with fmtCTypePoolString
ctype_pool_string: CType.Pool.String,
fn eql(lhs: CValue, rhs: CValue) bool {
return switch (lhs) {
.none => rhs == .none,
.new_local, .local => |lhs_local| switch (rhs) {
.new_local, .local => |rhs_local| lhs_local == rhs_local,
else => false,
},
.local_ref => |lhs_local| switch (rhs) {
.local_ref => |rhs_local| lhs_local == rhs_local,
else => false,
},
.constant => |lhs_val| switch (rhs) {
.constant => |rhs_val| lhs_val.toIntern() == rhs_val.toIntern(),
else => false,
},
.arg => |lhs_arg_index| switch (rhs) {
.arg => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
else => false,
},
.arg_array => |lhs_arg_index| switch (rhs) {
.arg_array => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
else => false,
},
.field => |lhs_field_index| switch (rhs) {
.field => |rhs_field_index| lhs_field_index == rhs_field_index,
else => false,
},
.nav => |lhs_nav| switch (rhs) {
.nav => |rhs_nav| lhs_nav == rhs_nav,
else => false,
},
.nav_ref => |lhs_nav| switch (rhs) {
.nav_ref => |rhs_nav| lhs_nav == rhs_nav,
else => false,
},
.undef => |lhs_ty| switch (rhs) {
.undef => |rhs_ty| lhs_ty.toIntern() == rhs_ty.toIntern(),
else => false,
},
.identifier => |lhs_id| switch (rhs) {
.identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
else => false,
},
.payload_identifier => |lhs_id| switch (rhs) {
.payload_identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
else => false,
},
.ctype_pool_string => |lhs_str| switch (rhs) {
.ctype_pool_string => |rhs_str| lhs_str.index == rhs_str.index,
else => false,
},
};
}
};
const BlockData = struct {
@ -4219,17 +4273,23 @@ fn airCmpOp(
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
const v = try Vectorize.start(f, inst, writer, lhs_ty);
const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
try writer.writeAll(" = ");
if (need_cast) try writer.writeAll("(void*)");
try f.writeCValue(writer, lhs, .Other);
try v.elem(f, writer);
try writer.writeAll(compareOperatorC(operator));
if (need_cast) try writer.writeAll("(void*)");
try f.writeCValue(writer, rhs, .Other);
try v.elem(f, writer);
try writer.writeAll(";\n");
try a.assign(f, writer);
if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
.lt, .neq, .gt => "false",
.lte, .eq, .gte => "true",
}) else {
if (need_cast) try writer.writeAll("(void*)");
try f.writeCValue(writer, lhs, .Other);
try v.elem(f, writer);
try writer.writeAll(compareOperatorC(operator));
if (need_cast) try writer.writeAll("(void*)");
try f.writeCValue(writer, rhs, .Other);
try v.elem(f, writer);
}
try a.end(f, writer);
try v.end(f, inst, writer);
return local;
@ -4270,7 +4330,11 @@ fn airEquality(
try a.assign(f, writer);
const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
switch (operand_ctype.info(ctype_pool)) {
if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
.lt, .lte, .gte, .gt => unreachable,
.neq => "false",
.eq => "true",
}) else switch (operand_ctype.info(ctype_pool)) {
.basic, .pointer => {
try f.writeCValue(writer, lhs, .Other);
try writer.writeAll(compareOperatorC(operator));

View File

@ -668,3 +668,32 @@ test "address of function parameter is consistent in function addrspace" {
};
S.paramAddrMatch(1);
}
test "function parameter self equality" {
const S = struct {
fn equal(x: u32) bool {
return x == x;
}
fn notEqual(x: u32) bool {
return x != x;
}
fn lessThan(x: u32) bool {
return x < x;
}
fn lessThanOrEqual(x: u32) bool {
return x <= x;
}
fn greaterThan(x: u32) bool {
return x > x;
}
fn greaterThanOrEqual(x: u32) bool {
return x >= x;
}
};
try expect(S.equal(42));
try expect(!S.notEqual(42));
try expect(!S.lessThan(42));
try expect(S.lessThanOrEqual(42));
try expect(!S.greaterThan(42));
try expect(S.greaterThanOrEqual(42));
}