https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 40936 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40936&action=edit gcc7-pr77975.patch Actually I think your patch is fully correct. If next[j] (the phi argument from the latch edge) is constant in addition to val[j] (the phi argument from preheader edge), then in the val[j] = get_val_for (next[j], val[j]); we want to set val[j] = next[j];, the processing of the statements in the loop is then done in the other get_val_for call - the aval[j] = get_val_for (op[j], val[j]); So, the first time we evaluate the statements for base of val[j] and second time for base of next[j] if both are constants. The only thing I've added in addition to some comment/formatting changes and testcase is a compile time optimization, MAX_ITERATIONS_TO_TRACK can be very large (I'm surprised we don't limit also the number of statements between op and the header phi node, there could be hundreds of thousands of them), but if the phi contains two same constants, then it is enough to do one iteration of the loop, if two different constants, then two, all further work is wasted.