Skip to content

Commit 03208c8

Browse files
author
Mike Pall
committed
Fix math.min()/math.max() inconsistencies.
1 parent 1e6e8aa commit 03208c8

13 files changed

+151
-92
lines changed

src/lj_asm_arm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,8 +1659,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int cc, int fcc)
16591659
asm_intmin_max(as, ir, cc);
16601660
}
16611661

1662-
#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_HI)
1663-
#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LO)
1662+
#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_PL)
1663+
#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LE)
16641664

16651665
/* -- Comparisons --------------------------------------------------------- */
16661666

@@ -1852,7 +1852,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
18521852
} else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
18531853
as->curins--; /* Always skip the loword min/max. */
18541854
if (uselo || usehi)
1855-
asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
1855+
asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_PL : CC_LE);
18561856
return;
18571857
#elif LJ_HASFFI
18581858
} else if ((ir-1)->o == IR_CONV) {

src/lj_asm_arm64.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,7 +1598,7 @@ static void asm_fpmin_max(ASMState *as, IRIns *ir, A64CC fcc)
15981598
Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
15991599
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
16001600
right = ((left >> 8) & 31); left &= 31;
1601-
emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, left, right);
1601+
emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, right, left);
16021602
emit_nm(as, A64I_FCMPd, left, right);
16031603
}
16041604

@@ -1610,8 +1610,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, A64CC cc, A64CC fcc)
16101610
asm_intmin_max(as, ir, cc);
16111611
}
16121612

1613-
#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_HI)
1614-
#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_LO)
1613+
#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_PL)
1614+
#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_LE)
16151615

16161616
/* -- Comparisons --------------------------------------------------------- */
16171617

src/lj_asm_mips.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,12 +2121,12 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
21212121
right = (left >> 8); left &= 255;
21222122
#if !LJ_TARGET_MIPSR6
21232123
if (dest == left) {
2124-
emit_fg(as, MIPSI_MOVT_D, dest, right);
2124+
emit_fg(as, MIPSI_MOVF_D, dest, right);
21252125
} else {
2126-
emit_fg(as, MIPSI_MOVF_D, dest, left);
2126+
emit_fg(as, MIPSI_MOVT_D, dest, left);
21272127
if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
21282128
}
2129-
emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);
2129+
emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? right : left, ismax ? left : right);
21302130
#else
21312131
emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
21322132
#endif

src/lj_asm_ppc.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,9 +1724,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
17241724
if (tmp == left || tmp == right)
17251725
tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
17261726
dest), left), right));
1727-
emit_facb(as, PPCI_FSEL, dest, tmp,
1728-
ismax ? left : right, ismax ? right : left);
1729-
emit_fab(as, PPCI_FSUB, tmp, left, right);
1727+
emit_facb(as, PPCI_FSEL, dest, tmp, left, right);
1728+
emit_fab(as, PPCI_FSUB, tmp, ismax ? left : right, ismax ? right : left);
17301729
} else {
17311730
Reg dest = ra_dest(as, ir, RSET_GPR);
17321731
Reg tmp1 = RID_TMP, tmp2 = dest;

src/lj_opt_fold.c

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,8 +1774,6 @@ LJFOLDF(reassoc_intarith_k64)
17741774
#endif
17751775
}
17761776

1777-
LJFOLD(MIN MIN any)
1778-
LJFOLD(MAX MAX any)
17791777
LJFOLD(BAND BAND any)
17801778
LJFOLD(BOR BOR any)
17811779
LJFOLDF(reassoc_dup)
@@ -1785,6 +1783,15 @@ LJFOLDF(reassoc_dup)
17851783
return NEXTFOLD;
17861784
}
17871785

1786+
LJFOLD(MIN MIN any)
1787+
LJFOLD(MAX MAX any)
1788+
LJFOLDF(reassoc_dup_minmax)
1789+
{
1790+
if (fins->op2 == fleft->op2)
1791+
return LEFTFOLD; /* (a o b) o b ==> a o b */
1792+
return NEXTFOLD;
1793+
}
1794+
17881795
LJFOLD(BXOR BXOR any)
17891796
LJFOLDF(reassoc_bxor)
17901797
{
@@ -1823,23 +1830,12 @@ LJFOLDF(reassoc_shift)
18231830
return NEXTFOLD;
18241831
}
18251832

1826-
LJFOLD(MIN MIN KNUM)
1827-
LJFOLD(MAX MAX KNUM)
18281833
LJFOLD(MIN MIN KINT)
18291834
LJFOLD(MAX MAX KINT)
18301835
LJFOLDF(reassoc_minmax_k)
18311836
{
18321837
IRIns *irk = IR(fleft->op2);
1833-
if (irk->o == IR_KNUM) {
1834-
lua_Number a = ir_knum(irk)->n;
1835-
lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
1836-
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1837-
return LEFTFOLD;
1838-
PHIBARRIER(fleft);
1839-
fins->op1 = fleft->op1;
1840-
fins->op2 = (IRRef1)lj_ir_knum(J, y);
1841-
return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1842-
} else if (irk->o == IR_KINT) {
1838+
if (irk->o == IR_KINT) {
18431839
int32_t a = irk->i;
18441840
int32_t y = kfold_intop(a, fright->i, fins->o);
18451841
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
@@ -1852,24 +1848,6 @@ LJFOLDF(reassoc_minmax_k)
18521848
return NEXTFOLD;
18531849
}
18541850

1855-
LJFOLD(MIN MAX any)
1856-
LJFOLD(MAX MIN any)
1857-
LJFOLDF(reassoc_minmax_left)
1858-
{
1859-
if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
1860-
return RIGHTFOLD; /* (b o1 a) o2 b ==> b; (a o1 b) o2 b ==> b */
1861-
return NEXTFOLD;
1862-
}
1863-
1864-
LJFOLD(MIN any MAX)
1865-
LJFOLD(MAX any MIN)
1866-
LJFOLDF(reassoc_minmax_right)
1867-
{
1868-
if (fins->op1 == fright->op1 || fins->op1 == fright->op2)
1869-
return LEFTFOLD; /* a o2 (a o1 b) ==> a; a o2 (b o1 a) ==> a */
1870-
return NEXTFOLD;
1871-
}
1872-
18731851
/* -- Array bounds check elimination -------------------------------------- */
18741852

18751853
/* Eliminate ABC across PHIs to handle t[i-1] forwarding case.
@@ -1995,15 +1973,22 @@ LJFOLDF(comm_comp)
19951973

19961974
LJFOLD(BAND any any)
19971975
LJFOLD(BOR any any)
1998-
LJFOLD(MIN any any)
1999-
LJFOLD(MAX any any)
20001976
LJFOLDF(comm_dup)
20011977
{
20021978
if (fins->op1 == fins->op2) /* x o x ==> x */
20031979
return LEFTFOLD;
20041980
return fold_comm_swap(J);
20051981
}
20061982

1983+
LJFOLD(MIN any any)
1984+
LJFOLD(MAX any any)
1985+
LJFOLDF(comm_dup_minmax)
1986+
{
1987+
if (fins->op1 == fins->op2) /* x o x ==> x */
1988+
return LEFTFOLD;
1989+
return NEXTFOLD;
1990+
}
1991+
20071992
LJFOLD(BXOR any any)
20081993
LJFOLDF(comm_bxor)
20091994
{

src/lj_vmmath.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ double lj_vm_foldarith(double x, double y, int op)
5050
#if LJ_HASJIT
5151
case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
5252
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
53-
case IR_MIN - IR_ADD: return x > y ? y : x; break;
54-
case IR_MAX - IR_ADD: return x < y ? y : x; break;
53+
case IR_MIN - IR_ADD: return x < y ? x : y; break;
54+
case IR_MAX - IR_ADD: return x > y ? x : y; break;
5555
#endif
5656
default: return x;
5757
}

src/vm_arm.dasc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,8 +1716,8 @@ static void build_subroutines(BuildCtx *ctx)
17161716
|.endif
17171717
|.endmacro
17181718
|
1719-
| math_minmax math_min, gt, hi
1720-
| math_minmax math_max, lt, lo
1719+
| math_minmax math_min, gt, pl
1720+
| math_minmax math_max, lt, le
17211721
|
17221722
|//-- String library -----------------------------------------------------
17231723
|

src/vm_arm64.dasc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,8 +1489,8 @@ static void build_subroutines(BuildCtx *ctx)
14891489
| b <6
14901490
|.endmacro
14911491
|
1492-
| math_minmax math_min, gt, hi
1493-
| math_minmax math_max, lt, lo
1492+
| math_minmax math_min, gt, pl
1493+
| math_minmax math_max, lt, le
14941494
|
14951495
|//-- String library -----------------------------------------------------
14961496
|

src/vm_mips.dasc

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,7 @@ static void build_subroutines(BuildCtx *ctx)
17681768
| b ->fff_res
17691769
|. li RD, (2+1)*8
17701770
|
1771-
|.macro math_minmax, name, intins, fpins
1771+
|.macro math_minmax, name, intins, ismax
17721772
| .ffunc_1 name
17731773
| addu TMP3, BASE, NARGS8:RC
17741774
| bne SFARG1HI, TISNUM, >5
@@ -1822,13 +1822,21 @@ static void build_subroutines(BuildCtx *ctx)
18221822
|.endif
18231823
|7:
18241824
|.if FPU
1825+
|.if ismax
1826+
| c.olt.d FARG1, FRET1
1827+
|.else
18251828
| c.olt.d FRET1, FARG1
1826-
| fpins FRET1, FARG1
1829+
|.endif
1830+
| movf.d FRET1, FARG1
1831+
|.else
1832+
|.if ismax
1833+
| bal ->vm_sfcmpogt
18271834
|.else
18281835
| bal ->vm_sfcmpolt
1836+
|.endif
18291837
|. nop
1830-
| intins SFARG1LO, SFARG2LO, CRET1
1831-
| intins SFARG1HI, SFARG2HI, CRET1
1838+
| movz SFARG1LO, SFARG2LO, CRET1
1839+
| movz SFARG1HI, SFARG2HI, CRET1
18321840
|.endif
18331841
| b <6
18341842
|. addiu TMP2, TMP2, 8
@@ -1849,8 +1857,8 @@ static void build_subroutines(BuildCtx *ctx)
18491857
|
18501858
|.endmacro
18511859
|
1852-
| math_minmax math_min, movz, movf.d
1853-
| math_minmax math_max, movn, movt.d
1860+
| math_minmax math_min, movz, 0
1861+
| math_minmax math_max, movn, 1
18541862
|
18551863
|//-- String library -----------------------------------------------------
18561864
|
@@ -2692,6 +2700,43 @@ static void build_subroutines(BuildCtx *ctx)
26922700
|. move CRET1, CRET2
26932701
|.endif
26942702
|
2703+
|->vm_sfcmpogt:
2704+
|.if not FPU
2705+
| sll AT, SFARG2HI, 1
2706+
| sll TMP0, SFARG1HI, 1
2707+
| or CRET1, SFARG2LO, SFARG1LO
2708+
| or TMP1, AT, TMP0
2709+
| or TMP1, TMP1, CRET1
2710+
| beqz TMP1, >8 // Both args +-0: return 0.
2711+
|. sltu CRET1, r0, SFARG2LO
2712+
| lui TMP1, 0xffe0
2713+
| addu AT, AT, CRET1
2714+
| sltu CRET1, r0, SFARG1LO
2715+
| sltu AT, TMP1, AT
2716+
| addu TMP0, TMP0, CRET1
2717+
| sltu TMP0, TMP1, TMP0
2718+
| or TMP1, AT, TMP0
2719+
| bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
2720+
|. and AT, SFARG2HI, SFARG1HI
2721+
| bltz AT, >5 // Both args negative?
2722+
|. nop
2723+
| beq SFARG2HI, SFARG1HI, >8
2724+
|. sltu CRET1, SFARG2LO, SFARG1LO
2725+
| jr ra
2726+
|. slt CRET1, SFARG2HI, SFARG1HI
2727+
|5: // Swap conditions if both operands are negative.
2728+
| beq SFARG2HI, SFARG1HI, >8
2729+
|. sltu CRET1, SFARG1LO, SFARG2LO
2730+
| jr ra
2731+
|. slt CRET1, SFARG1HI, SFARG2HI
2732+
|8:
2733+
| jr ra
2734+
|. nop
2735+
|9:
2736+
| jr ra
2737+
|. li CRET1, 0
2738+
|.endif
2739+
|
26952740
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
26962741
|// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
26972742
|->vm_sfcmpolex:
@@ -2734,24 +2779,24 @@ static void build_subroutines(BuildCtx *ctx)
27342779
|. li CRET1, 0
27352780
|.endif
27362781
|
2737-
|.macro sfmin_max, name, intins
2782+
|.macro sfmin_max, name, fpcall
27382783
|->vm_sf .. name:
27392784
|.if JIT and not FPU
27402785
| move TMP2, ra
2741-
| bal ->vm_sfcmpolt
2786+
| bal ->fpcall
27422787
|. nop
27432788
| move TMP0, CRET1
27442789
| move SFRETHI, SFARG1HI
27452790
| move SFRETLO, SFARG1LO
27462791
| move ra, TMP2
2747-
| intins SFRETHI, SFARG2HI, TMP0
2792+
| movz SFRETHI, SFARG2HI, TMP0
27482793
| jr ra
2749-
|. intins SFRETLO, SFARG2LO, TMP0
2794+
|. movz SFRETLO, SFARG2LO, TMP0
27502795
|.endif
27512796
|.endmacro
27522797
|
2753-
| sfmin_max min, movz
2754-
| sfmin_max max, movn
2798+
| sfmin_max min, vm_sfcmpolt
2799+
| sfmin_max max, vm_sfcmpogt
27552800
|
27562801
|//-----------------------------------------------------------------------
27572802
|//-- Miscellaneous functions --------------------------------------------

0 commit comments

Comments
 (0)