Bug: wrong result for (-0.0 - 0)

(exp - i) was being optimized to (exp + (-i)), to use OP_ADDI, but
(-0.0 - 0) is -0.0, while (-0.0 + 0) is +0.0, so the case (exp - 0)
was excluded from the optimization.
This commit is contained in:
Roberto I
2026-10-12 16:27:02 -03:00
parent 6db80b55c1
commit b35736b9d7
2 changed files with 10 additions and 1 deletions
+5 -1
View File
@@ -1542,15 +1542,19 @@ static void codebinK (FuncState *fs, BinOpr opr,
/* Try to code a binary operator negating its second operand.
** For the metamethod, 2nd operand must keep its original value.
** As a special case, avoid the optimization for (exp - 0), because
** (-0.0 - 0) is -0.0, while (-0.0 + 0) is +0.0.
*/
static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
OpCode op, int line, TMS event) {
OpCode op, int line, TMS event) {
if (!isKint(e2))
return 0; /* not an integer constant */
else {
lua_Integer i2 = e2->u.ival;
if (!(fitsC(i2) && fitsC(-i2)))
return 0; /* not in the proper range */
if (event == TM_SUB && i2 == 0)
return 0; /* do not optimize (exp - 0) */
else { /* operating a small integer constant */
int v2 = cast_int(i2);
finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event);
+5
View File
@@ -838,6 +838,11 @@ do
local a1, a2, a3, a4, a5 = 0, 0, "\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0"
assert(a1 == a2 and a2 == a4 and a1 ~= a3)
assert(a3 == a5)
-- Bug since 5.4: Results differ for constant 0 versus variable 0;
-- (mz - 0) should be -0.0, but it resulted in +0.0
local zi = 0
assert(1/(mz - 0) == 1/(mz - zi))
end