diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 98ec28c6..622ff0a9 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -1702,9 +1702,10 @@ LJFOLDF(abc_k) LJFOLD(ABC any any) LJFOLDF(abc_invar) { - /* Invariant ABC marked as PTR. Drop if op1 is invariant, too. */ + /* Invariant ABC marked as P32 or U32. Drop if op1 is invariant too. */ if (!irt_isint(fins->t) && fins->op1 < J->chain[IR_LOOP] && - !irt_isphi(IR(fins->op1)->t)) + (irt_isu32(fins->t) || + (!irref_isk(fins->op1) && !irt_isphi(IR(fins->op1)->t)))) return DROPFOLD; return NEXTFOLD; } diff --git a/src/lj_record.c b/src/lj_record.c index f2a06f41..207327b3 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1069,12 +1069,13 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize) /* Runtime value for stop of loop is within bounds? */ if ((uint64_t)stop + ofs < (uint64_t)asize) { /* Emit invariant bounds check for stop. */ - emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop : + uint32_t abc = IRTG(IR_ABC, tref_isk(asizeref) ? IRT_U32 : IRT_P32); + emitir(abc, asizeref, ofs == 0 ? J->scev.stop : emitir(IRTI(IR_ADD), J->scev.stop, ofsref)); /* Emit invariant bounds check for start, if not const or negative. */ if (!(J->scev.dir && J->scev.start && (int64_t)IR(J->scev.start)->i + ofs >= 0)) - emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey); + emitir(abc, asizeref, ikey); return; } }