On Wed, Jan 11, 2012 at 11:19 AM, Kai Tietz <ktiet...@googlemail.com> wrote: > 2012/1/11 Richard Guenther <richard.guent...@gmail.com>: >> On Wed, Jan 11, 2012 at 11:05 AM, Richard Guenther >> <richard.guent...@gmail.com> wrote: >>> On Tue, Jan 10, 2012 at 11:58 AM, Kai Tietz <ktiet...@googlemail.com> wrote: >>>> 2012/1/10 Richard Guenther <richard.guent...@gmail.com>: >>>>> On Tue, Jan 10, 2012 at 10:58 AM, Kai Tietz <ktiet...@googlemail.com> >>>>> wrote: >>>>>> Ping >>>>>> >>>>>> 2012/1/8 Kai Tietz <ktiet...@googlemail.com>: >>>>>>> Hi, >>>>>>> >>>>>>> this patch makes sure that for increment of >>>>>>> postfix-increment/decrement we use also orignal lvalue instead of tmp >>>>>>> lhs value for increment. This fixes reported issue about sequence >>>>>>> point in PR/48814 >>>>>>> >>>>>>> ChangeLog >>>>>>> >>>>>>> 2012-01-08 Kai Tietz <kti...@redhat.com> >>>>>>> >>>>>>> PR middle-end/48814 >>>>>>> * gimplify.c (gimplify_self_mod_expr): Use for >>>>>>> postfix-inc/dec lvalue instead of temporary >>>>>>> lhs. >>>>>>> >>>>>>> Regression tested for x86_64-unknown-linux-gnu for all languages >>>>>>> (including Ada and Obj-C++). Ok for apply? >>>>>>> >>>>>>> Regards, >>>>>>> Kai >>>>>>> >>>>>>> Index: gimplify.c >>>>>>> =================================================================== >>>>>>> --- gimplify.c (revision 182720) >>>>>>> +++ gimplify.c (working copy) >>>>>>> @@ -2258,7 +2258,7 @@ >>>>>>> arith_code = POINTER_PLUS_EXPR; >>>>>>> } >>>>>>> >>>>>>> - t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs); >>>>>>> + t1 = build2 (arith_code, TREE_TYPE (*expr_p), lvalue, rhs); >>>>>>> >>>>>>> if (postfix) >>>>>>> { >>>> >>>> Hi Richard, >>>> >>>>> Please add testcases. Why does your patch make a difference? >>>>> lhs is just the gimplified lvalue. >>>> >>>> yes, exactly this makes a big difference for post-inc/dec. I show you >>>> gimple-dump to illustrate this in more detail. I used here -O2 option >>>> with using attached patch. >>>> >>>> gcc without that patch produces following gimple for main: >>>> >>>> main () >>>> { >>>> int count.0; >>>> int count.1; >>>> int D.2721; >>>> int D.2725; >>>> int D.2726; >>>> >>>> count.0 = count; <-- here we store orginal value 'count' for having >>>> array-access-index >>>> D.2721 = incr (); <- within that function count gets modified >>>> arr[count.0] = D.2721; >>>> count.1 = count.0 + 1; <- Here happens the issue. We increment the >>>> saved value of 'count' >>>> count = count.1; <- By this the modification of count in incr() gets void. >>>> ... >>>> >>>> By the change we make sure to use count's value instead its saved >>>> temporary. >>>> >>>> Patched gcc produces this gimple: >>>> >>>> main () >>>> { >>>> int count.0; >>>> int count.1; >>>> int D.1718; >>>> int D.1722; >>>> int D.1723; >>>> >>>> count.0 = count; >>>> D.1718 = incr (); >>>> arr[count.0] = D.1718; >>>> count.0 = count; <-- Reload count.0 for post-inc/dec to use count's >>>> current value >>>> count.1 = count.0 + 1; >>>> count = count.1; >>>> count.0 = count; >>>> >>>> Ok, here is the patch with adusted testcase from PR. >>> >>> With your patch we generate wrong code for >>> >>> volatile int count; >>> int arr[4]; >>> void foo() >>> { >>> arr[count++] = 0; >>> } >>> >>> as we load from count two times instead of once. Similar for >>> >>> volatile int count; >>> void bar(int); >>> void foo() >>> { >>> bar(count++); >>> } >>> >>> Please add those as testcases for any revised patch you produce. >> >> I think a proper fix involves changing the order we gimplify the >> lhs/rhs for calls. > > Hmm, I don't see actual wrong code here. But I might missed something in > spec. > > For exampl1 we get: > foo () > { > volatile int count.0; > volatile int count.1; > volatile int count.2; > > count.0 = count; > arr[count.0] = 0; > count.1 = count; > count.2 = count.1 + 1; > count = count.2; > }
count despite being declared volatile and only loaded once in the source is loaded twice in gimple. If it were a HW register which destroys the device after the 2nd load without an intervening store you'd wrecked the device ;) Richard. > and here is no wrong code AFAICS. > > For second example we get: > > foo () > { > volatile int count.0; > volatile int count.1; > volatile int count.2; > volatile int count.3; > > count.0 = count; > count.3 = count.0; > count.1 = count; > count.2 = count.1 + 1; > count = count.2; > bar (count.3); > } > > Here we don't have wrong code either AFAICS. Passed argument to bar is > the value before increment, and count get incremented by 1 before call > of bar, which is right. > > Thanks for more details, > Kai