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.

Thanks,
Richard.

>
> ChangeLog
>
> 2012-01-10  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 all languages (including Ada and Obj-C++).  Ok for 
> apply?
>
> Regards,
> Kai
>
> 2012-01-10  Kai Tietz  <kti...@redhat.com>
>
>        * gcc.c-torture/execute/pr48814.c: New test.
>
> Index: gcc/gcc/gimplify.c
> ===================================================================
> --- gcc.orig/gcc/gimplify.c
> +++ gcc/gcc/gimplify.c
> @@ -2258,7 +2258,7 @@ gimplify_self_mod_expr (tree *expr_p, gi
>       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)
>     {
> Index: gcc/gcc/testsuite/gcc.c-torture/execute/pr48814.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.c-torture/execute/pr48814.c
> @@ -0,0 +1,18 @@
> +extern void abort (void);
> +
> +int arr[] = {1,2,3,4};
> +int count = 0;
> +
> +int __attribute__((noinline))
> +incr (void)
> +{
> +  return ++count;
> +}
> +
> +int main()
> +{
> +  arr[count++] = incr ();
> +  if (count != 2 || arr[count] != 3)
> +    abort ();
> +  return 0;
> +}

Reply via email to