History log of /PHP-8.4/ext/opcache/tests/opt/gh10008.phpt (Results 1 – 3 of 3)
Revision Date Author Comments
# 798b9d09 02-Nov-2023 Dmitry Stogov

Fixed GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT


# 643c4ba4 29-Sep-2023 Niels Dossche <7771979+nielsdos@users.noreply.github.com>

Revert "Fix GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT"

Although it passes CI on 8.1, it causes CI failures in the JIT on 8.2 and
higher.
See https:

Revert "Fix GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT"

Although it passes CI on 8.1, it causes CI failures in the JIT on 8.2 and
higher.
See https://github.com/php/php-src/actions/runs/6357716718/job/17269225001

This reverts commit e72fc12058dc0ee7bfe534dfa3daf46f3b357190.

show more ...


# e72fc120 26-Sep-2023 Niels Dossche <7771979+nielsdos@users.noreply.github.com>

Fix GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT

This test triggers narrowing for two ops: first ZEND_ADD_ARRAY_ELEMENT,
and then ZEND_ASSIGN.

Th

Fix GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT

This test triggers narrowing for two ops: first ZEND_ADD_ARRAY_ELEMENT,
and then ZEND_ASSIGN.

The type inference happens in the following order:
1) The ZEND_ADD_ARRAY_ELEMENT infers type 0x40e04080 (packed flag is set),
arr_type=0 at this point because it hasn't been set by ZEND_INIT_ARRAY yet.
2) The ZEND_INIT_ARRAY infers type 0x40804080
3) The ZEND_ADD_ARRAY_ELEMENT infers type 0x40e04080, arr_type=0x40804080,
which does not have the packed flag set while the existing result of
ZEND_ADD_ARRAY_ELEMENT has the packed flag set.

This seems to occur because of the phi node introduced by the while
loop. If I remove the loop the problem goes away.

As Arnaud noted, this seems to be caused by a too wide type inference
for arr_type==0. We should keep the invariant that if x>=y then
key_type(x) >= key_type(y).
If we write the possible results down in a table we get:

```
arr_type resulting key type
--------------- --------------------------------------------------------------------------
HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH
PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
0 -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
```

As we can see, `HASH_ONLY > 0` but
`MAY_BE_ARRAY_NUMERIC_HASH < MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED`,
which violates the invariant.
Instead if we modify the zero case to have MAY_BE_ARRAY_NUMERIC_HASH instead,
we get the following table which satisfies the invariant.

```
arr_type resulting key type
--------------- --------------------------------------------------------------------------
HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH
PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
0 -> MAY_BE_ARRAY_NUMERIC_HASH
```

Broke in 1ffbb73.
Closes GH-10294.

show more ...