summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-01-21 16:49:03 +0100
committerMike Pall <mike>2013-01-21 16:49:03 +0100
commit1651684417e3839d757f034fefea55fba7494ab2 (patch)
tree750739a92d0414c7cb46542b60cce105f3c5f8e5
parent89e4650baef2f67b12b2a7d9c91a8809f552568a (diff)
downloadluajit2-1651684417e3839d757f034fefea55fba7494ab2.tar.gz
Add missing FOLD rules for U32 conversions.
-rw-r--r--src/lj_opt_fold.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 7561fb9c..c10f3c73 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -938,25 +938,18 @@ LJFOLDF(shortcut_conv_num_int)
}
LJFOLD(CONV CONV IRCONV_INT_NUM) /* _INT */
-LJFOLDF(simplify_conv_int_num)
-{
- /* Fold even across PHI to avoid expensive num->int conversions in loop. */
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT)
- return fleft->op1;
- return NEXTFOLD;
-}
-
LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32*/
-LJFOLDF(simplify_conv_u32_num)
+LJFOLDF(simplify_conv_int_num)
{
/* Fold even across PHI to avoid expensive num->int conversions in loop. */
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
+ if ((fleft->op2 & IRCONV_SRCMASK) ==
+ ((fins->op2 & IRCONV_DSTMASK) >> IRCONV_DSH))
return fleft->op1;
return NEXTFOLD;
}
-LJFOLD(CONV CONV IRCONV_I64_NUM) /* _INT or _U32*/
-LJFOLD(CONV CONV IRCONV_U64_NUM) /* _INT or _U32*/
+LJFOLD(CONV CONV IRCONV_I64_NUM) /* _INT or _U32 */
+LJFOLD(CONV CONV IRCONV_U64_NUM) /* _INT or _U32 */
LJFOLDF(simplify_conv_i64_num)
{
PHIBARRIER(fleft);
@@ -978,13 +971,24 @@ LJFOLDF(simplify_conv_i64_num)
return NEXTFOLD;
}
-LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT */
-LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT */
+LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT or _U32 */
+LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT or _U32 */
+LJFOLD(CONV CONV IRCONV_U32_I64) /* _INT or _U32 */
+LJFOLD(CONV CONV IRCONV_U32_U64) /* _INT or _U32 */
LJFOLDF(simplify_conv_int_i64)
{
+ int src;
PHIBARRIER(fleft);
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT)
- return fleft->op1;
+ src = (fleft->op2 & IRCONV_SRCMASK);
+ if (src == IRT_INT || src == IRT_U32) {
+ if (src == ((fins->op2 & IRCONV_DSTMASK) >> IRCONV_DSH)) {
+ return fleft->op1;
+ } else {
+ fins->op2 = ((fins->op2 & IRCONV_DSTMASK) | src);
+ fins->op1 = fleft->op1;
+ return RETRYFOLD;
+ }
+ }
return NEXTFOLD;
}
@@ -1064,14 +1068,21 @@ LJFOLD(CONV MUL IRCONV_INT_I64)
LJFOLD(CONV ADD IRCONV_INT_U64)
LJFOLD(CONV SUB IRCONV_INT_U64)
LJFOLD(CONV MUL IRCONV_INT_U64)
+LJFOLD(CONV ADD IRCONV_U32_I64)
+LJFOLD(CONV SUB IRCONV_U32_I64)
+LJFOLD(CONV MUL IRCONV_U32_I64)
+LJFOLD(CONV ADD IRCONV_U32_U64)
+LJFOLD(CONV SUB IRCONV_U32_U64)
+LJFOLD(CONV MUL IRCONV_U32_U64)
LJFOLDF(simplify_conv_narrow)
{
IROp op = (IROp)fleft->o;
+ IRType t = irt_type(fins->t);
IRRef op1 = fleft->op1, op2 = fleft->op2, mode = fins->op2;
PHIBARRIER(fleft);
op1 = emitir(IRTI(IR_CONV), op1, mode);
op2 = emitir(IRTI(IR_CONV), op2, mode);
- fins->ot = IRTI(op);
+ fins->ot = IRT(op, t);
fins->op1 = op1;
fins->op2 = op2;
return RETRYFOLD;