Bug 43455 - ICE in fold_convert_loc, at fold-const.c:2670 with -O2 -flto
Summary: ICE in fold_convert_loc, at fold-const.c:2670 with -O2 -flto
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.5.1
Assignee: Richard Biener
URL:
Keywords: lto
Depends on:
Blocks:
 
Reported: 2010-03-20 19:09 UTC by Marcin Baczyński
Modified: 2010-05-19 13:15 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.5.0
Last reconfirmed: 2010-03-22 10:30:41


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcin Baczyński 2010-03-20 19:09:13 UTC
gcc -O2 -flto 1.c 2.c hangs.
-O1 or without -flto compiles and links just fine.

1.c:
struct bar {int x;};
extern struct bar foo(void);
int main()
{
        struct bar x=foo();
        return 0;
}

2.c:
typedef struct{int x;} bar;
bar foo (void)
{
        bar x;
        return x;
}

gcc -v:
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.5.0-alpha20100318/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.0-alpha20100318/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.5.0_alpha20100318/work/gcc-4.5-20100318/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.5.0-alpha20100318 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0-alpha20100318/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.0-alpha20100318 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.0-alpha20100318/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.0-alpha20100318/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.0-alpha20100318/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --with-ppl --with-cloog --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --enable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --enable-cld --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.5.0-alpha20100318/python --disable-libgcj --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.5.0_alpha20100318' --enable-lto
Thread model: posix
gcc version 4.5.0-alpha20100318 20100318 (experimental) (Gentoo 4.5.0_alpha20100318)
Comment 1 Richard Biener 2010-03-20 20:15:20 UTC
Works for me on i?86-linux.
Comment 2 Marcin Baczyński 2010-03-20 22:25:40 UTC
Passing -m32 make the hang disappear.

Below is slightly less reduced version of previous test case. It comes from gnu bc.

It causes ICE. Uncommenting declarations changes ICE into hang. ICE doesn't go away with -m32.

gcc -O2 -flto numeric.c eval.c 
===
In file included from eval.c:28:0,
                 from numeric.c:19,
                 from :0:
eval.c: In function 'dc_evalstr':
eval.c:30:10: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugs.gentoo.org/> for instructions.
lto-wrapper: /usr/x86_64-pc-linux-gnu/gcc-bin/4.5.0-alpha20100318/gcc returned 1 exit status
collect2: lto-wrapper returned 1 exit status
===

eval.c:
====
typedef enum {DC_UNINITIALIZED, DC_NUMBER, DC_STRING} dc_value_type;
typedef struct dc_number *dc_num;
typedef struct dc_string *dc_str;
typedef struct {
        dc_value_type dc_type;
        union { dc_num number; dc_str string; } v;
} dc_data;

const char *progname;

int main()
{
        return 0;
}
/*
int dc_func(int a, int b, int c);
void dc_push(dc_data);
dc_data dc_getnum(int a, int b, int c);
*/
static const char *input_str_string;

int
dc_evalstr (dc_data *string)
{
        const char *s;
        int peekc;
        switch (dc_func(0, 0, 0)){
        case 0:
                input_str_string = s - 1;
                dc_push(dc_getnum(0, 0, 0));
                s = input_str_string;
                if (peekc != -1)
                        --s;
                break;
        }
        return 0;
}
===

numeric.c 
===
typedef enum {DC_UNINITIALIZED, DC_NUMBER, DC_STRING} dc_value_type;
typedef struct bc_struct *dc_num;
typedef struct dc_string *dc_str;
typedef struct {
        dc_value_type dc_type;
        union {
                dc_num number;
                dc_str string;
        } v;
} dc_data;

dc_data dc_getnum(int input, int ibase, int readahead)
{
        dc_data x;
        return x;
}

int dc_func(int a, int b, int c){return 0;}
void dc_push(dc_data a){}
Comment 3 Richard Biener 2010-03-22 10:30:26 UTC
I get on x86_64-linux

> ./xgcc -B. -flto t1.c t2.c -O2
In file included from t2.c:2:0,
                 from t1.c:2,
                 from :0:
t1.c: In function 'main':
t1.c:5:22: internal compiler error: in fold_convert_loc, at fold-const.c:2792
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: ././xgcc returned 1 exit status
collect2: lto-wrapper returned 1 exit status

same with the less reduced testcase on x86_64 and i?86 linux.

Thanks for the report.


This is because we do not merge

  struct bar {int x;};

and

  typedef struct{int x;} bar;

but we expect to be able to convert them into each other during inlining:

#2  0x0000000000c120ac in declare_return_variable (id=0x7fffffffd9d0, 
    return_slot=0x0, modify_dest=0x7ffff5af03c0)
    at /space/rguenther/src/svn/trunk/gcc/tree-inline.c:2690
2690        use = fold_convert (caller_type, var);
(gdb) l
2685
2686      /* Build the use expr.  If the return type of the function was
2687         promoted, convert it back to the expected type.  */
2688      use = var;
2689      if (!useless_type_conversion_p (caller_type, TREE_TYPE (var)))
2690        use = fold_convert (caller_type, var);


This is really invalid C as bar is re-declared in an incompatible way
(which you'd see if you combine both TUs).

Now, we shouldn't ICE here anyway and LTO should be forgiving to this
kind of errors.

The following fixes the symptoms.

Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c   (revision 157619)
+++ gcc/tree-inline.c   (working copy)
@@ -2687,7 +2687,12 @@ declare_return_variable (copy_body_data
      promoted, convert it back to the expected type.  */
   use = var;
   if (!useless_type_conversion_p (caller_type, TREE_TYPE (var)))
-    use = fold_convert (caller_type, var);
+    {
+      if (fold_convertible_p (caller_type, var))
+       use = fold_convert (caller_type, var);
+      else
+       use = fold_build1 (VIEW_CONVERT_EXPR, caller_type, var);
+    }
 
   STRIP_USELESS_TYPE_CONVERSION (use);
Comment 4 Richard Biener 2010-04-23 13:39:50 UTC
I am testing a patch to tree_can_inline_p instead.  That doesn't work with
WPA as we do not have the call_stmt available there - Honza, any idea where
to re-apply the check?
Comment 5 Richard Biener 2010-04-23 15:18:48 UTC
Fixed.
Comment 6 Richard Biener 2010-04-23 15:18:51 UTC
Subject: Bug 43455

Author: rguenth
Date: Fri Apr 23 15:18:24 2010
New Revision: 158669

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

	PR lto/43455
	* tree-inline.c (tree_can_inline_p): Also check compatibility
	of return types.

	* gcc.dg/lto/20100423-1_0.c: New testcase.
	* gcc.dg/lto/20100423-1_1.c: Likewise.

Added:
    trunk/gcc/testsuite/gcc.dg/lto/20100423-1_0.c
    trunk/gcc/testsuite/gcc.dg/lto/20100423-1_1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-inline.c

Comment 7 Richard Biener 2010-05-19 13:16:34 UTC
Subject: Bug 43455

Author: rguenth
Date: Wed May 19 13:14:37 2010
New Revision: 159564

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

        Backport from mainline:
        2010-04-26  Richard Guenther  <rguenther@suse.de>

	PR lto/43455
	* tree-inline.c (tree_can_inline_p): Also check compatibility
	of return types.

	* gcc.dg/lto/20100423-1_0.c: New testcase.
	* gcc.dg/lto/20100423-1_1.c: Likewise.

        2010-04-23  Richard Guenther  <rguenther@suse.de>

	PR lto/42653
	* tree.c (free_lang_data_in_decl): Do not reset DECL_CONTEXT
	of FUNCTION_DECLs.

	* g++.dg/lto/20100423-1_0.C: New testcase.

        2010-04-26  Richard Guenther  <rguenther@suse.de>

	PR lto/42425
	* tree.c (free_lang_data_in_type): Do not free TYPE_CONTEXT
	if emitting debug information and it is either a function
	or a namespace decl.

	* g++.dg/lto/20100423-2_0.C: New testcase.

        2010-04-26  Richard Guenther  <rguenther@suse.de>

	PR lto/43080
	* gimple.c (gimple_decl_printable_name): Deal gracefully
	with a NULL DECL_NAME.

	* g++.dg/lto/20100423-3_0.C: New testcase.

        2010-04-30  Richard Guenther  <rguenther@suse.de>

	PR lto/43946
	* passes.c (init_optimization_passes): Move pass_ipa_free_lang_data
	first after all lowering passes.

	* gcc.dg/lto/20100430-1_0.c: New testcase.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/lto/20100423-1_0.C
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/lto/20100423-2_0.C
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/lto/20100423-3_0.C
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/lto/20100423-1_0.c
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/lto/20100423-1_1.c
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/lto/20100430-1_0.c
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/gimple.c
    branches/gcc-4_5-branch/gcc/passes.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_5-branch/gcc/tree-inline.c
    branches/gcc-4_5-branch/gcc/tree.c