Commit e72fc12
committed
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.1 parent 2a7f23e commit e72fc12
File tree
3 files changed
+53
-9
lines changed- Zend/Optimizer
- ext/opcache/tests/opt
3 files changed
+53
-9
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1926 | 1926 | | |
1927 | 1927 | | |
1928 | 1928 | | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
1929 | 1944 | | |
1930 | 1945 | | |
1931 | 1946 | | |
| |||
1939 | 1954 | | |
1940 | 1955 | | |
1941 | 1956 | | |
1942 | | - | |
| 1957 | + | |
1943 | 1958 | | |
1944 | 1959 | | |
1945 | 1960 | | |
1946 | 1961 | | |
1947 | 1962 | | |
1948 | | - | |
| 1963 | + | |
1949 | 1964 | | |
1950 | 1965 | | |
1951 | 1966 | | |
| |||
1954 | 1969 | | |
1955 | 1970 | | |
1956 | 1971 | | |
1957 | | - | |
| 1972 | + | |
1958 | 1973 | | |
1959 | 1974 | | |
1960 | 1975 | | |
| |||
3254 | 3269 | | |
3255 | 3270 | | |
3256 | 3271 | | |
3257 | | - | |
3258 | | - | |
| 3272 | + | |
3259 | 3273 | | |
3260 | 3274 | | |
3261 | 3275 | | |
3262 | 3276 | | |
3263 | 3277 | | |
3264 | 3278 | | |
3265 | 3279 | | |
3266 | | - | |
3267 | | - | |
| 3280 | + | |
3268 | 3281 | | |
3269 | 3282 | | |
3270 | 3283 | | |
| |||
3275 | 3288 | | |
3276 | 3289 | | |
3277 | 3290 | | |
3278 | | - | |
3279 | | - | |
| 3291 | + | |
3280 | 3292 | | |
3281 | 3293 | | |
3282 | 3294 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
0 commit comments