DUALNUM: Improve/fix edge cases of unary minus.

Thanks to Sergey Kaplun. #1422 #1418
This commit is contained in:
Mike Pall
2026-01-09 18:46:32 +01:00
parent 3015b6187e
commit 707c12bf00
8 changed files with 33 additions and 7 deletions

View File

@@ -545,9 +545,8 @@ 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);
return emitir(IRTGI(IR_SUBOV), zero, rc);
}

View 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;

View 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

View 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

View 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

View 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

View 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

View 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