@@ -436,21 +436,14 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
436436 Tsource [VAR_NUM (opline -> op1 .var )] = NULL ;
437437 break ;
438438 }
439- ZEND_FALLTHROUGH ;
440-
441- case ZEND_IS_EQUAL :
442- case ZEND_IS_NOT_EQUAL :
443439 if (opline -> op1_type == IS_CONST &&
444- opline -> op2_type == IS_CONST ) {
440+ opline -> op2_type == IS_CONST ) {
445441 goto optimize_constant_binary_op ;
446- }
447- /* IS_EQ(TRUE, X) => BOOL(X)
448- * IS_EQ(FALSE, X) => BOOL_NOT(X)
449- * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X)
450- * IS_NOT_EQ(FALSE, X) => BOOL(X)
451- * CASE(TRUE, X) => BOOL(X)
452- * CASE(FALSE, X) => BOOL_NOT(X)
453- */
442+ }
443+ /*
444+ * CASE(TRUE, X) => BOOL(X)
445+ * CASE(FALSE, X) => BOOL_NOT(X)
446+ */
454447 if (opline -> op1_type == IS_CONST &&
455448 (Z_TYPE (ZEND_OP1_LITERAL (opline )) == IS_FALSE ||
456449 Z_TYPE (ZEND_OP1_LITERAL (opline )) == IS_TRUE )) {
@@ -464,19 +457,34 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
464457 SET_UNUSED (opline -> op2 );
465458 ++ (* opt_count );
466459 goto optimize_bool ;
467- } else if (opline -> op2_type == IS_CONST &&
468- (Z_TYPE (ZEND_OP2_LITERAL (opline )) == IS_FALSE ||
469- Z_TYPE (ZEND_OP2_LITERAL (opline )) == IS_TRUE )) {
470- /* Optimization of comparison with "null" is not safe,
471- * because ("0" == null) is not equal to !("0")
472- */
473- opline -> opcode =
474- ((opline -> opcode != ZEND_IS_NOT_EQUAL ) == ((Z_TYPE (ZEND_OP2_LITERAL (opline ))) == IS_TRUE )) ?
475- ZEND_BOOL : ZEND_BOOL_NOT ;
476- SET_UNUSED (opline -> op2 );
477- ++ (* opt_count );
478- goto optimize_bool ;
460+ } else if (opline -> op2_type == IS_CONST &&
461+ (Z_TYPE (ZEND_OP2_LITERAL (opline )) == IS_FALSE ||
462+ Z_TYPE (ZEND_OP2_LITERAL (opline )) == IS_TRUE )) {
463+ /* Optimization of comparison with "null" is not safe,
464+ * because ("0" == null) is not equal to !("0")
465+ */
466+ opline -> opcode =
467+ ((opline -> opcode != ZEND_IS_NOT_EQUAL ) == ((Z_TYPE (ZEND_OP2_LITERAL (opline ))) == IS_TRUE )) ?
468+ ZEND_BOOL : ZEND_BOOL_NOT ;
469+ SET_UNUSED (opline -> op2 );
470+ ++ (* opt_count );
471+ goto optimize_bool ;
472+ }
473+ break ;
474+
475+ case ZEND_IS_EQUAL :
476+ case ZEND_IS_NOT_EQUAL :
477+ if (opline -> op1_type == IS_CONST &&
478+ opline -> op2_type == IS_CONST ) {
479+ goto optimize_constant_binary_op ;
479480 }
481+ /* IS_EQ(TRUE, X) => BOOL(X)
482+ * IS_EQ(FALSE, X) => BOOL_NOT(X)
483+ * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X)
484+ * IS_NOT_EQ(FALSE, X) => BOOL(X)
485+ * Those optimizations are not safe if the other operand end up being NAN
486+ * as BOOL/BOOL_NOT will warn which IS_EQUAL/IS_NOT_EQUAL do not.
487+ */
480488 break ;
481489 case ZEND_IS_IDENTICAL :
482490 if (opline -> op1_type == IS_CONST &&
0 commit comments