]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR67355] drop dummy zero from reverse VTA ops, fix infinite recursion
authorAlexandre Oliva <aoliva@redhat.com>
Sun, 13 Dec 2015 20:37:26 +0000 (20:37 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sun, 13 Dec 2015 20:37:26 +0000 (20:37 +0000)
VTA's cselib expression hashing compares expressions with the same
hash before adding them to the hash table.  When there is a collision
involving a self-referencing expression, we could get infinite
recursion, in spite of the cycle breakers already in place.  The
problem is currently latent in the trunk, because by chance we don't
get a collision.

Such value cycles are often introduced by reverse_op; most often,
they're indirect, and then value canonicalization takes care of the
cycle, but if the reverse operation simplifies to the original value,
we used to issue a (plus V (const_int 0)), because at some point
adding a plain value V to a location list as a reverse_op equivalence
caused other problems.

This dummy zero, in turn, caused the value canonicalizer to not fully
realize the equivalence, leading to more complex graphs and,
occasionally, to infinite recursion when comparing such
value-plus-zero expressions recursively.

Simply using V solves the infinite recursion from the PR testcase,
since the extra equivalence and the preexisting value canonicalization
together prevent recursion while the unrecognized equivalence
wouldn't, but it exposed another infinite recursion in
memrefs_conflict_p: get_addr had a cycle breaker in place, to skip RTL
referencing values introduced after the one we're examining, but it
wouldn't break the cycle if the value itself appeared in the
expression being examined.

After removing the dummy zero above, this kind of cycle in the
equivalence graph is no longer introduced by VTA itself, but dummy
zeros are also present in generated code, such as in the 32-bit x86's
pro_epilogue_adjust_stack_si_add epilogue insn generated as part of
the builtin longjmp in _Unwind_RaiseException building libgcc's
unwind-dw2.o.  So, break the recursion cycle for them too.

for  gcc/ChangeLog

PR debug/67355
* var-tracking.c (reverse_op): Don't add dummy zero to reverse
ops that simplify back to the original value.
* alias.c (refs_newer_value_p): Cut off recursion for
expressions containing the original value.

From-SVN: r231599

gcc/ChangeLog
gcc/alias.c
gcc/var-tracking.c

index 730c79f118f764bb19b524ef1f00d49051845016..42955284bc35728b56d7a193fdc90cf2434d603a 100644 (file)
@@ -1,3 +1,11 @@
+2015-12-13  Alexandre Oliva <aoliva@redhat.com>
+
+       PR debug/67355
+       * var-tracking.c (reverse_op): Don't add dummy zero to reverse
+       ops that simplify back to the original value.
+       * alias.c (refs_newer_value_p): Cut off recursion for
+       expressions containing the original value.
+
 2015-12-13  Kazu Kirata  <kazu@gcc.gnu.org>
 
        * config/m68k/m68k.md (load feeding clear byte): New peephole2.
index 095b2ade180b7cd09f8c0473201b7945b4fc8256..1ab96008743902f5b05e1ab1ebd483a25fe6adbb 100644 (file)
@@ -2129,7 +2129,7 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
 }
 
 /* Return TRUE if EXPR refers to a VALUE whose uid is greater than
-   that of V.  */
+   (or equal to) that of V.  */
 
 static bool
 refs_newer_value_p (const_rtx expr, rtx v)
@@ -2137,7 +2137,7 @@ refs_newer_value_p (const_rtx expr, rtx v)
   int minuid = CSELIB_VAL_PTR (v)->uid;
   subrtx_iterator::array_type array;
   FOR_EACH_SUBRTX (iter, array, expr, NONCONST)
-    if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid > minuid)
+    if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid)
       return true;
   return false;
 }
index 9185bfd39cf5c033ecf77a16a8894f36a1d52490..07eea841f4443f6c358c466d905679d654cc81ee 100644 (file)
@@ -5774,11 +5774,6 @@ reverse_op (rtx val, const_rtx expr, rtx_insn *insn)
            return;
        }
       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
-      if (ret == val)
-       /* Ensure ret isn't VALUE itself (which can happen e.g. for
-          (plus (reg1) (reg2)) when reg2 is known to be 0), as that
-          breaks a lot of routines during var-tracking.  */
-       ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
       break;
     default:
       gcc_unreachable ();