Bug 56570 - ICE when streaming a TREE_BLOCK
Summary: ICE when streaming a TREE_BLOCK
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: mozillametabug
  Show dependency treegraph
 
Reported: 2013-03-08 10:35 UTC by Martin Jambor
Modified: 2013-03-08 13:46 UTC (History)
0 users

See Also:
Host: x86_64-linux-gnu
Target: x86_64-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-03-08 00:00:00


Attachments
Pre-processed failing source (396.40 KB, application/x-gzip)
2013-03-08 10:35 UTC, Martin Jambor
Details
inliner patches (1.33 KB, patch)
2013-03-08 12:25 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Jambor 2013-03-08 10:35:13 UTC
Created attachment 29617 [details]
Pre-processed failing source

When building Mozilla Firefox with LTO (gcc revision 196427, FF
changeset 123831:c95439870e05), I'm encountering an ICE when compiling
js/src/ion/shared/CodeGenerator-shared.cpp (and I suppose the same one
in a number of other files).  The problem occurs in the compilation
phase.

The ICE simply disappears when I add -save-temps to the command line
but reappeared when I also added --param ggc-min-expand=10 --param
ggc-min-heapsize=1024.  The attached resultant .ii file also ICEs but
--param ggc-min-expand=5 --param ggc-min-heapsize=512 is necessary to
trigger it.
Comment 1 Martin Jambor 2013-03-08 10:39:52 UTC
Let me copy over here from PR 45375 the backtrace:

#0  0x0000000000f89a73 in get_location_from_adhoc_loc (set=0x7ffff7ff2000,
    loc=2947526575) at /home/mjambor/gcc/trunk/src/libcpp/line-map.c:165
#1  0x0000000000c247fe in inlined_function_outer_scope_p (block=0x7fffee4bcb28)
    at /home/mjambor/gcc/trunk/src/gcc/tree.h:5561
#2  pack_ts_block_value_fields (expr=0x7fffee4bcb28, bp=0x7fffffffd1a0,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:319
#3  streamer_pack_tree_bitfields (ob=0x1c73210, bp=0x7fffffffd1a0,
expr=0x7fffee4bcb28)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:417
#4  0x00000000009c3bc9 in lto_write_tree (ref_p=true, expr=0x7fffee4bcb28,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:317
#5  lto_output_tree (ob=0x1c73210, expr=0x7fffee4bcb28, ref_p=true,
    this_ref_p=<optimized out>) at
/home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:410
#6  0x0000000000c26617 in write_ts_common_tree_pointers (ref_p=true,
    expr=0x7ffff3f6bc80, ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:514
#7  streamer_write_tree_body (ob=0x1c73210, expr=0x7ffff3f6bc80,
ref_p=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:845
#8  0x00000000009c3bf7 in lto_write_tree (ref_p=true, expr=0x7ffff3f6bc80,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:321
#9  lto_output_tree (ob=ob@entry=0x1c73210, expr=0x7ffff3f6bc80,
ref_p=ref_p@entry=true,
    this_ref_p=this_ref_p@entry=true)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:410
#10 0x0000000000c26e62 in write_ts_exp_tree_pointers (ref_p=<optimized out>,
    expr=<optimized out>, ob=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:747
#11 streamer_write_tree_body (ob=0x1c73210, expr=0x7fffecc63dc0,
ref_p=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:884
#12 0x00000000009c3bf7 in lto_write_tree (ref_p=true, expr=0x7fffecc63dc0,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:321
#13 lto_output_tree (ob=0x1c73210, expr=0x7fffecc63dc0, ref_p=true,
    this_ref_p=<optimized out>) at
/home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:410
#14 0x0000000000c26df8 in write_ts_exp_tree_pointers (ref_p=<optimized out>,
    expr=<optimized out>, ob=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:746
#15 streamer_write_tree_body (ob=0x1c73210, expr=0x7fffecc70078,
ref_p=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:884
#16 0x00000000009c3bf7 in lto_write_tree (ref_p=true, expr=0x7fffecc70078,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:321
#17 lto_output_tree (ob=ob@entry=0x1c73210, expr=0x7fffecc70078,
ref_p=ref_p@entry=true,
    this_ref_p=this_ref_p@entry=true)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:410
#18 0x0000000000c2681d in write_ts_decl_common_tree_pointers (ref_p=true,
    expr=0x7fffecc6d720, ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:584
#19 streamer_write_tree_body (ob=0x1c73210, expr=0x7fffecc6d720,
ref_p=<optimized out>)
    at /home/mjambor/gcc/trunk/src/gcc/tree-streamer-out.c:857
#20 0x00000000009c3bf7 in lto_write_tree (ref_p=true, expr=0x7fffecc6d720,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:321
#21 lto_output_tree (ob=0x1c73210, expr=0x7fffecc6d720, ref_p=true,
    this_ref_p=<optimized out>) at
/home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:410
#22 0x0000000000ecd118 in output_gimple_stmt (stmt=0x7fffec6206c0,
ob=0x1c73210)
    at /home/mjambor/gcc/trunk/src/gcc/gimple-streamer-out.c:143
#23 output_bb (ob=0x1c73210, bb=0x7fffed130f08, fn=0x7fffef8603f0)
    at /home/mjambor/gcc/trunk/src/gcc/gimple-streamer-out.c:199
#24 0x00000000009c4f26 in output_function (node=0x7fffef8614a0)
    at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:823
#25 lto_output () at /home/mjambor/gcc/trunk/src/gcc/lto-streamer-out.c:987
#26 0x00000000009fa971 in ipa_write_summaries_2 (
    pass=0x1618f00 <pass_ipa_lto_gimple_out>, state=0x1ad8c00)
    at /home/mjambor/gcc/trunk/src/gcc/passes.c:2408


I am not sure to what extent it matters, given that the failure
apparently depends on when certain GC takes place, but the first
failing revision is 196174:

commit 560965e9b33deb5fa67c848c8b14ea7bbb42e8a2
Author: rguenth
Date:   Wed Feb 20 15:19:13 2013 +0000

    2013-02-20  Richard Biener  <rguenther@suse.de>
    
        * tree-call-cdce.c (tree_call_cdce): Do not remove unused locals.
        * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise.
        * tree-ssa-dce.c (perform_tree_ssa_dce): Likewise.
        * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do
        not return anything.
        (rename_ssa_copies): Do not remove unused locals.
        * tree-ssa-ccp.c (do_ssa_ccp): Likewise.
        * tree-ssanames.c (pass_release_ssa_names): Remove unused
        locals first.
        * passes.c (execute_function_todo): Do not schedule unused locals
        removal if cleanup_tree_cfg did something.
        * tree-ssa-live.c (remove_unused_locals): Dump statistics
        about the number of removed locals.
    
        * gcc.dg/tree-ssa/forwprop-8.c: Adjust.
Comment 2 Martin Jambor 2013-03-08 10:43:12 UTC
I forgot the compilation options I use:

~/gcc/trunk/inst/bin/g++ -o CodeGenerator-shared.o -c -fPIC  -Wno-invalid-offsetof -Wcast-align -flto -fpermissive -Wno-maybe-uninitialized -Wno-unused-local-typedefs -fuse-linker-plugin -fno-rtti -ffunction-sections -fdata-sections -fno-exceptions -pthread  -DNDEBUG -DTRIMMED -g -O3 CodeGenerator-shared.ii --param ggc-min-expand=5 --param ggc-min-heapsize=512
Comment 3 Richard Biener 2013-03-08 11:20:22 UTC
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 196540)
+++ gcc/tree-cfg.c      (working copy)
@@ -4521,6 +4541,15 @@ verify_expr_location_1 (tree *tp, int *w
 {
   struct pointer_set_t *blocks = (struct pointer_set_t *) data;
 
+  if (TREE_CODE (*tp) == VAR_DECL
+      && DECL_DEBUG_EXPR_IS_FROM (*tp))
+    {
+      tree t = DECL_DEBUG_EXPR (*tp);
+      tree addr = walk_tree (&t, verify_expr_location_1, blocks, NULL);
+      if (addr)
+       return addr;
+    }
+
   if (!EXPR_P (*tp))
     {
       *walk_subtrees = false;


exposes it.  Various fixes to tree-inline.c didn't yet fix it :/

Reducing the testcase with the above.
Comment 4 Richard Biener 2013-03-08 12:05:41 UTC
It's the DECL_DEBUG_EXPRs created by SRA, supposedly we can fix it by

Index: tree-sra.c
===================================================================
--- tree-sra.c  (revision 196487)
+++ tree-sra.c  (working copy)
@@ -1917,7 +1917,7 @@ create_access_replacement (struct access
       && !DECL_ARTIFICIAL (access->base))
     {
       char *pretty_name = make_fancy_name (access->expr);
-      tree debug_expr = unshare_expr (access->expr), d;
+      tree debug_expr = unshare_expr_without_location (access->expr), d;
       bool fail = false;
 
       DECL_NAME (repl) = get_identifier (pretty_name);

but we should fix the reason why it doesn't survive inlining properly.

Reducing a file from libgcc instead.
Comment 5 Richard Biener 2013-03-08 12:15:13 UTC
typedef struct { unsigned long long w[4]; } UINT256;
static void add256 (UINT256 x, UINT256 y, UINT256 * pz)
{
    UINT256 z;
    z.w[0] = x.w[0] + y.w[0];
    z.w[1] = x.w[1] + y.w[1];
    z.w[2] = x.w[2] + y.w[2];
    z.w[3] = x.w[3] + y.w[3];
    *pz = z;
}
static inline void bid128_ext_fma ()
{
  UINT256 C4;
  UINT256 R256;
  add256 (C4, R256, &R256);
  nr_digits256 (R256);
}
void __bid128_fma ()
{
  bid128_ext_fma ();
}


ICEs at -O2 -g -m32 with the extra checking.
Comment 6 Jakub Jelinek 2013-03-08 12:15:38 UTC
Locations are useless in DECL_DEBUG_EXPR expressions, so I have nothing against that SRA change, but please note that also gimplify.c and tree-complex.c create
DECL_DEBUG_EXPRs, so those places should be investigated too.
In gimplify.c sounds like *to_p is always DECL_P though, and in tree-complex.c REALPART_EXPR or IMAGPART_EXPR of a DECL_P where the expr is created with build1 (thus doesn't have loc?).
Comment 7 Richard Biener 2013-03-08 12:25:50 UTC
Created attachment 29620 [details]
inliner patches

For the inliner I've now synced copy_tree_body_r and remap_gimple_op_r wrt
MEM_REFs (to no avail).  I also added debug-expr remapping to copy_debug_stmt
(as the tree-ssa-live.c code shows not all debug-expr decls are in local-decls),
to no avail either.

See attachment.
Comment 8 Richard Biener 2013-03-08 12:42:12 UTC
We don't even copy the decl with the DECL_DEBUG_EXPR in copy_debug_stmt during
the 2nd inlining!  Because when the decls disappear from local-decls nothing
remaps them and we get into

  else if (TREE_CODE (t) == VAR_DECL
           && !is_global_var (t)
           && !pointer_map_contains (id->decl_map, t))
    /* T is a non-localized variable.  */;

so we absolutely rely on being able to share DECL_DEBUG_EXPR for those!

Thus, the SRA patch is correct and verification should be made even stricter.
Comment 9 Richard Biener 2013-03-08 13:46:35 UTC
Author: rguenth
Date: Fri Mar  8 13:46:18 2013
New Revision: 196546

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196546
Log:
2013-03-08  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56570
	* tree-cfg.c (verify_expr_location_1): Verify locations for
	DECL_DEBUG_EXPR.
	* tree-sra.c (create_access_replacement): Strip locations
	from DECL_DEBUG_EXPRs.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-cfg.c
    trunk/gcc/tree-sra.c
Comment 10 Richard Biener 2013-03-08 13:46:57 UTC
Fixed.