]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
DUALNUM: Improve/fix edge cases of unary minus. v2.1
authorMike Pall <mike>
Fri, 9 Jan 2026 17:46:32 +0000 (18:46 +0100)
committerMike Pall <mike>
Fri, 9 Jan 2026 17:46:32 +0000 (18:46 +0100)
Thanks to Sergey Kaplun. #1422 #1418

src/lj_opt_narrow.c
src/vm_arm.dasc
src/vm_arm64.dasc
src/vm_mips.dasc
src/vm_mips64.dasc
src/vm_ppc.dasc
src/vm_x64.dasc
src/vm_x86.dasc

index db5e8b5bd41ed1c9da1cd48ff49d000fa64a28e8..593bec394c6d51a8964d127c449777da51cdbdf6 100644 (file)
@@ -545,10 +545,9 @@ TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc)
   rc = conv_str_tonum(J, rc, vc);
   if (tref_isinteger(rc)) {
     uint32_t k = (uint32_t)numberVint(vc);
-    if ((tvisint(vc) || k != 0) && k != 0x80000000u) {
+    if (k != 0 && k != 0x80000000u) {
       TRef zero = lj_ir_kint(J, 0);
-      if (!tvisint(vc))
-       emitir(IRTGI(IR_NE), rc, zero);
+      emitir(IRTGI(IR_NE), rc, zero);
       return emitir(IRTGI(IR_SUBOV), zero, rc);
     }
     rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
index d99cdaca86a7b055c766642239dda25e583065a1..d67dbffcc1e4fa9b03d1bb370017c44ed9b33fbb 100644 (file)
@@ -3125,13 +3125,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  bhi ->vmeta_unm
     |  eorne CARG2, CARG2, #0x80000000
     |  bne >5
-    |  rsbseq CARG1, CARG1, #0
+    |  rsbs CARG1, CARG1, #0
+    |  ldrdeq CARG12, >8
     |  ldrdvs CARG12, >9
     |5:
     |  strd CARG12, [BASE, RA]
     |   ins_next3
     |
     |.align 8
+    |8:
+    |  .long 0x00000000, 0x80000000    // -0.
     |9:
     |  .long 0x00000000, 0x41e00000    // 2^31.
     break;
index a0789efbdec18a760a44da329900b4bc3f84de4c..be8b76a7a524a4b9cfe08e90fb7711028ef1c974 100644 (file)
@@ -2687,6 +2687,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   movz CARG3, #0x41e0, lsl #48   // 2^31.
     |   add_TISNUM TMP0, TMP0
     |  csel TMP0, TMP0, CARG3, vc
+    |   movz CARG3, #0x8000, lsl #48   // -0.
+    |  csel TMP0, TMP0, CARG3, ne
     |5:
     |  str TMP0, [BASE, RA, lsl #3]
     |  ins_next
index 5063e7c60c5b94e312130bccabd2a9e4107418c5..9a39edd69eeabedc387d2521d8324f85d11d17d1 100644 (file)
@@ -3566,7 +3566,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   addu RA, BASE, RA
     |  bne SFARG1HI, TISNUM, >2
     |.  lw SFARG1LO, LO(RB)
-    |  lui TMP1, 0x8000
+    |  beqz SFARG1LO, >3
+    |.  lui TMP1, 0x8000
     |  beq SFARG1LO, TMP1, ->vmeta_unm // Meta handler deals with -2^31.
     |.  negu SFARG1LO, SFARG1LO
     |1:
@@ -3580,6 +3581,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.  lui TMP1, 0x8000
     |  b <1
     |.  xor SFARG1HI, SFARG1HI, TMP1
+    |3:
+    |  b <1
+    |.  lui SFARG1HI, 0x8000   // -0.
     break;
   case BC_LEN:
     |  // RA = dst*8, RD = src*8
index 8365da8eb05a92cd7389a7f626264e840a84b614..310269ce1c23d5a54d97932309d5159f6d4d3702 100644 (file)
@@ -3804,7 +3804,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  sextw CARG1, CARG1
     |  beq CARG1, TMP1, ->vmeta_unm    // Meta handler deals with -2^31.
     |.  negu CARG1, CARG1
-    |  zextw CARG1, CARG1
+    |  beqz CARG1, >3
+    |.  zextw CARG1, CARG1
     |  settp CARG1, TISNUM
     |1:
     |  ins_next1
@@ -3816,6 +3817,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.  dsll TMP1, TMP1, 32
     |  b <1
     |.  xor CARG1, CARG1, TMP1
+    |3:
+    |  b <1
+    |.  dsll CARG1, TMP1, 32
     break;
   case BC_LEN:
     |  // RA = dst*8, RD = src*8
index 37be772d02a62a925e2bb9c77a3db934978781c0..440bf1c4b04c043ba47fa08a4d333952c4373eb5 100644 (file)
@@ -3962,11 +3962,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  bne >5
     |.if GPR64
     |  lus TMP2, 0x8000
-    |  neg TMP0, TMP0
+    |  neg. TMP0, TMP0
+    |  beq >8
     |  cmplw TMP0, TMP2
     |  beq >4
     |.else
     |  nego. TMP0, TMP0
+    |  beq >8
     |  bso >4
     |1:
     |.endif
@@ -3993,6 +3995,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   stw TMP0, 4(RA)
     |.if DUALNUM
     |  b <3
+    |8:
+    |  lus TMP1, 0x8000                        // -0.
+    |  b <7
     |.else
     |  ins_next2
     |.endif
index a2fa9bfaa07ba38c8ff055717212f5442396478e..9e0f58fd34e48551cb5a2a74f6f1ed1aa96c73a1 100644 (file)
@@ -3266,11 +3266,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.if DUALNUM
     |  checkint RB, >5
     |  neg RBd
+    |  jz >3
     |  jo >4
     |  setint RB
     |9:
     |  mov [BASE+RA*8], RB
     |  ins_next
+    |3:
+    |  mov64 RB, U64x(80000000,00000000)  // -0.
+    |  jmp <9
     |4:
     |  mov64 RB, U64x(41e00000,00000000)  // 2^31.
     |  jmp <9
index d7d82b32ce8c2c8bd6f824bc27f0e71032247852..7e3d68a00692ec09d98a9752178d94a7824c02f1 100644 (file)
@@ -3856,11 +3856,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  checkint RD, >5
     |  mov RB, [BASE+RD*8]
     |  neg RB
+    |  jz >3
     |  jo >4
     |  mov dword [BASE+RA*8+4], LJ_TISNUM
+    |8:
     |  mov dword [BASE+RA*8], RB
     |9:
     |  ins_next
+    |3:
+    |  mov dword [BASE+RA*8+4], 0x80000000  // -0.
+    |  jmp <8
     |4:
     |  mov dword [BASE+RA*8+4], 0x41e00000  // 2^31.
     |  mov dword [BASE+RA*8], 0