public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR77544
@ 2016-09-15 12:51 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2016-09-15 12:51 UTC (permalink / raw)
  To: gcc-patches


This fixes an endless recursion through fold-const.c associate code.
While the testcase is fixed if we "properly" split the TREE_CONSTANT
~(unsigned int) (302806 >> 0) into *conp and *minus_lit this runs
into endless recursion during Ada bootstrap as the condition

          /* Only do something if we found more than two objects.  
Otherwise,
             nothing has changed and we risk infinite recursion.  */
          if (ok
              && (2 < ((var0 != 0) + (var1 != 0)
                       + (con0 != 0) + (con1 != 0)
                       + (lit0 != 0) + (lit1 != 0)
                       + (minus_lit0 != 0) + (minus_lit1 != 0))))

is really too simple (when you have var0 and from the above con1 and
minus_lit1 you combine back to the original tree but from three
components).  I suspect this is a latent issue on the path where
we split PLUS/MINUS_EXPRs in split_tree as well (didn't try to come
up with a testcase, sth like x + (&foo + 1) would probably do).

So rather than trying to convince myself about a "better" condition
for the above the following simply restricts the "unfolding" trick
we apply to ~X to the non-TREE_CONSTANT case.  (a condition might
be that we need from any of two vars, two cons or two lit/minus-lit
from the different sources)

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2016-09-15  Richard Biener  <rguenther@suse.de>

	PR middle-end/77544
	* fold-const.c (split_tree): Do not split constant ~X.

	* c-c++-common/torture/pr77544.c: New testcase.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 240153)
--- gcc/fold-const.c	(working copy)
*************** split_tree (location_t loc, tree in, tre
*** 837,851 ****
  	  var = negate_expr (var);
  	}
      }
    else if (TREE_CODE (in) == BIT_NOT_EXPR
  	   && code == PLUS_EXPR)
      {
!       /* -X - 1 is folded to ~X, undo that here.  */
        *minus_litp = build_one_cst (TREE_TYPE (in));
        var = negate_expr (TREE_OPERAND (in, 0));
      }
-   else if (TREE_CONSTANT (in))
-     *conp = in;
    else
      var = in;
  
--- 837,852 ----
  	  var = negate_expr (var);
  	}
      }
+   else if (TREE_CONSTANT (in))
+     *conp = in;
    else if (TREE_CODE (in) == BIT_NOT_EXPR
  	   && code == PLUS_EXPR)
      {
!       /* -X - 1 is folded to ~X, undo that here.  Do _not_ do this
!          when IN is constant.  */
        *minus_litp = build_one_cst (TREE_TYPE (in));
        var = negate_expr (TREE_OPERAND (in, 0));
      }
    else
      var = in;
  
Index: gcc/testsuite/c-c++-common/torture/pr77544.c
===================================================================
*** gcc/testsuite/c-c++-common/torture/pr77544.c	(revision 0)
--- gcc/testsuite/c-c++-common/torture/pr77544.c	(working copy)
***************
*** 0 ****
--- 1,7 ----
+ /* { dg-do compile } */
+ 
+ struct {
+   long a : 17;
+ } b;
+ int c, d;
+ void e() { b.a = d + c + ~(long)(302806U >> 0); }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-09-15 12:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-15 12:51 [PATCH] Fix PR77544 Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).