Commit 25b67546 by David Malcolm Committed by David Malcolm

Fix more ICEs in -fsave-optimization-record (PR tree-optimization/89235)

PR tree-optimization/89235 reports an ICE inside -fsave-optimization-record
whilst reporting the inlining chain of of the location_t in the
vect_location global.

This is very similar to PR tree-optimization/86637, fixed in r266821.

The issue is that the inlining chains are read from the location_t's
ad-hoc data, referencing GC-managed tree blocks, but the former are
not GC roots; it's simply assumed that old locations referencing dead
blocks never get used again.

The fix is to reset the "vect_location" global in more places.  Given
that is a somewhat subtle detail, the patch adds a sentinel class to
reset vect_location at the end of a scope.  Doing it as a class
simplifies the task of ensuring that the global is reset on every
exit path from a function, and also gives a good place to signpost
the above subtlety (in the documentation for the class).

The patch also adds test cases for both of the PRs mentioned above.

gcc/testsuite/ChangeLog:
	PR tree-optimization/86637
	PR tree-optimization/89235
	* gcc.c-torture/compile/pr86637-1.c: New test.
	* gcc.c-torture/compile/pr86637-2.c: New test.
	* gcc.c-torture/compile/pr86637-3.c: New test.
	* gcc.c-torture/compile/pr89235.c: New test.

gcc/ChangeLog:
	PR tree-optimization/86637
	PR tree-optimization/89235
	* tree-vect-loop.c (optimize_mask_stores): Add an
	auto_purge_vect_location sentinel to ensure that vect_location is
	purged on exit.
	* tree-vectorizer.c
	(auto_purge_vect_location::~auto_purge_vect_location): New dtor.
	(try_vectorize_loop_1): Add an auto_purge_vect_location sentinel
	to ensure that vect_location is purged on exit.
	(pass_slp_vectorize::execute): Likewise, replacing the manual
	reset.
	* tree-vectorizer.h (class auto_purge_vect_location): New class.

From-SVN: r268659
parent 8544ed6e
2019-02-07 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/86637
PR tree-optimization/89235
* tree-vect-loop.c (optimize_mask_stores): Add an
auto_purge_vect_location sentinel to ensure that vect_location is
purged on exit.
* tree-vectorizer.c
(auto_purge_vect_location::~auto_purge_vect_location): New dtor.
(try_vectorize_loop_1): Add an auto_purge_vect_location sentinel
to ensure that vect_location is purged on exit.
(pass_slp_vectorize::execute): Likewise, replacing the manual
reset.
* tree-vectorizer.h (class auto_purge_vect_location): New class.
2019-02-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/iterators.md (max_opp): New code_attr.
......
2019-02-07 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/86637
PR tree-optimization/89235
* gcc.c-torture/compile/pr86637-1.c: New test.
* gcc.c-torture/compile/pr86637-2.c: New test.
* gcc.c-torture/compile/pr86637-3.c: New test.
* gcc.c-torture/compile/pr89235.c: New test.
2019-02-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/abd_1.c: New test.
......
/* { dg-options "-fsave-optimization-record -ftree-slp-vectorize --param ggc-min-expand=1 --param ggc-min-heapsize=1024" } */
void
en (void)
{
}
void
n4 (int zb)
{
while (zb < 1)
++zb;
}
/* { dg-do compile { target fgraphite } } */
/* { dg-options "-floop-parallelize-all -fsave-optimization-record -ftree-parallelize-loops=2 -ftree-slp-vectorize" } */
#include <stdint.h>
#include <stdlib.h>
signed char qq;
int rm, mu, l9;
long long unsigned int ip;
void
fi (void)
{
}
void
il (long long unsigned int c5)
{
int *na = &mu;
while (l9 < 1)
{
if (qq < 1)
{
short int ds = 0;
if ((ip - *na - ip / c5 != 0) && (*na / ((c5 + c5) && !!ip) != 0))
__builtin_trap ();
rm = -1 / (!!rm && !!c5);
while (qq < 1)
{
++*na;
++ip;
if (*na < (int) ip)
while (ds < 2)
{
++qq;
++ds;
}
}
}
++l9;
}
for (;;)
{
}
}
void
uu (short int wk)
{
int64_t tl = ip;
while (ip < 2)
{
signed char vn;
for (vn = 1; vn != 0; ++vn)
{
int rh;
if (qq < 1)
{
while (mu < 1)
ip = 0;
while (rm != 0)
++rm;
}
for (rh = 0; rh < 3; ++rh)
{
int ab;
for (ab = 0; ab < 5; ++ab)
{
tl -= qq;
wk += rh - tl;
ip += (ab < wk) + wk;
}
}
}
}
}
void
im (uint8_t kt)
{
int wu = 0;
for (;;)
{
++rm;
if (rm < 1)
{
short int ms = 0;
while (kt < 1)
{
ms += rm < 0;
if (wu != 0)
for (;;)
{
}
while (ms < 4)
{
while (wu < 1)
wu += 2;
++ms;
}
}
if (ms == 0 || wu == 0)
break;
}
}
while (wu < 1)
while (qq < 1)
++qq;
}
/* { dg-options "-fsave-optimization-record -ftree-slp-vectorize --param ggc-min-expand=0 --param ggc-min-heapsize=1024" } */
void
te (void)
{
}
int
main (void)
{
return 0;
}
/* { dg-require-effective-target fopenmp } */
/* { dg-options "-S -fopenmp -fsave-optimization-record -ftree-parallelize-loops=2 -fno-tree-vectorize --param ggc-min-expand=0" } */
int a1, dr, xm, ly, zb, g9, il;
long int wt;
unsigned int mq;
int br, e7, rm, t4, jb, ry;
int
fi (void);
int
z5 (int fl)
{
while (br < 1)
while (e7 != 0)
while (mq != 1)
{
if (!!fl)
{
wt = rm;
fi ();
}
++mq;
}
return 0;
}
void
gg (void)
{
t4 = rm = z5 (rm);
jb = z5 (rm);
ry = fi ();
}
#pragma omp declare simd
void
hl (void)
{
for (;;)
{
gg ();
gg ();
gg ();
}
}
#pragma omp declare simd
int
cw (void)
{
return 0;
}
......@@ -8578,6 +8578,7 @@ optimize_mask_stores (struct loop *loop)
gimple_stmt_iterator gsi;
gimple *stmt;
auto_vec<gimple *> worklist;
auto_purge_vect_location sentinel;
vect_location = find_loop_location (loop);
/* Pick up all masked stores in loop if any. */
......
......@@ -86,6 +86,15 @@ along with GCC; see the file COPYING3. If not see
/* Loop or bb location, with hotness information. */
dump_user_location_t vect_location;
/* auto_purge_vect_location's dtor: reset the vect_location
global, to avoid stale location_t values that could reference
GC-ed blocks. */
auto_purge_vect_location::~auto_purge_vect_location ()
{
vect_location = dump_user_location_t ();
}
/* Dump a cost entry according to args to F. */
void
......@@ -860,6 +869,7 @@ try_vectorize_loop_1 (hash_table<simduid_to_vf> *&simduid_to_vf_htab,
{
unsigned ret = 0;
vec_info_shared shared;
auto_purge_vect_location sentinel;
vect_location = find_loop_location (loop);
if (LOCATION_LOCUS (vect_location.get_location_t ()) != UNKNOWN_LOCATION
&& dump_enabled_p ())
......@@ -1269,6 +1279,7 @@ public:
unsigned int
pass_slp_vectorize::execute (function *fun)
{
auto_purge_vect_location sentinel;
basic_block bb;
bool in_loop_pipeline = scev_initialized_p ();
......@@ -1303,8 +1314,6 @@ pass_slp_vectorize::execute (function *fun)
loop_optimizer_finalize ();
}
vect_location = dump_user_location_t ();
return 0;
}
......
......@@ -1420,6 +1420,24 @@ extern dump_user_location_t vect_location;
#define DUMP_VECT_SCOPE(MSG) \
AUTO_DUMP_SCOPE (MSG, vect_location)
/* A sentinel class for ensuring that the "vect_location" global gets
reset at the end of a scope.
The "vect_location" global is used during dumping and contains a
location_t, which could contain references to a tree block via the
ad-hoc data. This data is used for tracking inlining information,
but it's not a GC root; it's simply assumed that such locations never
get accessed if the blocks are optimized away.
Hence we need to ensure that such locations are purged at the end
of any operations using them (e.g. via this class). */
class auto_purge_vect_location
{
public:
~auto_purge_vect_location ();
};
/*-----------------------------------------------------------------*/
/* Function prototypes. */
/*-----------------------------------------------------------------*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment