aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-03 17:29:09 +0100
committerMike Pall <mike>2011-03-03 17:29:09 +0100
commitf29a9d4341c64fa47c735bdf6ae1f379b6b6464c (patch)
tree78582e47199e76dad6309ddd540d070e3f4c16d2
parent1cb58fb7bb3cfe455426246599cac32ad5ec57ee (diff)
downloadluajit-f29a9d4341c64fa47c735bdf6ae1f379b6b6464c.tar.gz
luajit-f29a9d4341c64fa47c735bdf6ae1f379b6b6464c.tar.bz2
luajit-f29a9d4341c64fa47c735bdf6ae1f379b6b6464c.zip
Fix narrowing of POW.
-rw-r--r--src/lj_opt_narrow.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/lj_opt_narrow.c b/src/lj_opt_narrow.c
index 71062493..0a2bb6cd 100644
--- a/src/lj_opt_narrow.c
+++ b/src/lj_opt_narrow.c
@@ -413,23 +413,27 @@ TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc)
413 if (tvisstr(vc) && !lj_str_tonum(strV(vc), vc)) 413 if (tvisstr(vc) && !lj_str_tonum(strV(vc), vc))
414 lj_trace_err(J, LJ_TRERR_BADTYPE); 414 lj_trace_err(J, LJ_TRERR_BADTYPE);
415 n = numV(vc); 415 n = numV(vc);
416 /* Limit narrowing for pow to small exponents (or for two constants). */ 416 /* Narrowing must be unconditional to preserve (-x)^i semantics. */
417 if ((tref_isk(rc) && tref_isint(rc) && tref_isk(rb)) || 417 if (numisint(n)) {
418 ((J->flags & JIT_F_OPT_NARROW) && 418 int checkrange = 0;
419 (numisint(n) && n >= -65536.0 && n <= 65536.0))) { 419 /* Split pow is faster for bigger exponents. But do this only for (+k)^i. */
420 TRef tmp; 420 if (tref_isk(rb) && (int32_t)ir_knum(IR(tref_ref(rb)))->u32.hi >= 0) {
421 if (!(n >= -65536.0 && n <= 65536.0)) goto split_pow;
422 checkrange = 1;
423 }
421 if (!tref_isinteger(rc)) { 424 if (!tref_isinteger(rc)) {
422 if (tref_isstr(rc)) 425 if (tref_isstr(rc))
423 rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); 426 rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
424 /* Guarded conversion to integer! */ 427 /* Guarded conversion to integer! */
425 rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK); 428 rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK);
426 } 429 }
427 if (!tref_isk(rc)) { /* Range guard: -65536 <= i <= 65536 */ 430 if (checkrange && !tref_isk(rc)) { /* Range guard: -65536 <= i <= 65536 */
428 tmp = emitir(IRTI(IR_ADD), rc, lj_ir_kint(J, 65536-2147483647-1)); 431 TRef tmp = emitir(IRTI(IR_ADD), rc, lj_ir_kint(J, 65536));
429 emitir(IRTGI(IR_LE), tmp, lj_ir_kint(J, 2*65536-2147483647-1)); 432 emitir(IRTGI(IR_ULE), tmp, lj_ir_kint(J, 2*65536));
430 } 433 }
431 return emitir(IRTN(IR_POW), rb, rc); 434 return emitir(IRTN(IR_POW), rb, rc);
432 } 435 }
436split_pow:
433 /* FOLD covers most cases, but some are easier to do here. */ 437 /* FOLD covers most cases, but some are easier to do here. */
434 if (tref_isk(rb) && tvispone(ir_knum(IR(tref_ref(rb))))) 438 if (tref_isk(rb) && tvispone(ir_knum(IR(tref_ref(rb)))))
435 return rb; /* 1 ^ x ==> 1 */ 439 return rb; /* 1 ^ x ==> 1 */