]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Fix IR_ABC hoisting.
authorMike Pall <mike>
Wed, 14 Aug 2024 22:10:01 +0000 (00:10 +0200)
committerMike Pall <mike>
Wed, 14 Aug 2024 22:10:01 +0000 (00:10 +0200)
Reported by pwnhacker0x18. Fixed by Peter Cawley. #1194

src/lj_opt_fold.c
src/lj_record.c

index 98ec28c623fba90d05059450e6a4b4f07bb39efc..622ff0a93871bcd8401c6debda7200520145899b 100644 (file)
@@ -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;
 }
index f2a06f41cdf386ceeea8f44f3c474e3193063532..207327b333e3f52a753ddf77d9bd9e34ea0c80e0 100644 (file)
@@ -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;
       }
     }