IRIns *ir = (xr->o == IR_HREFK || xr->o == IR_AREF) ? IR(xr->op1) : xr;
IRRef tab = ir->op1;
ir = IR(tab);
- if (ir->o == IR_TNEW || (ir->o == IR_TDUP && irref_isk(xr->op2))) {
+ if ((ir->o == IR_TNEW || (ir->o == IR_TDUP && irref_isk(xr->op2))) &&
+ fwd_aa_tab_clear(J, tab, tab)) {
/* A NEWREF with a number key may end up pointing to the array part.
** But it's referenced from HSTORE and not found in the ASTORE chain.
+ ** Or a NEWREF may rehash the table and move unrelated number keys.
** For now simply consider this a conflict without forwarding anything.
*/
if (xr->o == IR_AREF) {
TRef key = ix->key;
if (tref_isinteger(key)) /* NEWREF needs a TValue as a key. */
key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
- xref = emitir(IRT(IR_NEWREF, IRT_P32), ix->tab, key);
+ else if (tref_isnumber(key) && tref_isk(key) && tvismzero(&ix->keyv))
+ key = lj_ir_knum_zero(J); /* Canonicalize -0.0 to +0.0. */
+ xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
keybarrier = 0; /* NEWREF already takes care of the key barrier. */
+#ifdef LUAJIT_ENABLE_TABLE_BUMP
+ if ((J->flags & JIT_F_OPT_SINK)) /* Avoid a separate flag. */
+ rec_idx_bump(J, ix);
+#endif
}
} else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
/* Cannot derive that the previous value was non-nil, must do checks. */