diff --git a/src/lj_asm.c b/src/lj_asm.c index d26d0b4b..e7f2cb72 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -96,7 +96,7 @@ typedef struct ASMState { #define neverfuse(as) (as->fuseref == FUSE_DISABLED) #define opisfusableload(o) \ ((o) == IR_ALOAD || (o) == IR_HLOAD || (o) == IR_ULOAD || \ - (o) == IR_FLOAD || (o) == IR_SLOAD || (o) == IR_XLOAD) + (o) == IR_FLOAD || (o) == IR_XLOAD || (o) == IR_SLOAD || (o) == IR_VLOAD) /* Instruction selection for XMM moves. */ #define XMM_MOVRR(as) ((as->flags & JIT_F_SPLIT_XMM) ? XO_MOVSD : XO_MOVAPS) @@ -1315,6 +1315,9 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) asm_fusexref(as, IR(ir->op1), xallow); return RID_MRM; } + } else if (ir->o == IR_VLOAD) { + asm_fuseahuref(as, ir->op1, xallow); + return RID_MRM; } } if (!(as->freeset & allow) && @@ -1978,7 +1981,7 @@ static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck) } #endif -static void asm_ahuload(ASMState *as, IRIns *ir) +static void asm_ahuvload(ASMState *as, IRIns *ir) { lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t)); #if LJ_64 @@ -3385,7 +3388,9 @@ static void asm_ir(ASMState *as, IRIns *ir) case IR_STRREF: asm_strref(as, ir); break; /* Loads and stores. */ - case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: asm_ahuload(as, ir); break; + case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: + asm_ahuvload(as, ir); + break; case IR_FLOAD: case IR_XLOAD: asm_fxload(as, ir); break; case IR_SLOAD: asm_sload(as, ir); break; diff --git a/src/lj_ir.h b/src/lj_ir.h index cc57560d..c483e60f 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -95,8 +95,9 @@ _(HLOAD, L , ref, ___) \ _(ULOAD, L , ref, ___) \ _(FLOAD, L , ref, lit) \ - _(SLOAD, L , lit, lit) \ _(XLOAD, L , ref, lit) \ + _(SLOAD, L , lit, lit) \ + _(VLOAD, L , ref, ___) \ \ _(ASTORE, S , ref, ref) \ _(HSTORE, S , ref, ref) \ diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 90520d8c..5a6ea29b 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -1308,6 +1308,7 @@ LJFOLDF(fload_str_len_snew) } LJFOLD(FLOAD any IRFL_STR_LEN) +LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ LJFOLDX(lj_opt_cse) /* All other field loads need alias analysis. */ diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index c862e67e..8674ddea 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c @@ -102,9 +102,6 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) IRRef lim = xref; /* Search limit. */ IRRef ref; - if (IR(xr->op1)->o != IR_FLOAD) /* Varargs have no corresponding stores. */ - goto cselim; - /* Search for conflicting stores. */ ref = J->chain[fins->o+IRDELTA_L2S]; while (ref > xref) { diff --git a/src/lj_record.c b/src/lj_record.c index 42bcca1a..6e396729 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1998,7 +1998,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) IRType t = itype2irt(&J->L->base[i-1-nvararg]); TRef aref = emitir(IRT(IR_AREF, IRT_PTR), vbase, lj_ir_kint(J, (int32_t)i)); - TRef tr = emitir(IRTG(IR_ALOAD, t), aref, 0); + TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0); if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ J->base[dst+i] = tr; } @@ -2044,7 +2044,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) vbase = emitir(IRT(IR_ADD, IRT_PTR), vbase, lj_ir_kint(J, frofs-8)); t = itype2irt(&J->L->base[idx-2-nvararg]); aref = emitir(IRT(IR_AREF, IRT_PTR), vbase, tridx); - tr = emitir(IRTG(IR_ALOAD, t), aref, 0); + tr = emitir(IRTG(IR_VLOAD, t), aref, 0); if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ } J->base[dst-2] = tr;