aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_crecord.c10
-rw-r--r--src/lj_opt_fold.c45
2 files changed, 49 insertions, 6 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index c7c99133..566c064b 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -335,15 +335,17 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
335 IRIns *ir = IR(tref_ref(idx)); 335 IRIns *ir = IR(tref_ref(idx));
336 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && 336 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) &&
337 ir->o == IR_ADD && irref_isk(ir->op2)) { 337 ir->o == IR_ADD && irref_isk(ir->op2)) {
338 IRIns *irk = IR(ir->op2);
339 idx = ir->op1;
338 /* This would be rather difficult in FOLD, so do it here: 340 /* This would be rather difficult in FOLD, so do it here:
339 ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) 341 ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
340 */ 342 */
341 idx = ir->op1;
342#if LJ_64 343#if LJ_64
343 ofs += (int64_t)ir_kint64(IR(ir->op2))->u64 * sz; 344 if (irk->o == IR_KINT64)
344#else 345 ofs += (ptrdiff_t)ir_kint64(irk)->u64 * sz;
345 ofs += IR(ir->op2)->i * sz; 346 else
346#endif 347#endif
348 ofs += (ptrdiff_t)irk->i * sz;
347 } 349 }
348 idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); 350 idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz));
349 ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); 351 ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr);
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index d650f09c..e8e81a3e 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -644,8 +644,8 @@ LJFOLD(TOINT ADD any)
644LJFOLD(TOINT SUB any) 644LJFOLD(TOINT SUB any)
645LJFOLD(TOBIT ADD KNUM) 645LJFOLD(TOBIT ADD KNUM)
646LJFOLD(TOBIT SUB KNUM) 646LJFOLD(TOBIT SUB KNUM)
647LJFOLD(TOI64 ADD any) 647LJFOLD(TOI64 ADD 5) /* IRTOINT_TRUNCI64 */
648LJFOLD(TOI64 SUB any) 648LJFOLD(TOI64 SUB 5) /* IRTOINT_TRUNCI64 */
649LJFOLDF(narrow_convert) 649LJFOLDF(narrow_convert)
650{ 650{
651 PHIBARRIER(fleft); 651 PHIBARRIER(fleft);
@@ -669,6 +669,47 @@ LJFOLDF(cse_toint)
669 return EMITFOLD; /* No fallthrough to regular CSE. */ 669 return EMITFOLD; /* No fallthrough to regular CSE. */
670} 670}
671 671
672/* -- Strength reduction of widening -------------------------------------- */
673
674LJFOLD(TOI64 any 3) /* IRTOINT_ZEXT64 */
675LJFOLDF(simplify_zext64)
676{
677#if LJ_TARGET_X64
678 /* Eliminate widening. All 32 bit ops implicitly zero-extend the result. */
679 return LEFTFOLD;
680#else
681 UNUSED(J);
682 return NEXTFOLD;
683#endif
684}
685
686LJFOLD(TOI64 any 4) /* IRTOINT_SEXT64 */
687LJFOLDF(simplify_sext64)
688{
689 IRRef ref = fins->op1;
690 int64_t ofs = 0;
691 if (fleft->o == IR_ADD && irref_isk(fleft->op2)) {
692 ofs = (int64_t)IR(fleft->op2)->i;
693 ref = fleft->op1;
694 }
695 /* Use scalar evolution analysis results to strength-reduce sign-extension. */
696 if (ref == J->scev.idx) {
697 IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop;
698 lua_assert(irt_isint(J->scev.t));
699 if (lo && IR(lo)->i + ofs >= 0) {
700#if LJ_TARGET_X64
701 /* Eliminate widening. All 32 bit ops do an implicit zero-extension. */
702 return LEFTFOLD;
703#else
704 /* Reduce to a (cheaper) zero-extension. */
705 fins->op2 = IRTOINT_ZEXT64;
706 return RETRYFOLD;
707#endif
708 }
709 }
710 return NEXTFOLD;
711}
712
672/* -- Integer algebraic simplifications ----------------------------------- */ 713/* -- Integer algebraic simplifications ----------------------------------- */
673 714
674LJFOLD(ADD any KINT) 715LJFOLD(ADD any KINT)