Bug 53168 - ICE in find_or_generate_expression, at tree-ssa-pre.c:3053
Summary: ICE in find_or_generate_expression, at tree-ssa-pre.c:3053
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-04-30 13:42 UTC by John Regehr
Modified: 2012-05-04 11:35 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-04-30 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Regehr 2012-04-30 13:42:38 UTC
[regehr@dyson r44]$ current-gcc -c -O2 small.c
small.c: In function 'fn3':
small.c:7:1: internal compiler error: in find_or_generate_expression, at tree-ssa-pre.c:3053
 fn3 ()
 ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
[regehr@dyson r44]$ cat small.c
int a, b, c;
unsigned *d;
int e[1];
void fn1 ();
int fn2 ();
int
fn3 ()
{
    int *f = &a;
    if (fn2 ())
    {
        for (; c; c++)
        {
            e[a] && (b = 0);
            fn1 ();
            if (e[a])
                return 0;
        }
        for (; c <= 0; c++)
            for (;;)
                ;
    }
    else
        e[0] = 0 != (d = f);
    return *d;
}
[regehr@dyson r44]$ current-gcc -v
Using built-in specs.
COLLECT_GCC=current-gcc
COLLECT_LTO_WRAPPER=/uusoc/exports/scratch/regehr/z/compiler-install/gcc-r186954-install/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --with-libelf=/usr/local --enable-lto --prefix=/home/regehr/z/compiler-install/gcc-r186954-install --program-prefix=r186954- --enable-languages=c,c++
Thread model: posix
gcc version 4.8.0 20120430 (experimental) (GCC)
Comment 1 Jakub Jelinek 2012-04-30 15:18:05 UTC
Started failing with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185691
Comment 2 Richard Biener 2012-05-02 10:31:23 UTC
Mine.
Comment 3 Richard Biener 2012-05-02 15:00:54 UTC
It's what I always wondered about ... we phi-translate again during
do_regular_insertion but we fail to "clean" the result in any way.  So
we end with a translation result that is "invalid", thus one without
a leader and one which we cannot re-create.  That is, valid_in_sets returns
false for it.

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c  (revision 187042)
+++ gcc/tree-ssa-pre.c  (working copy)
@@ -3617,6 +3619,11 @@ do_regular_insertion (basic_block block,
                                                 vprime, NULL);
              if (edoubleprime == NULL)
                {
+                 if (!valid_in_sets (AVAIL_OUT (bprime), NULL, eprime, bprime))
+                   {
+                     cant_insert = true;
+                     break;
+                   }
                  avail[bprime->index] = eprime;
                  all_same = false;
                }

Steven - do you by chance remember why "re-translating" during insertion
is ok?  Or is a phi-translation result that cannot be inserted in its
form at the end of the BB bogus (always? or only during insertion?).
Comment 4 Steven Bosscher 2012-05-03 08:31:54 UTC
I don't remember. Did you look at the paper/thesis to see if it says anything about this?
Comment 5 Richard Biener 2012-05-03 14:17:32 UTC
I think it is because of how we do VN lookup / insert during phi_translation.
SCCVN does not guarantee availability of its lookup result, thus when
such availability is not guaranteed when we translate things we should rather
use the non-canonical expression (after all we translate expressions (sic!),
not values).

What happens is that we have (simplified)

  if (b)
    {
      x_1 = a;
    }
  else
    {
      if (c)
        for(;;)
          {
            x_2 = a;
            a = 0;
          }
    }

and SCCVN value-numbers x_2 to x_1.  PRE sees that 'a' is ANTIC_IN in the
for (;;) block - but it's not ANTIC_OUT in the if (c) block because it
gets cleaned out there as it is translated as x_1 which is not insertable.

I think the PRE algorithm does not expect that phi_translate (ANTIC_IN (succ))
will ever return something that is _not_ valid at the ANTIC_OUT position.
But our phi-translate implementation happily causes this situation.

My suggested change to check validity of the phi_translate result at
insert time is a workaround, but it only makes this a missed optimization.

This particular case is fixed by not turning the memory reference into
a conversion on translation.
Comment 6 Richard Biener 2012-05-04 11:30:39 UTC
Author: rguenth
Date: Fri May  4 11:30:35 2012
New Revision: 187153

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=187153
Log:
2012-05-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/53168
	* tree-ssa-pre.c (phi_translate_1): Only handle type-punned
	memory reads when the result is a constant we can pun.

	* gcc.dg/torture/pr53168.c: New testcase.
	* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr53168.c
    trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-pre.c
Comment 7 Richard Biener 2012-05-04 11:35:25 UTC
Fixed.