2012/2/9 Richard Guenther <richard.guent...@gmail.com>:
> On Thu, Feb 9, 2012 at 3:41 PM, Richard Guenther
> <richard.guent...@gmail.com> wrote:
>> On Thu, Feb 9, 2012 at 2:48 PM, Kai Tietz <ktiet...@googlemail.com> wrote:
>>> 2012/2/9 Richard Guenther <richard.guent...@gmail.com>:
>>>> On Thu, Feb 9, 2012 at 11:53 AM, Richard Guenther
>>>> <richard.guent...@gmail.com> wrote:
>>>>> On Thu, Feb 9, 2012 at 11:29 AM, Richard Guenther
>>>>> <richard.guent...@gmail.com> wrote:
>>>>>> On Wed, Feb 8, 2012 at 10:25 PM, Kai Tietz <ktiet...@googlemail.com> 
>>>>>> wrote:
>>>>>>> 2012/1/11 Richard Guenther <richard.guent...@gmail.com>:
>>>>>>>>
>>>>>>>> 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.
>>>>>>>
>>>>>>> Thanks for explaination.  I tried to flip order for lhs/rhs in
>>>>>>> gimplify_modify_expr & co.  Issue here is that for some cases we are
>>>>>>> relying here on lhs for gimplifying rhs (is_gimple_reg_rhs_or_call vs
>>>>>>> is_gimple_mem_rhs_or_call) and this doesn't work for cases in C++
>>>>>>> like:
>>>>>>>
>>>>>>> typedef const unsigned char _Jv_Utf8Const;
>>>>>>> typedef __SIZE_TYPE__ uaddr;
>>>>>>>
>>>>>>> void maybe_adjust_signature (_Jv_Utf8Const *&s, uaddr &special)
>>>>>>> {
>>>>>>>  union {
>>>>>>>    _Jv_Utf8Const *signature;
>>>>>>>    uaddr signature_bits;
>>>>>>>  };
>>>>>>>  signature = s;
>>>>>>>  special = signature_bits & 1;
>>>>>>>  signature_bits -= special;
>>>>>>>  s = signature;
>>>>>>> }
>>>>>>>
>>>>>>> So I modified gimplify_self_mod_expr for post-inc/dec so that we use
>>>>>>> following sequence
>>>>>>> and add it to pre_p for it:
>>>>>>>
>>>>>>> tmp = lhs;
>>>>>>> lvalue = tmp (+/-) rhs
>>>>>>> *expr_p = tmp;
>>>>>>
>>>>>> As I explained this is the wrong place to fix the PR.  The issue is not
>>>>>> about self-modifying expressions but about evaluating call argument
>>>>>> side-effects before side-effects of the lhs.
>>>>>
>>>>> I am testing the attached instead.
>>>>
>>>> Doesn't work.  Btw, Kai, your patch surely breaks things if you put
>>>> the lvalue update into the pre queue.
>>>>
>>>> Consider a simple
>>>>
>>>>  a[i++] = i;
>>>>
>>>> you gimplify that to
>>>>
>>>>  i.0 = i;
>>>>  D.1709 = i.0;
>>>>  i = D.1709 + 1;
>>>>  a[D.1709] = i;
>>>>
>>>> which is wrong.
>>>>
>>>> Seems we are lacking some basic pre-/post-modify testcases ...
>>>>
>>>> Richard.
>>>
>>> Why, this should be wrong?  In fact C specification just says that the
>>> post-inc has to happen at least before next sequence-point.  It
>>> doesn't say that the increment has to happen after evaluation of rhs.
>>>
>>> The produced gimple for the following C-code
>>>
>>> int arr[128];
>>>
>>> void foo (int i)
>>> {
>>>  arr[i++] = i;
>>> }
>>>
>>> is:
>>>
>>> foo (int i)
>>> {
>>>  int D.1364;
>>>
>>>  D.1364 = i;
>>>  i = D.1364 + 1;
>>>  arr[D.1364] = i;
>>> }
>>>
>>> which looks to me from description of the C-specification correct.
>>
>> Hm, indeed.  I'll test the following shorter patch and add the struct-return
>> volatile testcase.
>
> Works apart from
>
> Running target unix/
> FAIL: ext/pb_ds/regression/trie_map_rand.cc execution test
> FAIL: ext/pb_ds/regression/trie_set_rand.cc execution test
>
> Maybe invalid testcases.  Who knows ... same fails happen with your patch.
>
> Richard.
>
>> Richard.

Hmm, I see in libstdc++'s file include/bits/boost_concept_check.h some
use of '*__i++ = *__i;' and '*__i-- = *__i;', which seems to cause
part of this failure.

This might lead here to this failure.  I am not sure, if such
constructs having fixed behavior for C++, but it looks to me like
undefined behavior.

A C-testcase for the issue would be:

int *foo (int *p)
{
  *p++ = *p;
  return p;
}

which produces with patch now:

foo (int * p)
{
  int * D.1363;
  int D.1364;
  int * D.1365;

  D.1363 = p;
  p = D.1363 + 4;
  D.1364 = *p;
  *D.1363 = D.1364;
  D.1365 = p;
  return D.1365;
}

but in old variant we were producing:

foo (int * p)
{
  int D.1363;
  int * D.1364;

  D.1363 = *p;
  *p = D.1363;
  p = p + 4;
  D.1364 = p;
  return D.1364;
}

So, maybe the real solution for this issue might be to swap for
assignment gimplification the order for lhs/rhs gimplification
instead.


Regards,
Kai

Reply via email to