------- Comment #24 from rguenth at gcc dot gnu dot org 2007-05-13 13:02 ------- That leaves aliasing and DCE.
The following statement connects to the initializing of the function pointer. # SFT.78D.2952_55 = V_MAY_DEF <SFT.78D.2952_31>; # VUSE <D.2838_29>; thisD.2828_22->functor_D.2399 = D.2838; but, D.2839_30 = 0B; # SFT.78D.2952_32 = V_MUST_DEF <SFT.78D.2952_55>; D.2831.bound1_D.2423 = D.2839_30; kills it. Still they look like they are accessing different fields (propagating pointers for the first expression): # SFT.78D.2952_55 = V_MAY_DEF <SFT.78D.2952_31>; # VUSE <D.2838_29>; D.2831.D.2432.functor_D.2382.functor_D.2399 = D.2838; so my hint at a frontend problem with type-layout. Scheduling some more early cleanup passes before the first DCE shows this (and fixes the segfault!?): # SFT.79D.2951_66 = V_MUST_DEF <SFT.79D.2951_49>; # VUSE <D.2836_27>; D.2435.D.2432.functor_D.2382.functor_D.2399 = D.2836; D.2837_28 = 0B; # SFT.78D.2950_30 = V_MUST_DEF <SFT.78D.2950_29>; D.2435.bound1_D.2423 = D.2837_28; note how we no longer thing the second store kills the first one. Which makes it look like an aliasing problem again. Scheduling another may_alias pass before the first DCE also fixes the problem, as we then have # SFT.88D.2960_48 = V_MAY_DEF <SFT.88D.2960_29>; # SFT.89D.2961_61 = V_MAY_DEF <SFT.89D.2961_49>; # VUSE <D.2836_27>; thisD.2827_20->functor_D.2399 = D.2836; D.2837_28 = 0B; # SFT.88D.2960_30 = V_MUST_DEF <SFT.88D.2960_48>; D.2435.bound1_D.2423 = D.2837_28; aliasing is fixed as long as the extra may_alias pass is after CCP, but that CCP pass doesn't do too much interesting stuff to the above stmts: # SFT.88D.2960_48 = V_MAY_DEF <SFT.88D.2960_29>; # VUSE <D.2836_27>; thisD.2827_20->functor_D.2399 = D.2836; # VUSE <_A_b1D.2819_9>; - D.2837_28 = *_A_bound1D.2820_11; + D.2837_28 = _A_b1D.2819; # SFT.88D.2960_30 = V_MUST_DEF <SFT.88D.2960_48>; D.2435.bound1_D.2423 = D.2837_28; and if you diff a may_alias pass before and after CCP you get @@ -487,20 +489,20 @@ _A_bound1_11 = { _A_b1 } this_12 = { D.2435 D.2435.bound1_ } D.2435 = { } -D.2435.bound1_ = { NULL } +D.2435.bound1_ = { NULL foo } this_13 = { D.2435 D.2435.bound1_ } _A_functor_14 = { D.2328 } this_15 = { D.2435 D.2435.bound1_ } this_16 = { D.2435 D.2435.bound1_ } this_17 = { D.2435 D.2435.bound1_ } this_18 = { D.2435 D.2435.bound1_ } -this_19 = { D.2435.bound1_ } -this_20 = { D.2435.bound1_ } +this_19 = { D.2435 D.2435.bound1_ } +this_20 = { D.2435 D.2435.bound1_ } _A_functor_21 = { D.2328 } -this_22 = { D.2435.bound1_ } -this_23 = { D.2435.bound1_ } -this_24 = { D.2435.bound1_ } -this_25 = { D.2435.bound1_ } +this_22 = { D.2435 D.2435.bound1_ } +this_23 = { D.2435 D.2435.bound1_ } +this_24 = { D.2435 D.2435.bound1_ } +this_25 = { D.2435 D.2435.bound1_ } D.2836 = { foo } D.2837_28 = { NULL } functor_31 = { D.2435 D.2435.bound1_ } @@ -510,8 +512,6 @@ functor_35 = { D.2435 D.2435.bound1_ } this_36 = { NULL NONLOCAL.105 foo call_it } this_37 = { NULL NONLOCAL.105 foo call_it } -structcopydereftmp.127 = { NULL } -structcopydereftmp.127.bound1_ = { NULL } rep_38 = { NULL NONLOCAL.105 foo call_it } this_39 = { D.2301 } D.2301 = { NULL NONLOCAL.105 foo call_it } @@ -524,7 +524,7 @@ call_it = { NULL NONLOCAL.105 foo call_it } D.2967_47 = { call_it } which should be the most interesting parts of the diff (apart from the extra vops that prevent the DCE). Danny? Any hints on what can go wrong here? -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dberlin at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30252