diff options
| -rw-r--r-- | src/Sema.zig | 5 | ||||
| -rw-r--r-- | src/Value.zig | 2 | ||||
| -rw-r--r-- | test/behavior/floatop.zig | 11 |
3 files changed, 17 insertions, 1 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 9e729a17ea..5982024d89 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -38137,6 +38137,11 @@ fn compareScalar( const pt = sema.pt; const coerced_lhs = try pt.getCoerced(lhs, ty); const coerced_rhs = try pt.getCoerced(rhs, ty); + + // Equality comparisons of signed zero and NaN need to use floating point semantics + if (coerced_lhs.isFloat(pt.zcu) or coerced_rhs.isFloat(pt.zcu)) + return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt); + switch (op) { .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty), .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)), diff --git a/src/Value.zig b/src/Value.zig index be2c73c3e9..40e5331c4e 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -1132,6 +1132,8 @@ pub fn compareHeteroAdvanced( else => {}, } } + + if (lhs.isNan(zcu) or rhs.isNan(zcu)) return op == .neq; return (try orderAdvanced(lhs, rhs, strat, zcu, tid)).compare(op); } diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index f2fa2f4b0a..0eb1bd2d93 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -194,7 +194,7 @@ fn testCmp(comptime T: type) !void { try expect(x <= 2.0); } - @setEvalBranchQuota(2_000); + @setEvalBranchQuota(4_000); var edges = [_]T{ -math.inf(T), -math.floatMax(T), @@ -210,6 +210,7 @@ fn testCmp(comptime T: type) !void { }; _ = &edges; for (edges, 0..) |rhs, rhs_i| { + const rhs_v: @Vector(4, T) = @splat(rhs); for (edges, 0..) |lhs, lhs_i| { const no_nan = lhs_i != 5 and rhs_i != 5; const lhs_order = if (lhs_i < 5) lhs_i else lhs_i - 2; @@ -220,6 +221,14 @@ fn testCmp(comptime T: type) !void { try expect((lhs > rhs) == (no_nan and lhs_order > rhs_order)); try expect((lhs <= rhs) == (no_nan and lhs_order <= rhs_order)); try expect((lhs >= rhs) == (no_nan and lhs_order >= rhs_order)); + + const lhs_v: @Vector(4, T) = @splat(lhs); + try expect(@reduce(.And, (lhs_v == rhs_v)) == (no_nan and lhs_order == rhs_order)); + try expect(@reduce(.And, (lhs_v != rhs_v)) == !(no_nan and lhs_order == rhs_order)); + try expect(@reduce(.And, (lhs_v < rhs_v)) == (no_nan and lhs_order < rhs_order)); + try expect(@reduce(.And, (lhs_v > rhs_v)) == (no_nan and lhs_order > rhs_order)); + try expect(@reduce(.And, (lhs_v <= rhs_v)) == (no_nan and lhs_order <= rhs_order)); + try expect(@reduce(.And, (lhs_v >= rhs_v)) == (no_nan and lhs_order >= rhs_order)); } } } |
