> On Jul 1, 2021, at 9:09 AM, Richard Sandiford <richard.sandif...@arm.com> > wrote: > > Qing Zhao <qing.z...@oracle.com> writes: >>> On Jul 1, 2021, at 1:48 AM, Richard Biener <richard.guent...@gmail.com> >>> wrote: >>> >>> On Wed, Jun 30, 2021 at 9:15 PM Qing Zhao via Gcc-patches >>> <gcc-patches@gcc.gnu.org> wrote: >>>> >>>> >>>> >>>>> On Jun 30, 2021, at 1:59 PM, Richard Biener <rguent...@suse.de> wrote: >>>>> >>>>> On June 30, 2021 8:07:43 PM GMT+02:00, Qing Zhao <qing.z...@oracle.com> >>>>> wrote: >>>>>> >>>>>> >>>>>>> On Jun 30, 2021, at 12:36 PM, Richard Biener <rguent...@suse.de> >>>>>> wrote: >>>>>>> >>>>>>> On June 30, 2021 7:20:18 PM GMT+02:00, Andrew Pinski >>>>>> <pins...@gmail.com> wrote: >>>>>>>> On Wed, Jun 30, 2021 at 8:47 AM Qing Zhao via Gcc-patches >>>>>>>> <gcc-patches@gcc.gnu.org> wrote: >>>>>>>>> >>>>>>>>> I came up with a very simple testing case that can repeat the same >>>>>>>> issue: >>>>>>>>> >>>>>>>>> [qinzhao@localhost gcc]$ cat t.c >>>>>>>>> extern void bar (int); >>>>>>>>> void foo (int a) >>>>>>>>> { >>>>>>>>> int i; >>>>>>>>> for (i = 0; i < a; i++) { >>>>>>>>> if (__extension__({int size2; >>>>>>>>> size2 = 4; >>>>>>>>> size2 > 5;})) >>>>>>>>> bar (a); >>>>>>>>> } >>>>>>>>> } >>>>>>>> >>>>>>>> You should show the full dump, >>>>>>>> What we have is the following: >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> size2_3 = PHI <size2_1(D), size2_13> >>>>>>>> <bb 3> : >>>>>>>> >>>>>>>> size2_12 = .DEFERRED_INIT (size2_3, 2); >>>>>>>> size2_13 = 4; >>>>>>>> >>>>>>>> So CCP decides to propagate 4 into the PHI and then decides >>>>>> size2_1(D) >>>>>>>> is undefined so size2_3 is then considered 4 and propagates it into >>>>>>>> the .DEFERRED_INIT. >>>>>>> >>>>>>> Which means the DEFERED_INIT is inserted at the wrong place. >>>>>> >>>>>> Then, where is the correct place for “.DEFERRED_INIT(size2,2)? >>>>>> >>>>>> The variable “size2” is a block scope variable which is declared inside >>>>>> the “if” condition: >>>>> >>>>> But that's obviously not how it behaves >>>>> During into SSA phase since we're inserting a PHI for it - and we're >>>>> inserting it because of the use in the DEFERED_INIT call. I suppose you >>>>> need to fiddle with the SSA rewrite and avoid treating the use as a use >>>>> but only for the purpose of inserting PHIs... >>>> >>>> Please see my other email on the new small testing case without >>>> -ftrivial-auto-var-init. The same issue in SSA with that testing case >>>> even without -ftrivial-auto-var-init. >>>> It looks like an existing bug to me in SSA. >>> >>> It's not a bug in SSA, it's at most a missed optimization there. >> >> I still think that SSA cannot handle block-scoped variable correctly in this >> case, it should not move the variable out side of the block scope. -:) >> >>> But >>> with -ftrivial-auto-var-init it >>> becomes a correctness issue. > > I might have lost track of what “it” is here. Do you mean the progation, > or the fact that we have a PHI in the first place?
“PHI” out of the live scope of the corresponding variable. > > For: > > unsigned int > f (int n) > { > unsigned int res = 0; > for (int i = 0; i < n; i += 1) > { > unsigned int foo; > foo += 1; > res = foo; > } > return res; > } > > we generate: > > unsigned int foo; > int i; > unsigned int res; > unsigned int _8; > > <bb 2> : > res_4 = 0; > i_5 = 0; > goto <bb 4>; [INV] > > <bb 3> : > foo_10 = foo_3 + 1; > res_11 = foo_10; > i_12 = i_2 + 1; > > <bb 4> : > # res_1 = PHI <res_4(2), res_11(3)> > # i_2 = PHI <i_5(2), i_12(3)> > # foo_3 = PHI <foo_6(D)(2), foo_10(3)> > if (i_2 < n_7(D)) > goto <bb 3>; [INV] > else > goto <bb 5>; [INV] > > <bb 5> : > _8 = res_1; > return _8; > > IMO the foo_3 PHI makes no sense. foo doesn't live beyond its block, > so there should be no loop-carried dependency here. > > So yeah, if “it” meant that the fact that variables live too long, > then I agree that becomes a correctness issue with this feature, > rather than just an odd quirk. Yes, I think so. > Could we solve it by inserting > a clobber at the end of the variable's scope, or something like that? Yes, I think that will be a good solution. > >>> I think the idea avoiding the USE of the variable in .DEFERRED_INIT >>> and instead passing the init size is a good one and should avoid this >>> case (hopefully). >> >> >> Agreed, I have made such change yesterday, and this work around the current >> issue. >> >> temp = .DEFERRED_INIT (temp/WITH_SIZE_EXPR(temp), init_type) >> >> To: >> >> temp = .DEFERRED_INIT (SIZE_of_temp, init_type) > > I think we're going round in circles here though. The point of having > the undefined input was so that we would continue to warn about undefined > inputs. The above issue doesn't seem like a good justification for > dropping that. Actually, in the current patch, the .DEFERRED_INIT calls are handled specially for uninitialized warnings Analysis, this call itself is treated as the undefined input. Therefore, even after I made the above change, all the uninitialized warnings still are kept well. So, I think that this change should be fine for keeping the uninitialized warnings. Qing > > Thanks, > Richard > >