diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_opt_narrow.c | 20 |
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 | } |
| 436 | split_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 */ |
