com php-src: Fix optimization of $i = $i++: ext/opcac he/Optimizer/dfa_pass.c ext/opcache/tests/ssa_bug_0 06.phpt
| From: | Nikita Popov | Date: | Sun, 17 Jul 2016 20:47:49 +0000 |
| Subject: | com php-src: Fix optimization of $i = $i++: ext/opcac he/Optimizer/dfa_pass.c ext/opcache/tests/ssa_bug_0 06.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-93072@lists.php.net to get a copy of this message | ||
Commit: 42260325a47480bc97f7dceb2ac5d8e8d7799928
Author: Nikita Popov <nikic@php.net> Sun, 17 Jul 2016 22:47:49 +0200
Parents: e1496f45fd53c60df8755edfd556aa733fc4810d
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=42260325a47480bc97f7dceb2ac5d8e8d7799928
Log:
Fix optimization of $i = $i++
Changed paths:
M ext/opcache/Optimizer/dfa_pass.c
A ext/opcache/tests/ssa_bug_006.phpt
Diff:
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index a64619b..a99d50f 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass..c
@@ -343,7 +343,8 @@ static inline zend_bool can_elide_return_type_check(
return 1;
}
-static zend_bool opline_supports_assign_contraction(zend_ssa *ssa, zend_op *opline, int src_var) {
+static zend_bool opline_supports_assign_contraction(
+ zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) {
if (opline->opcode == ZEND_NEW) {
/* see Zend/tests/generators/aborted_yield_during_new.phpt */
return 0;
@@ -358,6 +359,12 @@ static zend_bool opline_supports_assign_contraction(zend_ssa *ssa, zend_op
*opli
return !((type & MAY_BE_ANY) & ~simple);
}
+ if (opline->opcode == ZEND_POST_INC || opline->opcode == ZEND_POST_DEC) {
+ /* POST_INC/DEC write the result variable before performing the inc/dec. For $i = $i++
+ * eliding the temporary variable would thus yield an incorrect result. */
+ return opline->op1_type != IS_CV || opline->op1.var != cv_var;
+ }
+
return 1;
}
@@ -476,7 +483,8 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
&& !ssa->vars[src_var].phi_use_chain
&& !ssa->vars[src_var].sym_use_chain
&& opline_supports_assign_contraction(
- ssa, &op_array->opcodes[ssa->vars[src_var].definition], src_var)
+ ssa, &op_array->opcodes[ssa->vars[src_var].definition],
+ src_var, opline->op1.var)
) {
int op_2 = ssa->vars[src_var].definition;
diff --git a/ext/opcache/tests/ssa_bug_006.phpt b/ext/opcache/tests/ssa_bug_006.phpt
new file mode 100644
index 0000000..624c1e0
--- /dev/null
+++ b/ext/opcache/tests/ssa_bug_006.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Incorrect optimization of $i = $i++
+--FILE--
+<?php
+
+function test() {
+ $i = 1;
+ $i = $i++;
+ var_dump($i);
+
+ $i = 1;
+ $i = $i--;
+ var_dump($i);
+}
+test();
+
+?>
+--EXPECT--
+int(1)
+int(1)