-
Notifications
You must be signed in to change notification settings - Fork 7.9k
8.4 function JIT overflow bug #16984
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I can reproduce this, and I managed to reduce this to a standalone test case: <?php
final class Test {
public int $integer = -1;
public function foo(int $x) {
return $x;
}
}
function foo(Test $test, int $value) {
$val = $test->foo($value);
if ($val <= PHP_INT_MAX) {
$test->integer = $val;
}
}
function main() {
$test = new Test;
foo($test, 9223372036854775806);
foo($test, 9223372036854775807); // Also reproduces without this call, but this imitates the psalm code
var_dump($test->integer);
}
main(); Run with: Without JIT it prints |
I tried tackling this, and I figured out it was something related to diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
index f1b02ecbc4e..411d71b64d0 100644
--- a/ext/opcache/jit/zend_jit_ir.c
+++ b/ext/opcache/jit/zend_jit_ir.c
@@ -6775,10 +6775,10 @@ static ir_ref zend_jit_cmp_long_long(zend_jit_ctx *jit,
if (smart_branch_opcode && !exit_addr) {
if (smart_branch_opcode == ZEND_JMPZ ||
smart_branch_opcode == ZEND_JMPZ_EX) {
- return jit_IF_ex(jit, IR_FALSE, result ? target_label : target_label2);
+ return jit_IF_ex(jit, result ? IR_TRUE : IR_FALSE, target_label2);
} else if (smart_branch_opcode == ZEND_JMPNZ ||
smart_branch_opcode == ZEND_JMPNZ_EX) {
- return jit_IF_ex(jit, IR_TRUE, result ? target_label : target_label2);
+ return jit_IF_ex(jit, result ? IR_TRUE : IR_FALSE, target_label);
} else {
ZEND_UNREACHABLE();
}
Although I'm a bit confused why this variant works and the original code does not. |
@nielsdos Thanks for the fix! |
I'm afraid this is indeed the case because the code generation is identical if I switch target_label and target_label2 in my patch; that is unexpected. |
I've found the real bug. When diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
index e4b68d23520..beab53894a1 100644
--- a/ext/opcache/jit/zend_jit_ir.c
+++ b/ext/opcache/jit/zend_jit_ir.c
@@ -7204,9 +7204,9 @@ static int zend_jit_cmp(zend_jit_ctx *jit,
while (n) {
n--;
- ir_IF_TRUE(end_inputs->refs[n]);
+ jit_IF_TRUE_FALSE_ex(jit, end_inputs->refs[n], label);
ir_END_list(true_inputs);
- ir_IF_FALSE(end_inputs->refs[n]);
+ jit_IF_TRUE_FALSE_ex(jit, end_inputs->refs[n], label2);
ir_END_list(false_inputs);
}
ir_MERGE_list(true_inputs); |
Description
Running:
in https://github.com/danog/jit_bugs/ causes a test failure only with function JIT on x86-64-v4
ping @dstogov
PHP Version
nigtly
Operating System
No response
The text was updated successfully, but these errors were encountered: