From 89b82ef70949279675640085b4b71bd165502c14 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 3 Dec 2024 20:43:15 +0300 Subject: [PATCH] Fix GH-16996: 8.4 tracing JIT phpseclib failures (#17030) * Fix GH-16996: 8.4 tracing JIT phpseclib failures This prevents conflicts caused by spilling to bound PHP stack slots by creating copies. * Fix build --- ext/opcache/jit/zend_jit_ir.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index beab53894a1b8..f9e78368a2476 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -1332,8 +1332,16 @@ static void zend_jit_def_reg(zend_jit_ctx *jit, zend_jit_addr addr, ir_ref val) ZEND_ASSERT(jit->ra && jit->ra[var].ref == IR_NULL); /* Negative "var" has special meaning for IR */ - if (val > 0 && !zend_jit_spilling_may_cause_conflict(jit, var, val)) { - val = ir_bind(&jit->ctx, -EX_NUM_TO_VAR(jit->ssa->vars[var].var), val); + if (val > 0) { + if (jit->ctx.binding) { + ir_ref old = ir_binding_find(&jit->ctx, val); + if (old && old != -EX_NUM_TO_VAR(jit->ssa->vars[var].var)) { + val = ir_emit2(&jit->ctx, IR_OPT(IR_COPY, jit->ctx.ir_base[val].type), val, 1); + } + } + if (!zend_jit_spilling_may_cause_conflict(jit, var, val)) { + val = ir_bind(&jit->ctx, -EX_NUM_TO_VAR(jit->ssa->vars[var].var), val); + } } jit->ra[var].ref = val;