Skip to content

Commit 96d6d50

Browse files
author
Mike Pall
committed
Revert to trival pow() optimizations to prevent inaccuracies.
1 parent aa0550e commit 96d6d50

18 files changed

+45
-157
lines changed

src/lj_asm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,8 +1680,7 @@ static void asm_pow(ASMState *as, IRIns *ir)
16801680
IRCALL_lj_carith_powu64);
16811681
else
16821682
#endif
1683-
asm_callid(as, ir, irt_isnum(IR(ir->op2)->t) ? IRCALL_lj_vm_pow :
1684-
IRCALL_lj_vm_powi);
1683+
asm_callid(as, ir, IRCALL_pow);
16851684
}
16861685

16871686
static void asm_div(ASMState *as, IRIns *ir)

src/lj_dispatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ extern double __divdf3(double a, double b);
4444
#define GOTDEF(_) \
4545
_(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \
4646
_(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \
47-
_(lj_vm_pow) _(fmod) _(ldexp) _(lj_vm_modi) \
47+
_(pow) _(fmod) _(ldexp) _(lj_vm_modi) \
4848
_(lj_dispatch_call) _(lj_dispatch_ins) _(lj_dispatch_stitch) \
4949
_(lj_dispatch_profile) _(lj_err_throw) \
5050
_(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \

src/lj_ffrecord.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,8 @@ static void LJ_FASTCALL recff_math_call(jit_State *J, RecordFFData *rd)
638638

639639
static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
640640
{
641-
J->base[0] = lj_opt_narrow_pow(J, J->base[0], J->base[1],
642-
&rd->argv[0], &rd->argv[1]);
641+
J->base[0] = lj_opt_narrow_arith(J, J->base[0], J->base[1],
642+
&rd->argv[0], &rd->argv[1], IR_POW);
643643
UNUSED(rd);
644644
}
645645

src/lj_ircall.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ typedef struct CCallInfo {
217217
_(FPMATH, sqrt, 1, N, NUM, XA_FP) \
218218
_(ANY, log, 1, N, NUM, XA_FP) \
219219
_(ANY, lj_vm_log2, 1, N, NUM, XA_FP) \
220-
_(ANY, lj_vm_powi, 2, N, NUM, XA_FP) \
221-
_(ANY, lj_vm_pow, 2, N, NUM, XA2_FP) \
220+
_(ANY, pow, 2, N, NUM, XA2_FP) \
222221
_(ANY, atan2, 2, N, NUM, XA2_FP) \
223222
_(ANY, ldexp, 2, N, NUM, XA_FP) \
224223
_(SOFTFP, lj_vm_tobit, 1, N, INT, XA_FP32) \

src/lj_iropt.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
145145
TValue *vb, TValue *vc, IROp op);
146146
LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc);
147147
LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc);
148-
LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc);
149148
LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);
150149

151150
/* Optimization passes. */

src/lj_opt_fold.c

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,10 @@ LJFOLDF(kfold_fpcall2)
236236
return NEXTFOLD;
237237
}
238238

239-
LJFOLD(POW KNUM KINT)
240239
LJFOLD(POW KNUM KNUM)
241240
LJFOLDF(kfold_numpow)
242241
{
243-
lua_Number a = knumleft;
244-
lua_Number b = fright->o == IR_KINT ? (lua_Number)fright->i : knumright;
245-
lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD);
246-
return lj_ir_knum(J, y);
242+
return lj_ir_knum(J, lj_vm_foldarith(knumleft, knumright, IR_POW - IR_ADD));
247243
}
248244

249245
/* Must not use kfold_kref for numbers (could be NaN). */
@@ -1113,34 +1109,17 @@ LJFOLDF(simplify_nummuldiv_negneg)
11131109
return RETRYFOLD;
11141110
}
11151111

1116-
LJFOLD(POW any KINT)
1117-
LJFOLDF(simplify_numpow_xkint)
1112+
LJFOLD(POW any KNUM)
1113+
LJFOLDF(simplify_numpow_k)
11181114
{
1119-
int32_t k = fright->i;
1120-
TRef ref = fins->op1;
1121-
if (k == 0) /* x ^ 0 ==> 1 */
1115+
if (knumright == 0) /* x ^ 0 ==> 1 */
11221116
return lj_ir_knum_one(J); /* Result must be a number, not an int. */
1123-
if (k == 1) /* x ^ 1 ==> x */
1117+
else if (knumright == 1) /* x ^ 1 ==> x */
11241118
return LEFTFOLD;
1125-
if ((uint32_t)(k+65536) > 2*65536u) /* Limit code explosion. */
1119+
else if (knumright == 2) /* x ^ 2 ==> x * x */
1120+
return emitir(IRTN(IR_MUL), fins->op1, fins->op1);
1121+
else
11261122
return NEXTFOLD;
1127-
if (k < 0) { /* x ^ (-k) ==> (1/x) ^ k. */
1128-
ref = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), ref);
1129-
k = -k;
1130-
}
1131-
/* Unroll x^k for 1 <= k <= 65536. */
1132-
for (; (k & 1) == 0; k >>= 1) /* Handle leading zeros. */
1133-
ref = emitir(IRTN(IR_MUL), ref, ref);
1134-
if ((k >>= 1) != 0) { /* Handle trailing bits. */
1135-
TRef tmp = emitir(IRTN(IR_MUL), ref, ref);
1136-
for (; k != 1; k >>= 1) {
1137-
if (k & 1)
1138-
ref = emitir(IRTN(IR_MUL), ref, tmp);
1139-
tmp = emitir(IRTN(IR_MUL), tmp, tmp);
1140-
}
1141-
ref = emitir(IRTN(IR_MUL), ref, tmp);
1142-
}
1143-
return ref;
11441123
}
11451124

11461125
/* -- Simplify conversions ------------------------------------------------ */

src/lj_opt_narrow.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -584,30 +584,6 @@ TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc)
584584
return emitir(IRTN(IR_SUB), rb, tmp);
585585
}
586586

587-
/* Narrowing of power operator or math.pow. */
588-
TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc)
589-
{
590-
rb = conv_str_tonum(J, rb, vb);
591-
rb = lj_ir_tonum(J, rb); /* Left arg is always treated as an FP number. */
592-
rc = conv_str_tonum(J, rc, vc);
593-
if (tvisint(vc) || numisint(numV(vc))) {
594-
int32_t k = numberVint(vc);
595-
if (!(k >= -65536 && k <= 65536)) goto force_pow_num;
596-
if (!tref_isinteger(rc)) {
597-
/* Guarded conversion to integer! */
598-
rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK);
599-
}
600-
if (!tref_isk(rc)) { /* Range guard: -65536 <= i <= 65536 */
601-
TRef tmp = emitir(IRTI(IR_ADD), rc, lj_ir_kint(J, 65536));
602-
emitir(IRTGI(IR_ULE), tmp, lj_ir_kint(J, 2*65536));
603-
}
604-
} else {
605-
force_pow_num:
606-
rc = lj_ir_tonum(J, rc); /* Want POW(num, num), not POW(num, int). */
607-
}
608-
return emitir(IRTN(IR_POW), rb, rc);
609-
}
610-
611587
/* -- Predictive narrowing of induction variables ------------------------- */
612588

613589
/* Narrow a single runtime value. */

src/lj_opt_split.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ static void split_ir(jit_State *J)
400400
hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_div);
401401
break;
402402
case IR_POW:
403-
hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi);
403+
hi = split_call_li(J, hisubst, oir, ir, IRCALL_pow);
404404
break;
405405
case IR_FPMATH:
406406
hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2);

src/lj_record.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,7 @@ void lj_record_ins(jit_State *J)
23942394

23952395
case BC_POW:
23962396
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
2397-
rc = lj_opt_narrow_pow(J, rb, rc, rbv, rcv);
2397+
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
23982398
else
23992399
rc = rec_mm_arith(J, &ix, MM_pow);
24002400
break;

src/lj_vm.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ LJ_ASMF int lj_vm_errno(void);
9898
LJ_ASMF TValue *lj_vm_next(GCtab *t, uint32_t idx);
9999
#endif
100100

101-
LJ_ASMF double lj_vm_powi(double, int32_t);
102-
LJ_ASMF double lj_vm_pow(double, double);
103-
104101
/* Continuations for metamethods. */
105102
LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */
106103
LJ_ASMF void lj_cont_ra(void); /* Store result in RA from instruction. */

0 commit comments

Comments
 (0)