Skip to content

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Aug 24, 2025

@Girgias Girgias force-pushed the 8.5-warn-nan-coercion branch from 564b005 to 8da693f Compare August 29, 2025 09:11
@Girgias Girgias force-pushed the 8.5-warn-nan-coercion branch from 8da693f to 729488f Compare August 29, 2025 15:06
@Girgias Girgias requested a review from arnaud-lb August 29, 2025 15:38
Copy link

AWS x86_64 (c7i.24xl)

Attribute Value
Environment aws
Runner host
Instance type c7i.metal-24xl (dedicated)
Architecture x86_64
CPU 48 cores
CPU settings disabled deeper C-states, disabled turbo boost, disabled hyper-threading
RAM 188 GB
Kernel 6.1.147-172.266.amzn2023.x86_64
OS Amazon Linux 2023.8.20250818
GCC 14.2.1
Time 2025-08-29 17:20:09 UTC

Laravel 12.2.0 demo app - 100 consecutive runs, 50 warmups, 100 requests (sec)

PHP Min Max Std dev Rel std dev % Mean Mean diff % Median Median diff % Skew P-value Instr count Memory
PHP - baseline@fc46 0.46565 0.46818 0.00045 0.10% 0.46637 0.00% 0.46629 0.00% 1.515 0.999 176423932 44.01 MB
PHP - 8.5-warn-nan-coercion 0.45876 0.46679 0.00075 0.16% 0.46494 -0.31% 0.46499 -0.28% -5.442 0.000 176485965 44.07 MB

Symfony 2.7.0 demo app - 100 consecutive runs, 50 warmups, 100 requests (sec)

PHP Min Max Std dev Rel std dev % Mean Mean diff % Median Median diff % Skew P-value Instr count Memory
PHP - baseline@fc46 0.72046 0.73259 0.00155 0.21% 0.72261 0.00% 0.72217 0.00% 3.109 0.999 287234974 40.16 MB
PHP - 8.5-warn-nan-coercion 0.72253 0.72854 0.00100 0.14% 0.72405 0.20% 0.72384 0.23% 1.831 0.000 287280133 40.53 MB

Wordpress 6.2 main page - 100 consecutive runs, 20 warmups, 20 requests (sec)

PHP Min Max Std dev Rel std dev % Mean Mean diff % Median Median diff % Skew P-value Instr count Memory
PHP - baseline@fc46 0.57464 0.58357 0.00228 0.39% 0.58060 0.00% 0.58151 0.00% -1.225 0.999 1119139470 43.91 MB
PHP - 8.5-warn-nan-coercion 0.57682 0.58512 0.00218 0.37% 0.58209 0.26% 0.58298 0.25% -1.361 0.000 1119813967 43.91 MB

bench.php - 100 consecutive runs, 10 warmups, 2 requests (sec)

PHP Min Max Std dev Rel std dev % Mean Mean diff % Median Median diff % Skew P-value Instr count Memory
PHP - baseline@fc46 0.42476 0.55444 0.02724 6.28% 0.43407 0.00% 0.42786 0.00% 4.179 0.999 2020744423 26.98 MB
PHP - 8.5-warn-nan-coercion 0.42534 0.58863 0.03210 7.34% 0.43703 0.68% 0.42765 -0.05% 3.477 0.582 2020694323 27.05 MB

Comment on lines +126 to +146
case ZEND_CAST: {
uint32_t t1 = OP1_INFO();
/* Cast from NAN emits warning */
if (t1 & MAY_BE_DOUBLE) {
return true;
}
if (t1 & MAY_BE_ARRAY) {
/* Array cast to string emits warning */
return opline->extended_value == IS_STRING;
}
return false;
}
case ZEND_BOOL:
case ZEND_BOOL_NOT: {
uint32_t t1 = OP1_INFO();
/* Cast from NAN emits warning */
if (t1 & MAY_BE_DOUBLE) {
return true;
}
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only zend_may_throw() needs to be modified:

 * * We separate intrinsic side-effects from potential side-effects in the form of notices thrown
 *    by the instruction (in case we want to make this configurable). See may_have_side_effects() and
 * zend_may_throw().

|| opcode == ZEND_BOOL
|| opcode == ZEND_BOOL_NOT
) {
/* BW_NOT on string does not convert the string into an integer. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should be updated :)

Comment on lines +10032 to +10033
opcode == ZEND_IS_EQUAL
|| opcode == ZEND_IS_NOT_EQUAL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not unary

@@ -16,6 +16,7 @@
+----------------------------------------------------------------------+
*/

#include "../../../Zend/zend_portability.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "../../../Zend/zend_portability.h"
#include "Zend/zend_portability.h"

@@ -7728,7 +7728,14 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32
if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE)));
ir_IF_TRUE(if_double);
}
ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to avoid calling zend_is_true() during compilation above when the value is a const nan, otherwise we emit two warnings here: (during tracing, then while compiling the trace)

echo (bool)NAN;

@@ -7728,7 +7728,14 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32
if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE)));
ir_IF_TRUE(if_double);
}
ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0));

ir_ref dval = jit_Z_DVAL(jit, op1_addr);ir_ref is_nan = ir_NE(dval, dval);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ir_ref dval = jit_Z_DVAL(jit, op1_addr);ir_ref is_nan = ir_NE(dval, dval);
ir_ref dval = jit_Z_DVAL(jit, op1_addr);
ir_ref is_nan = ir_NE(dval, dval);

@@ -2566,6 +2567,11 @@ static void ZEND_FASTCALL zend_jit_invalid_array_access(zval *container)
zend_error(E_WARNING, "Trying to access array offset on %s", zend_zval_value_name(container));
}

static void ZEND_FASTCALL zend_jit_check_nan_to_bool_coercion(void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static void ZEND_FASTCALL zend_jit_check_nan_to_bool_coercion(void)
static void ZEND_FASTCALL zend_jit_nan_coerced_to_type_warning(void)

Comment on lines +485 to +486
* Those optimizations are not safe if the other operand end up being NAN
* as BOOL/BOOL_NOT will warn which IS_EQUAL/IS_NOT_EQUAL do not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Triggered a benchmark to check the effect of this: valgrind shows no regression (changes are under 0.0x%).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants