Bug #80959 [Ver->Csd]: infinite loop in building cfg during JIT compilation
Edit report at https://bugs.php.net/bug.php?id=80959&edit=1
ID: 80959
Updated by: git@php.net
Reported by: zengyhkyle at asu dot edu
Summary: infinite loop in building cfg during JIT compilation
-Status: Verified
+Status: Closed
Type: Bug
Package: JIT
Operating System: Linux
PHP Version: 8.0.4RC1
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of dstogov
Revision: https://github.com/php/php-src/commit/a9991fbf281ae49c11780bc5bc43df4b1a080d37
Log: Fixed Bug #80959 (infinite loop in building cfg during JIT compilation)
Previous Comments:
------------------------------------------------------------------------
[2021-04-16 09:50:26] nikic@php.net
Possible patch to avoid infinite loop: https://gist.github.com/nikic/072a365f6fe2f07e523757de0eb6c61f
It uses missing idom to identify blocks that are unreachable or only abnormally reachable and skips
the loop header assignment for them.
Of course, that doesn't fix the problem that computed results for try/catch may be incorrect,
as we're working on an inaccurate CFG.
------------------------------------------------------------------------
[2021-04-16 09:25:52] nikic@php.net
Though it would be great if we could not run loop identification in the first place if a function
has try/catch. In that case we don't perform SSA construction or register allocation, which
need this for correctness. It seems like the only places that use the information in that case is
timeout checks and hot loop counters. Maybe we just want to pessimize those in the presence of
try/catch?
------------------------------------------------------------------------
[2021-04-16 09:12:46] nikic@php.net
CFG for reference: https://gist.github.com/nikic/84d11192df4d7b6cc42f971c7d15920b
The core problem here is that BB5 and BB6 are not reachable from entry through normal edges (they
have domtree level 0 and will be processed last). They are reachable in the reverse graph though,
which is traversed when loop headers are assigned. We end up with BB3 having BB6 as loop header, and
BB6 having BB3 as loop header, causing an infinite loop.
There's probably two separate problems here: We should be treating unreachable code more
gracefully, and we should not be treating this code as unreachable in the first place, though
I'm not sure what the right way to handle unwind edges would be right now.
------------------------------------------------------------------------
[2021-04-16 08:23:48] nikic@php.net
Nice find! Here's a somewhat reduced version:
<?php
function test($a, $b) {
echo "Start\n";
do {
$i++;
try {
continue;
} catch (Exception $e) {
}
do {
$j++;
} while ($j < $b);
} while ($i < $a);
echo "Done\n";
}
test();
------------------------------------------------------------------------
[2021-04-15 22:34:42] zengyhkyle at asu dot edu
in our experiment, the execution is stuck at function zend_cfg_identify_loops
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=80959
--
Edit this bug report at https://bugs.php.net/bug.php?id=80959&edit=1
Thread (8 messages)