[~]gcc -v gcc version 4.4.0 20090304 (experimental) (GCC) [~]gcc -O2 -c patch_realtek.c sound/pci/hda/patch_realtek.c: In function 'patch_alc861vd': sound/pci/hda/patch_realtek.c:14747: internal compiler error: in referenced_var_lookup, at tree-dfa.c:563 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
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.