Message ID | 20161031215244.GN3541@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Mon, 31 Oct 2016, Jakub Jelinek wrote: > Hi! > > Some automatic VAR_DECLs don't get DECL_RTL set - e.g. if its SSA_NAMEs > expand to multiple rtls, then there is not a single one that can be used. > Using DECL_RTL on such VAR_DECLs ICEs. > > I've tried to just return 0 in nonoverlapping_memrefs_p if either > DECL_RTL_SET_P (expr{x,y}) wasn't true, but that triggered way too often > during bootstrap/regtest (3800+ times). So the following patch narrows it > down more and triggers only on the testcase below. What kind of cases did this trigger on? I would have expected we have DECL_RTL_SET_P on (almost?) all decls that can have it. And for those that don't it should be uninteresting to have? > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Hmm. Can you try splitting out a decl_can_have_rtl () predicate from make_decl_rtl and use that? Thanks, Richard. > 2016-10-31 Jakub Jelinek <jakub@redhat.com> > > PR target/77834 > * alias.c (nonoverlapping_memrefs_p): Return 0 if exprx or expry > doesn't have rtl set and it can't be safely created. > > * gcc.dg/pr77834.c: New test. > > --- gcc/alias.c.jj 2016-10-21 17:06:27.000000000 +0200 > +++ gcc/alias.c 2016-10-31 11:38:29.448031590 +0100 > @@ -2755,6 +2755,27 @@ nonoverlapping_memrefs_p (const_rtx x, c > || TREE_CODE (expry) == CONST_DECL) > return 1; > > + /* Don't try to create RTL for decls that intentionally don't have > + DECL_RTL set (e.g. marked as living in multiple places). */ > + if (!DECL_RTL_SET_P (exprx)) > + { > + if (TREE_CODE (exprx) == PARM_DECL > + || TREE_CODE (exprx) == RESULT_DECL > + || (VAR_P (exprx) > + && !TREE_STATIC (exprx) > + && !DECL_EXTERNAL (exprx))) > + return 0; > + } > + if (!DECL_RTL_SET_P (expry)) > + { > + if (TREE_CODE (expry) == PARM_DECL > + || TREE_CODE (expry) == RESULT_DECL > + || (VAR_P (expry) > + && !TREE_STATIC (expry) > + && !DECL_EXTERNAL (expry))) > + return 0; > + } > + > rtlx = DECL_RTL (exprx); > rtly = DECL_RTL (expry); > > --- gcc/testsuite/gcc.dg/pr77834.c.jj 2016-10-31 11:41:46.290521464 +0100 > +++ gcc/testsuite/gcc.dg/pr77834.c 2016-10-31 11:41:24.000000000 +0100 > @@ -0,0 +1,18 @@ > +/* PR target/77834 */ > +/* { dg-do compile } */ > +/* { dg-options "-O -ftree-pre -Wno-psabi" } */ > +/* { dg-additional-options "-mstringop-strategy=libcall" { target i?86-*-* x86_64-*-* } } */ > + > +typedef int V __attribute__ ((vector_size (64))); > + > +V > +foo (V u, V v, int w) > +{ > + do > + { > + if (u[0]) v ^= u[w]; > + } > + while ((V) { 0, u[w] }[1]); > + u = (V) { v[v[0]], u[u[0]] }; > + return v + u; > +} > > Jakub > >
On Wed, Nov 02, 2016 at 10:08:25AM +0100, Richard Biener wrote: > On Mon, 31 Oct 2016, Jakub Jelinek wrote: > > > Hi! > > > > Some automatic VAR_DECLs don't get DECL_RTL set - e.g. if its SSA_NAMEs > > expand to multiple rtls, then there is not a single one that can be used. > > Using DECL_RTL on such VAR_DECLs ICEs. > > > > I've tried to just return 0 in nonoverlapping_memrefs_p if either > > DECL_RTL_SET_P (expr{x,y}) wasn't true, but that triggered way too often > > during bootstrap/regtest (3800+ times). So the following patch narrows it > > down more and triggers only on the testcase below. > > What kind of cases did this trigger on? I would have expected we > have DECL_RTL_SET_P on (almost?) all decls that can have it. And for > those that don't it should be uninteresting to have? I admit I havne't studied it in detail yet. Attaching list of BITS_PER_WORD, main_input_filename, current_function_name () where nonoverlapping_memrefs_p returned 0 early because either exprx or expry didn't have DECL_RTL_SET_P. As except for the new testcase that didn't result into ICE, all of those must have been something where make_decl_rtl created RTL in that case. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > Hmm. Can you try splitting out a decl_can_have_rtl () predicate > from make_decl_rtl and use that? Will do. Jakub
On Wed, 2 Nov 2016, Jakub Jelinek wrote: > On Wed, Nov 02, 2016 at 10:08:25AM +0100, Richard Biener wrote: > > On Mon, 31 Oct 2016, Jakub Jelinek wrote: > > > > > Hi! > > > > > > Some automatic VAR_DECLs don't get DECL_RTL set - e.g. if its SSA_NAMEs > > > expand to multiple rtls, then there is not a single one that can be used. > > > Using DECL_RTL on such VAR_DECLs ICEs. > > > > > > I've tried to just return 0 in nonoverlapping_memrefs_p if either > > > DECL_RTL_SET_P (expr{x,y}) wasn't true, but that triggered way too often > > > during bootstrap/regtest (3800+ times). So the following patch narrows it > > > down more and triggers only on the testcase below. > > > > What kind of cases did this trigger on? I would have expected we > > have DECL_RTL_SET_P on (almost?) all decls that can have it. And for > > those that don't it should be uninteresting to have? > > I admit I havne't studied it in detail yet. Attaching list of > BITS_PER_WORD, main_input_filename, current_function_name () > where nonoverlapping_memrefs_p returned 0 early because > either exprx or expry didn't have DECL_RTL_SET_P. As except for the new > testcase that didn't result into ICE, all of those must have been something > where make_decl_rtl created RTL in that case. Ok, just looking at regex.c (I happen to have regex.i around) shows the first hit as #2 0x00000000008d9914 in true_dependence_1 (mem=0x7ffff61ef360, mem_mode=DImode, mem_addr=0x7ffff6220cf0, x=0x7ffff6605060, x_addr=0x7ffff662ffd8, mem_canonicalized=true) at /space/rguenther/src/svn/trunk/gcc/alias.c:2928 2928 if (nonoverlapping_memrefs_p (mem, x, false)) (gdb) p debug_tree (expry) <function_decl 0x7ffff6941f00 __builtin_malloc type <function_type 0x7ffff68b0dc8 2928 if (nonoverlapping_memrefs_p (mem, x, false)) (gdb) p debug_rtx (mem) (mem/f/c:DI (plus:DI (reg/f:DI 7 sp) (const_int 200 [0xc8])) [5 p+0 S8 A64]) $4 = void (gdb) p debug_rtx (x) (mem:QI (symbol_ref:DI ("malloc") [flags 0x41] <function_decl 0x7ffff6943000 malloc>) [0 __builtin_malloc S1 A8]) $5 = void called from DSE check_mem_read_rtx. I believe that's a bogus query. (I see only a single hit on regex.c, your log seems to have multiple ones...) I wouldn't worry about the lost cases, and if I'd be ambitious I'd try to investigate the above and see what remains... > > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > > > Hmm. Can you try splitting out a decl_can_have_rtl () predicate > > from make_decl_rtl and use that? > > Will do. Thanks, Richard.
On Wed, Nov 02, 2016 at 10:34:15AM +0100, Richard Biener wrote: > Ok, just looking at regex.c (I happen to have regex.i around) shows > the first hit as > > #2 0x00000000008d9914 in true_dependence_1 (mem=0x7ffff61ef360, > mem_mode=DImode, mem_addr=0x7ffff6220cf0, x=0x7ffff6605060, > x_addr=0x7ffff662ffd8, mem_canonicalized=true) > at /space/rguenther/src/svn/trunk/gcc/alias.c:2928 > 2928 if (nonoverlapping_memrefs_p (mem, x, false)) > (gdb) p debug_tree (expry) > <function_decl 0x7ffff6941f00 __builtin_malloc > type <function_type 0x7ffff68b0dc8 > > 2928 if (nonoverlapping_memrefs_p (mem, x, false)) > (gdb) p debug_rtx (mem) > (mem/f/c:DI (plus:DI (reg/f:DI 7 sp) > (const_int 200 [0xc8])) [5 p+0 S8 A64]) > $4 = void > (gdb) p debug_rtx (x) > (mem:QI (symbol_ref:DI ("malloc") [flags 0x41] <function_decl > 0x7ffff6943000 malloc>) [0 __builtin_malloc S1 A8]) > $5 = void > > called from DSE check_mem_read_rtx. I believe that's a bogus query. I guess I should also log debug_rtx (DECL_RTL (expr{x,y})) in those cases then and perhaps also if we ever return non-zero in those cases. > (I see only a single hit on regex.c, your log seems to have multiple > ones...) That was statistics gathered across x86_64-linux and i686-linux simultaneous bootstraps + regtests (and most likely I've mistyped the first value from (int) BITS_PER_WORD to (int) BITS_PER_UNIT :( ). So regex.c is built there many times (3 times each bootstrap at least). Jakub
On Wed, 2 Nov 2016, Jakub Jelinek wrote: > On Wed, Nov 02, 2016 at 10:34:15AM +0100, Richard Biener wrote: > > Ok, just looking at regex.c (I happen to have regex.i around) shows > > the first hit as > > > > #2 0x00000000008d9914 in true_dependence_1 (mem=0x7ffff61ef360, > > mem_mode=DImode, mem_addr=0x7ffff6220cf0, x=0x7ffff6605060, > > x_addr=0x7ffff662ffd8, mem_canonicalized=true) > > at /space/rguenther/src/svn/trunk/gcc/alias.c:2928 > > 2928 if (nonoverlapping_memrefs_p (mem, x, false)) > > (gdb) p debug_tree (expry) > > <function_decl 0x7ffff6941f00 __builtin_malloc > > type <function_type 0x7ffff68b0dc8 > > > > 2928 if (nonoverlapping_memrefs_p (mem, x, false)) > > (gdb) p debug_rtx (mem) > > (mem/f/c:DI (plus:DI (reg/f:DI 7 sp) > > (const_int 200 [0xc8])) [5 p+0 S8 A64]) > > $4 = void > > (gdb) p debug_rtx (x) > > (mem:QI (symbol_ref:DI ("malloc") [flags 0x41] <function_decl > > 0x7ffff6943000 malloc>) [0 __builtin_malloc S1 A8]) > > $5 = void > > > > called from DSE check_mem_read_rtx. I believe that's a bogus query. > > I guess I should also log debug_rtx (DECL_RTL (expr{x,y})) in those cases > then and perhaps also if we ever return non-zero in those cases. Yeah, plus if a followup test would have disambiguated things (the dispatch to the tree oracle for example). > > (I see only a single hit on regex.c, your log seems to have multiple > > ones...) > > That was statistics gathered across x86_64-linux and i686-linux simultaneous > bootstraps + regtests (and most likely I've mistyped the first value > from (int) BITS_PER_WORD to (int) BITS_PER_UNIT :( ). So regex.c is built > there many times (3 times each bootstrap at least). Ah, ok. At least 12 times for x86_64 with multilibs (we build PIC and non-PIC variants IIRC). Richard.
--- gcc/alias.c.jj 2016-10-21 17:06:27.000000000 +0200 +++ gcc/alias.c 2016-10-31 11:38:29.448031590 +0100 @@ -2755,6 +2755,27 @@ nonoverlapping_memrefs_p (const_rtx x, c || TREE_CODE (expry) == CONST_DECL) return 1; + /* Don't try to create RTL for decls that intentionally don't have + DECL_RTL set (e.g. marked as living in multiple places). */ + if (!DECL_RTL_SET_P (exprx)) + { + if (TREE_CODE (exprx) == PARM_DECL + || TREE_CODE (exprx) == RESULT_DECL + || (VAR_P (exprx) + && !TREE_STATIC (exprx) + && !DECL_EXTERNAL (exprx))) + return 0; + } + if (!DECL_RTL_SET_P (expry)) + { + if (TREE_CODE (expry) == PARM_DECL + || TREE_CODE (expry) == RESULT_DECL + || (VAR_P (expry) + && !TREE_STATIC (expry) + && !DECL_EXTERNAL (expry))) + return 0; + } + rtlx = DECL_RTL (exprx); rtly = DECL_RTL (expry); --- gcc/testsuite/gcc.dg/pr77834.c.jj 2016-10-31 11:41:46.290521464 +0100 +++ gcc/testsuite/gcc.dg/pr77834.c 2016-10-31 11:41:24.000000000 +0100 @@ -0,0 +1,18 @@ +/* PR target/77834 */ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-pre -Wno-psabi" } */ +/* { dg-additional-options "-mstringop-strategy=libcall" { target i?86-*-* x86_64-*-* } } */ + +typedef int V __attribute__ ((vector_size (64))); + +V +foo (V u, V v, int w) +{ + do + { + if (u[0]) v ^= u[w]; + } + while ((V) { 0, u[w] }[1]); + u = (V) { v[v[0]], u[u[0]] }; + return v + u; +}