authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-08 16:57:53+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-15 14:00:08+02:00
log839a93a101804bb41cb519a965dc62e3eb7deed0
tree4e659f3f84455ee84bb5b68af03b28e9daff0426
parent4f279078c8bd57e7ee47eebce2572ab25729850a
signaturebadge-check Signed by SSH key SHA256:CQ99aPxq+RueiL9u7z0FEki5Fm7V6T8q4PrEGmINrA4

intern pool: fix float equality

We need to perform bitwise equality here, otherwise we get two different entries for nan values.

1 files changed, 10 insertions(+), 5 deletions(-)

src/InternPool.zig+10-5
...@@ -1556,10 +1556,10 @@ pub const Key = union(enum) {...@@ -1556,10 +1556,10 @@ pub const Key = union(enum) {
1556 // These are strange: we'll sometimes represent them as f128, even if the1556 // These are strange: we'll sometimes represent them as f128, even if the
1557 // underlying type is smaller. f80 is an exception: see float_c_longdouble_f80.1557 // underlying type is smaller. f80 is an exception: see float_c_longdouble_f80.
1558 const a_val = switch (a_info.storage) {1558 const a_val = switch (a_info.storage) {
1559 inline else => |val| @as(f128, @floatCast(val)),1559 inline else => |val| @as(u128, @bitCast(@as(f128, @floatCast(val)))),
1560 };1560 };
1561 const b_val = switch (b_info.storage) {1561 const b_val = switch (b_info.storage) {
1562 inline else => |val| @as(f128, @floatCast(val)),1562 inline else => |val| @as(u128, @bitCast(@as(f128, @floatCast(val)))),
1563 };1563 };
1564 return a_val == b_val;1564 return a_val == b_val;
1565 }1565 }
...@@ -1567,9 +1567,14 @@ pub const Key = union(enum) {...@@ -1567,9 +1567,14 @@ pub const Key = union(enum) {
1567 const StorageTag = @typeInfo(Key.Float.Storage).Union.tag_type.?;1567 const StorageTag = @typeInfo(Key.Float.Storage).Union.tag_type.?;
1568 assert(@as(StorageTag, a_info.storage) == @as(StorageTag, b_info.storage));1568 assert(@as(StorageTag, a_info.storage) == @as(StorageTag, b_info.storage));
15691569
1570 return switch (a_info.storage) {1570 switch (a_info.storage) {
1571 inline else => |val, tag| val == @field(b_info.storage, @tagName(tag)),1571 inline else => |val, tag| {
1572 };1572 const Bits = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(val)));
1573 const a_bits: Bits = @bitCast(val);
1574 const b_bits: Bits = @bitCast(@field(b_info.storage, @tagName(tag)));
1575 return a_bits == b_bits;
1576 },
1577 }
1573 },1578 },
15741579
1575 .opaque_type => |a_info| {1580 .opaque_type => |a_info| {