Summary: | [4.4 Regression] ICE in referenced_var_lookup, at tree-dfa.c:563 | ||
---|---|---|---|
Product: | gcc | Reporter: | macius bat <linuxl4> |
Component: | middle-end | Assignee: | Jakub Jelinek <jakub> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | gcc-bugs, hubicka, jh |
Priority: | P1 | Keywords: | ice-on-valid-code |
Version: | 4.4.0 | ||
Target Milestone: | 4.4.0 | ||
URL: | http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00407.html | ||
Host: | x86_64-pc-linux-gnu | Target: | x86_64-pc-linux-gnu |
Build: | x86_64-pc-linux-gnu | Known to work: | |
Known to fail: | Last reconfirmed: | 2009-03-06 20:45:27 | |
Bug Depends on: | |||
Bug Blocks: | 39392 | ||
Attachments: |
the preprocessed source
gcc44-pr39360.patch |
Description
macius bat
2009-03-04 14:34:51 UTC
Created attachment 17393 [details]
the preprocessed source
Reducing. It is most likely caused by revision 144497: http://gcc.gnu.org/ml/gcc-cvs/2009-02/msg00665.html In TODO_recompute_alias after PRE we have something (alc_capture_mixer1, found through DECL_INITIAL of caps) in gimple_addressable_vars that is no longer available. Honza, this is yours again. I guess during inlining we no longer add referenced vars to the inlined-to function if they are addresses of globals referenced through initializers of local statics? static struct snd_kcontrol_new alc_capture_mixer1[]; static void set_capture_mixer(struct alc_spec *spec) { static struct snd_kcontrol_new *caps[3] = { alc_capture_mixer1, alc_capture_mixer2, alc_capture_mixer3, }; if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) spec->cap_mixer = caps[spec->num_adc_nids - 1]; } inlined into some other function. Proper testcase still reducing. Reduced testcase: typedef unsigned short u16; struct snd_kcontrol_new { }; typedef u16 hda_nid_t; struct alc_spec { struct snd_kcontrol_new *cap_mixer; unsigned int num_adc_nids; }; static struct snd_kcontrol_new alc_capture_mixer1[] = { }; static struct snd_kcontrol_new alc_capture_mixer2[] = { }; static struct snd_kcontrol_new alc_capture_mixer3[] = { }; static void set_capture_mixer(struct alc_spec *spec) { static struct snd_kcontrol_new *caps[3] = { alc_capture_mixer1, alc_capture_mixer2, alc_capture_mixer3 }; if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) spec->cap_mixer = caps[spec->num_adc_nids - 1]; } static hda_nid_t alc662_adc_nids[1] = { 0x09, }; int patch_alc662(struct hda_codec *codec) { struct alc_spec *spec; spec->num_adc_nids = (sizeof(alc662_adc_nids) / sizeof((alc662_adc_nids)[0]) + (sizeof(char[1 - 2 * !!(__builtin_types_compatible_p(typeof(alc662_adc_nids), typeof(&alc662_adc_nids[0])))]) - 1)); if (!spec->cap_mixer) set_capture_mixer(spec); } This is curious, since we should see the initializer when adding variable at first time. I am looking into this. Honza Smaller testcase: static int a[] = { 1 }; static inline void bar (int **x) { static int *c[2] = { 0, a }; *x = c[1]; } int foo (int **x) { bar (x); } I think it is the new: 3384 if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var)) 3385 { 3386 if (var_ann (var) && referenced_var_check_and_insert (var)) 3387 cfun->local_decls = tree_cons (NULL_TREE, var, 3388 cfun->local_decls); 3389 } that causes this. Compared to add_referenced_var this doesn't do the: /* Scan DECL_INITIAL for pointer variables as they may contain address arithmetic referencing the address of other variables. Even non-constant initializers need to be walked, because IPA passes might prove that their are invariant later on. */ if (DECL_INITIAL (var) /* Initializers of external variables are not useful to the optimizers. */ && !DECL_EXTERNAL (var)) walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0); part. So, either tree-inline.c needs to do the same, or it can't use referenced_vars bit as a test whether it has been queued already onto local_decls or not. Honza? Subject: Re: [4.4 Regression] ICE in referenced_var_lookup, at tree-dfa.c:563
> part. So, either tree-inline.c needs to do the same, or it can't use
> referenced_vars bit as a test whether it has been queued already onto
> local_decls or not. Honza?
Ah I see. Actually original version of patch added function to tree-dfa
to check if variable is referenced and used this predicate followed by
add_referenced_var if it was not, but then I noticed that
referenced_var_check_and_insert is available to I decided to use it.
OK, I will prepare this version of patch tomorrow.
To "do the same" the easiest would be probably change add_referenced_var to return bool, whatever referenced_var_check_and_insert returned, and use add_referenced_var instead of referenced_var_check_and_insert in expand_call_inline. Created attachment 17412 [details] gcc44-pr39360.patch Patch I'm bootstrapping/regtesting now. Subject: Bug 39360 Author: jakub Date: Fri Mar 6 22:51:28 2009 New Revision: 144683 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144683 Log: PR middle-end/39360 * tree-flow.h (add_referenced_var): Return bool instead of void. * tree-dfa.c (add_referenced_var): Return result of referenced_var_check_and_insert call. * tree-inline.c (expand_call_inline): Call add_referenced_var instead of referenced_var_check_and_insert. * gcc.c-torture/compile/pr39360.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/compile/pr39360.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-dfa.c trunk/gcc/tree-flow.h trunk/gcc/tree-inline.c Fixed. thanks a lot. |