On Tue, Mar 21, 2017 at 08:38:20AM +1000, Richard Henderson wrote: > On 03/21/2017 07:15 AM, Jakub Jelinek wrote: > > Not really sure what we should do if both i1 and i2 are frame related, shall > > we check for each of the CFA reg notes if they are available and equal? > > Or punt if either of the insns is frame related? > > I would punt if either is frame related.
Ok, I'll test then the following patch and gather some statistic on how often we trigger this. > As an aside, if the length of "blockage" is corrected to 0, does > cross-jumping skip this case? Because replacing a simple_return with a > direct branch to a simple_return is not a win. But of course at the moment > cross-jumping thinks it is eliminating the second blockage as well... I don't think cross-jumping counts anything but the number of active_insn_p, at least I can't find any get_attr_length uses outside of final.c in the generic code (and just very few (shrink-wrap and bb-reorder) get_attr_min_length calls). So shall cross-jumping only count ifdef HAVE_attr_length insns with get_attr_length > 0? 2017-03-21 Jakub Jelinek <ja...@redhat.com> PR target/80102 * cfgcleanup.c (old_insns_match_p): Don't cross-jump frame related insns. * g++.dg/opt/pr80102.C: New test. --- gcc/cfgcleanup.c.jj 2017-01-09 22:46:03.000000000 +0100 +++ gcc/cfgcleanup.c 2017-03-20 13:55:58.823983848 +0100 @@ -1149,6 +1149,10 @@ old_insns_match_p (int mode ATTRIBUTE_UN else if (p1 || p2) return dir_none; + /* Do not allow cross-jumping frame related insns. */ + if (RTX_FRAME_RELATED_P (i1) || RTX_FRAME_RELATED_P (i2)) + return dir_none; + p1 = PATTERN (i1); p2 = PATTERN (i2); --- gcc/testsuite/g++.dg/opt/pr80102.C.jj 2017-03-20 14:34:01.223434828 +0100 +++ gcc/testsuite/g++.dg/opt/pr80102.C 2017-03-20 14:33:36.000000000 +0100 @@ -0,0 +1,14 @@ +// PR target/80102 +// { dg-do compile } +// { dg-options "-fnon-call-exceptions -Os" } +// { dg-additional-options "-mminimal-toc" { target { powerpc*-*-* && lp64 } } } + +struct B { float a; B (float c) { for (int g; g < c;) ++a; } }; +struct D { D (B); }; + +int +main () +{ + B (1.0); + D e (0.0), f (1.0); +} Jakub