Bug 61773 - [5 Regression] ICE in tree-ssa-strlen.c:417
Summary: [5 Regression] ICE in tree-ssa-strlen.c:417
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 5.0
: P1 normal
Target Milestone: 5.0
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks: 63989 63787
  Show dependency treegraph
 
Reported: 2014-07-10 13:25 UTC by Richard Biener
Modified: 2014-11-21 09:38 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.9.0
Known to fail:
Last reconfirmed: 2014-10-17 00:00:00


Attachments
gcc5-pr61773.patch (783 bytes, patch)
2014-11-20 09:28 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2014-07-10 13:25:18 UTC
char *foo (void)
{
  char *p = __builtin_malloc (64);
  char *q = __builtin_malloc (64);
  __builtin_strcat (q, "abcde");
  __builtin_strcat (p, "ab");
  p[1] = q[3];
  __builtin_strcat (p, q);
  return q;
}

gives

> ../../obj2/gcc/cc1 -quiet -O2 t.c
t.c: In function ‘foo’:
t.c:1:7: internal compiler error: in get_string_length, at tree-ssa-strlen.c:417
 char *foo (void)
       ^
0x876c3d2 get_string_length
        /space/rguenther/tramp3d/trunk/gcc/tree-ssa-strlen.c:417
0x8772b02 get_string_length
        /space/rguenther/tramp3d/trunk/gcc/tree.h:2731
0x8772b02 handle_builtin_strlen
        /space/rguenther/tramp3d/trunk/gcc/tree-ssa-strlen.c:899

(gdb) up
#1  0x0876c3d3 in get_string_length (si=0x3c)
    at /space/rguenther/tramp3d/trunk/gcc/tree-ssa-strlen.c:417
417           gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));


while trying to write a testcase that shows that handle_char_store should
handle a character copy from a known non-zero value.  Well, while really
trying to incrementally teach handle_char_store to handle arbitrary
stores.
Comment 1 Richard Biener 2014-07-10 13:25:52 UTC
Seems to not ICE with 4.9 for me.
Comment 2 Richard Biener 2014-07-10 13:27:58 UTC
Fixed with adding a prototype

char *stpcpy (char*, const char *);
Comment 3 Richard Biener 2014-07-10 13:36:37 UTC
Proper testcase (string init was missing):

char *stpcpy (char*, const char *);
char *foo (void)
{
  char *p = __builtin_calloc (64, 1);
  char *q = __builtin_calloc (64, 1);
  __builtin_strcat (q, "abcde");
  __builtin_strcat (p, "ab");
  p[1] = 'a';
  __builtin_strcat (p, q);
  return q;
}

this isn't optimized either, only when p[0] = 'a'; is there the last
strcat will be optimized with known strlen of p.  Hmm, a p[1] = '\0'
isn't optimized either.

Unfortunately strlen isn't very verbose in its -details dump.
Comment 4 Richard Biener 2014-07-10 13:55:08 UTC
(In reply to Richard Biener from comment #3)
> Proper testcase (string init was missing):
> 
> char *stpcpy (char*, const char *);
> char *foo (void)
> {
>   char *p = __builtin_calloc (64, 1);
>   char *q = __builtin_calloc (64, 1);
>   __builtin_strcat (q, "abcde");
>   __builtin_strcat (p, "ab");
>   p[1] = 'a';
>   __builtin_strcat (p, q);
>   return q;
> }
> 
> this isn't optimized either, only when p[0] = 'a'; is there the last
> strcat will be optimized with known strlen of p.  Hmm, a p[1] = '\0'
> isn't optimized either.
> 
> Unfortunately strlen isn't very verbose in its -details dump.

Ok, those are all because the store is

  MEM[ptr, 1] = ...

while only a zero offset MEM is handled in handle_char_store.  For
non-constant offset this gets handled by handle_pointer_plus.

It seems to me that all builtin handling will have a similar issue
when faced with arguments of &MEM[ptr_1, <nonzero-offset>] (zero-offset
should be folded to plain ptr_1 of course, so doesn't happen).

Simple

char *stpcpy (char*, const char *);
char *foo (void)
{
  char *p = __builtin_calloc (64, 1);
  char *q = __builtin_calloc (64, 1);
  __builtin_strcat (q, "abcde");
  __builtin_strcat (p, "ab");
  p = p + 1;
  __builtin_strcat (p, q);
  return q;
}

isn't optimized because we get

  _10 = p_3 + _9;
  __builtin_memcpy (_10, "ab", 3);
  p_12 = p_3 + 1;
  __builtin_strcat (p_12, q_5);

and likely p_3 string-info is invalidated instead of made a copy of that
of _10 (as _9 is zero).

char *stpcpy (char*, const char *);
char *foo (char *q)
{
  char *p = __builtin_strdup ("abcde");
  p = p + 1;
  __builtin_strcat (p, "blah");
  return q;
}

is also not handled well as we don't seem to recognize strdup?
Comment 5 Markus Trippelsdorf 2014-10-17 13:02:58 UTC
Also happens during PGO/LTO bootstrap:

markus@x4 gcc % /var/tmp/gcc_build_dir/./stage1-gcc/xg++ -B/var/tmp/gcc_build_dir/./stage1-gcc/ -B/usr/x86_64-pc-linux-gnu/bin/ -nostdinc++ -B/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs -B/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/.libs -I/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu -I/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/include -I/var/tmp/gcc/libstdc++-v3/libsupc++ -L/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs -L/var/tmp/gcc_build_dir/stage1-x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/.libs -march=native -O3 -pipe -flto=jobserver -frandom-seed=1 -fprofile-use -DIN_GCC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -DHAVE_CONFIG_H -DGENERATOR_FILE -Wl,-O1,--hash-style=gnu,--as-needed,--gc-sections,--icf=safe,--icf-iterations=3 -o build/gengtype build/gengtype.o build/errors.o build/gengtype-lex.o build/gengtype-parse.o build/gengtype-state.o build/version.o .././libiberty/libiberty.a
../../gcc/gcc/gengtype.c: In function ‘output_mangled_typename’:
../../gcc/gcc/gengtype.c:2625:1: internal compiler error: in get_string_length, at tree-ssa-strlen.c:417
 output_mangled_typename (outf_p of, const_type_p t)
 ^
Please submit a full bug report,
Comment 6 Jakub Jelinek 2014-11-20 08:49:37 UTC
The ICE started with r211956, before that it was assumed that any non-NULL si->stmt is something to be optimized with stpcpy and friends, so has to be guarded when creating it so that such optimization isn't attempted if stpcpy isn't declared.

So, for the ICE I'd like to fix it with:
--- gcc/tree-ssa-strlen.c.jj	2014-11-19 18:47:59.000000000 +0100
+++ gcc/tree-ssa-strlen.c	2014-11-20 09:46:33.949017462 +0100
@@ -430,7 +430,6 @@ get_string_length (strinfo si)
       callee = gimple_call_fndecl (stmt);
       gcc_assert (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL);
       lhs = gimple_call_lhs (stmt);
-      gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
       /* unshare_strinfo is intentionally not called here.  The (delayed)
 	 transformation of strcpy or strcat into stpcpy is done at the place
 	 of the former strcpy/strcat call and so can affect all the strinfos
@@ -479,6 +478,7 @@ get_string_length (strinfo si)
 	case BUILT_IN_STRCPY_CHK:
 	case BUILT_IN_STRCPY_CHKP:
 	case BUILT_IN_STRCPY_CHK_CHKP:
+	  gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
 	  if (gimple_call_num_args (stmt) == (with_bounds ? 4 : 2))
 	    fn = builtin_decl_implicit (BUILT_IN_STPCPY);
 	  else

now that BUILT_IN_MALLOC uses si->stmt non-NULL too and obviously isn't in any way related to stpcpy.  I'll look at the missed optimizations.
Comment 7 Jakub Jelinek 2014-11-20 09:28:17 UTC
Created attachment 34048 [details]
gcc5-pr61773.patch

Full (untested) patch.  Let's split this PR into the ICE part and another one for the enhancement request, which isn't a regression.
Comment 8 Jakub Jelinek 2014-11-21 09:27:51 UTC
Author: jakub
Date: Fri Nov 21 09:27:19 2014
New Revision: 217910

URL: https://gcc.gnu.org/viewcvs?rev=217910&root=gcc&view=rev
Log:
	PR tree-optimization/61773
	* tree-ssa-strlen.c (get_string_length): Don't assert
	stpcpy has been prototyped if si->stmt is BUILT_IN_MALLOC.

	* gcc.dg/pr61773.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr61773.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-strlen.c
Comment 9 Jakub Jelinek 2014-11-21 09:38:21 UTC
Fixed.