diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_opt_fold.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index ae65e15a..7a02c6ff 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -237,10 +237,11 @@ LJFOLDF(kfold_fpcall2) | |||
237 | } | 237 | } |
238 | 238 | ||
239 | LJFOLD(POW KNUM KINT) | 239 | LJFOLD(POW KNUM KINT) |
240 | LJFOLD(POW KNUM KNUM) | ||
240 | LJFOLDF(kfold_numpow) | 241 | LJFOLDF(kfold_numpow) |
241 | { | 242 | { |
242 | lua_Number a = knumleft; | 243 | lua_Number a = knumleft; |
243 | lua_Number b = (lua_Number)fright->i; | 244 | lua_Number b = fright->o == IR_KINT ? (lua_Number)fright->i : knumright; |
244 | lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD); | 245 | lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD); |
245 | return lj_ir_knum(J, y); | 246 | return lj_ir_knum(J, y); |
246 | } | 247 | } |
@@ -1077,7 +1078,7 @@ LJFOLDF(simplify_nummuldiv_negneg) | |||
1077 | } | 1078 | } |
1078 | 1079 | ||
1079 | LJFOLD(POW any KINT) | 1080 | LJFOLD(POW any KINT) |
1080 | LJFOLDF(simplify_numpow_xk) | 1081 | LJFOLDF(simplify_numpow_xkint) |
1081 | { | 1082 | { |
1082 | int32_t k = fright->i; | 1083 | int32_t k = fright->i; |
1083 | TRef ref = fins->op1; | 1084 | TRef ref = fins->op1; |
@@ -1106,13 +1107,22 @@ LJFOLDF(simplify_numpow_xk) | |||
1106 | return ref; | 1107 | return ref; |
1107 | } | 1108 | } |
1108 | 1109 | ||
1110 | LJFOLD(POW any KNUM) | ||
1111 | LJFOLDF(simplify_numpow_xknum) | ||
1112 | { | ||
1113 | if (knumright == 0.5) /* x ^ 0.5 ==> sqrt(x) */ | ||
1114 | return emitir(IRTN(IR_FPMATH), fins->op1, IRFPM_SQRT); | ||
1115 | return NEXTFOLD; | ||
1116 | } | ||
1117 | |||
1109 | LJFOLD(POW KNUM any) | 1118 | LJFOLD(POW KNUM any) |
1110 | LJFOLDF(simplify_numpow_kx) | 1119 | LJFOLDF(simplify_numpow_kx) |
1111 | { | 1120 | { |
1112 | lua_Number n = knumleft; | 1121 | lua_Number n = knumleft; |
1113 | if (n == 2.0) { /* 2.0 ^ i ==> ldexp(1.0, tonum(i)) */ | 1122 | if (n == 2.0 && irt_isint(fright->t)) { /* 2.0 ^ i ==> ldexp(1.0, i) */ |
1114 | fins->o = IR_CONV; | ||
1115 | #if LJ_TARGET_X86ORX64 | 1123 | #if LJ_TARGET_X86ORX64 |
1124 | /* Different IR_LDEXP calling convention on x86/x64 requires conversion. */ | ||
1125 | fins->o = IR_CONV; | ||
1116 | fins->op1 = fins->op2; | 1126 | fins->op1 = fins->op2; |
1117 | fins->op2 = IRCONV_NUM_INT; | 1127 | fins->op2 = IRCONV_NUM_INT; |
1118 | fins->op2 = (IRRef1)lj_opt_fold(J); | 1128 | fins->op2 = (IRRef1)lj_opt_fold(J); |