[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 --- Comment #6 from Jakub Jelinek --- Author: jakub Date: Fri Mar 10 07:53:57 2017 New Revision: 246021 URL: https://gcc.gnu.org/viewcvs?rev=246021&root=gcc&view=rev Log: PR tree-optimization/77975 * tree-ssa-loop-niter.c (get_base_for): Allow phi argument from latch edge to be constant. (get_val_for): For constant x return it. Formatting fix. (loop_niter_by_eval): Avoid pointless looping if the next iteration would use the same bases as the current one. * gcc.dg/pr77975.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr77975.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-loop-niter.c
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 --- Comment #5 from rguenther at suse dot de --- On Thu, 9 Mar 2017, jakub at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 > > Jakub Jelinek changed: > >What|Removed |Added > > CC||jakub at gcc dot gnu.org > > --- Comment #4 from Jakub Jelinek --- > 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. It's been some time but I think I have tested my patch and it failed somewhere, but maybe I just thought it was too simple.
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek --- 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.
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 Jakub Jelinek changed: What|Removed |Added Target Milestone|6.3 |6.4 --- Comment #3 from Jakub Jelinek --- GCC 6.3 is being released, adjusting target milestone.
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 Richard Biener changed: What|Removed |Added Priority|P3 |P2 CC||rguenth at gcc dot gnu.org
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 --- Comment #2 from Richard Biener --- > Proved that loop 1 iterates 2 times using brute force. so the question is why that doesn't work for the new form (and this is what we should fix). Because static gphi * get_base_for (struct loop *loop, tree x) { ... init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop)); if (TREE_CODE (next) != SSA_NAME) return NULL; Index: gcc/tree-ssa-loop-niter.c === --- gcc/tree-ssa-loop-niter.c (revision 241148) +++ gcc/tree-ssa-loop-niter.c (working copy) @@ -2545,13 +2551,11 @@ get_base_for (struct loop *loop, tree x) init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop)); - if (TREE_CODE (next) != SSA_NAME) -return NULL; - if (!is_gimple_min_invariant (init)) return NULL; - if (chain_of_csts_start (loop, next) != phi) + if (TREE_CODE (next) == SSA_NAME + && chain_of_csts_start (loop, next) != phi) return NULL; return phi; @@ -2574,6 +2578,8 @@ get_val_for (tree x, tree base) if (!x) return base; + else if (is_gimple_min_invariant (x)) +return x; stmt = SSA_NAME_DEF_STMT (x); if (gimple_code (stmt) == GIMPLE_PHI) fixes it. But I think it's not correct as it misses the intermediate stmt evaluations. Some more refactoring (passing in the PHI def to get_val_for) is necessary I think.
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 Martin Liška changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2016-10-14 CC||law at gcc dot gnu.org, ||marxin at gcc dot gnu.org Ever confirmed|0 |1 Known to fail||6.1.0, 7.0 --- Comment #1 from Martin Liška --- Confirmed, started with r232361. IV canon can't identify number of iterations: Before: ;; Function f7 (f7, funcdef_no=11, decl_uid=2279, cgraph_uid=11, symbol_order=11) Proved that loop 1 iterates 2 times using brute force. Loop 1 iterates 2 times. Loop 1 iterates at most 2 times. Loop 1 likely iterates at most 2 times. Added canonical iv to loop 1, 2 iterations. f7 () { unsigned int a; unsigned int c; struct _IO_FILE * stderr.0_1; unsigned int ivtmp_2; unsigned int ivtmp_3; : : # c_14 = PHI # a_15 = PHI # ivtmp_3 = PHI a_5 = a_15 >> 1; c_6 = c_14 + 1; ivtmp_2 = ivtmp_3 - 1; if (ivtmp_2 != 0) goto ; else goto ; : goto ; : # c_4 = PHI stderr.0_1 = stderr; fprintf (stderr.0_1, "cnt: %d\n", c_4); return 0; } After: ;; Function f7 (f7, funcdef_no=11, decl_uid=2279, cgraph_uid=11, symbol_order=11) f7 () { unsigned int a; unsigned int c; struct _IO_FILE * stderr.0_1; : : # c_14 = PHI # a_15 = PHI <1(4), 3(2)> a_5 = a_15 >> 1; c_6 = c_14 + 1; if (a_5 != 0) goto ; else goto ; : goto ; : # c_4 = PHI stderr.0_1 = stderr; fprintf (stderr.0_1, "cnt: %d\n", c_4); return 0; } Diff: # a_15 = PHI # a_15 = PHI <1(4), 3(2)> Maybe ivcanon can handle such degenerated situation? Thoughts?
[Bug tree-optimization/77975] [6/7 Regression] Missed optimization for some small constants
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77975 Andrew Pinski changed: What|Removed |Added Keywords||missed-optimization Component|c |tree-optimization Target Milestone|--- |6.3 Summary|[6 / 7 Regression] Missed |[6/7 Regression] Missed |optimization for some small |optimization for some small |constants |constants