]> granicus.if.org Git - php/commitdiff
Fix bug #79358: JIT miscompile in composer
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 9 Mar 2020 11:55:14 +0000 (12:55 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 9 Mar 2020 11:55:14 +0000 (12:55 +0100)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_x86.h
ext/opcache/tests/jit/bug79358.phpt [new file with mode: 0644]

index 07d82b89de808bbbc1611f4a72caef5ae9f101d7..1b3fbcee2f2c94c08671372e2cb75338452fe453 100644 (file)
@@ -2474,7 +2474,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                        case ZEND_IS_NOT_EQUAL:
                                        case ZEND_IS_SMALLER:
                                        case ZEND_IS_SMALLER_OR_EQUAL:
-                                       case ZEND_CASE:
+                                       case ZEND_CASE: {
+                                               res_addr = RES_REG_ADDR();
                                                if ((opline->result_type & IS_TMP_VAR)
                                                 && (i + 1) <= end
                                                 && ((opline+1)->opcode == ZEND_JMPZ
@@ -2488,6 +2489,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        smart_branch_opcode = (opline+1)->opcode;
                                                        target_label = ssa->cfg.blocks[b].successors[0];
                                                        target_label2 = ssa->cfg.blocks[b].successors[1];
+                                                       /* For EX variant write into the result of EX opcode. */
+                                                       if ((opline+1)->opcode == ZEND_JMPZ_EX
+                                                                       || (opline+1)->opcode == ZEND_JMPNZ_EX) {
+                                                               res_addr = OP_REG_ADDR(opline + 1, result_type, result, result_def);
+                                                       }
                                                } else {
                                                        smart_branch_opcode = 0;
                                                        target_label = target_label2 = (uint32_t)-1;
@@ -2495,12 +2501,13 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                if (!zend_jit_cmp(&dasm_state, opline, op_array,
                                                                OP1_INFO(), OP1_REG_ADDR(),
                                                                OP2_INFO(), OP2_REG_ADDR(),
-                                                               RES_REG_ADDR(),
+                                                               res_addr,
                                                                zend_may_throw(opline, op_array, ssa),
                                                                smart_branch_opcode, target_label, target_label2)) {
                                                        goto jit_failure;
                                                }
                                                goto done;
+                                       }
                                        case ZEND_IS_IDENTICAL:
                                        case ZEND_IS_NOT_IDENTICAL:
                                                if ((opline->result_type & IS_TMP_VAR)
index b3806036f6d0d5ce7f2efc1e4b33239a969f0154..6a3b4551051a6b4c97d424784b7f8820a8d0161d 100644 (file)
@@ -270,7 +270,7 @@ static zend_always_inline zend_jit_addr _zend_jit_decode_op(zend_uchar op_type,
 #define OP2_ADDR() \
        OP_ADDR(opline, op2_type, op2)
 #define RES_ADDR() \
-       OP_ADDR(opline, op2_type, op2)
+       OP_ADDR(opline, result_type, result)
 #define OP1_DATA_ADDR() \
        OP_ADDR(opline + 1, op1_type, op1)
 
diff --git a/ext/opcache/tests/jit/bug79358.phpt b/ext/opcache/tests/jit/bug79358.phpt
new file mode 100644 (file)
index 0000000..1d79404
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #79358: JIT miscompile in composer
+--FILE--
+<?php
+
+function test(int $x) {
+    return ($x > 0xdead && unimportant()) ||
+           ($x < 0xbeef && unimportant());
+}
+
+var_dump(test(0xcccc));
+
+?>
+--EXPECT--
+bool(false)