On 6/27/19 10:12 AM, Jakub Jelinek wrote:
> On Thu, Jun 27, 2019 at 09:15:41AM -0600, Jeff Law wrote:
>> Actually it was trivial to create with store merging.
>>
>> char x[20];
>> foo()
>> {
>>   x[0] = 0x41;
>>   x[1] = 0x42;
>> }
>>
>>   MEM <unsigned short> [(char *)&x] = 16961;
>>
>> So clearly we can get this in gimple.  So we need a check of some kind,
>> either on the LHS or the RHS to ensure that we actually have a single
>> character store as opposed to something like the above.
> 
> handle_char_store is only called if:
>           tree type = TREE_TYPE (lhs);
>           if (TREE_CODE (type) == ARRAY_TYPE)
>             type = TREE_TYPE (type);
>           if (TREE_CODE (type) == INTEGER_TYPE
>               && TYPE_MODE (type) == TYPE_MODE (char_type_node)
>               && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node))
>             {
>               if (! handle_char_store (gsi))
>                 return false;
>             }
> so the above case will not trigger, the only way to call it for multiple
> character stores is if you have an array.  And so far I've succeeded
> creating that just with strcpy builtin.
How I could have missed it so many times is a mystery to me.  I
literally was looking at this on the phone with Martin today for the nth
time and my brain just wouldn't parse this code correctly.

We can only get into handle_char_store for an LHS that is a character or
array of characters.  So the only case we have to worry about would be
if we have a constant array on the RHS.  Something like this from Jakub:

 MEM <char[2]> [(char *)&x] = MEM <char[2]> [(char *)"ab"];

But in this case the RHS is going to be an ARRAY_TYPE.  And thus
Martin's new code would reject it because it would only do the
optmiization if the RHS has INTEGER_TYPE.

So I think my concerns are ultimately a non-issue.

FWIW if you're trying to get something like Jakub's assignment, this
will do it:

  char a[7];
  int f ()
  {
    __builtin_strcpy (a, "654321");
  }

Which results in this being passed to handle_char_store:

  MEM <unsigned char[7]> [(char * {ref-all})&a] = MEM <unsigned char[7]>
[(char * {ref-all})"654321"];

We can make it more problematical by first doing a strcpy into a so that
we create an SI structure.  Something like this:

 char a[7];
  int f ()
  {
    strcpy (a, "123");
    __builtin_strcpy (a, "654321");
  }

Compiled with -O2 -fno-tree-dse (the -fno-tree-dse ensures the first
strcpy is not eliminated).

That should get us into handle_char_store and into the new code from
Martin's patch that wants to test:



+      if (cmp > 0
+         && storing_nonzero_p
+         && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)

But the RHS in this case has an ARRAY_TYPE and Martin's test would
reject it.


So at this point my concerns are alleviated.

Jakub, Richi, do either of you have concerns?  I've kindof owned the
review of this patch from Martin, but since y'all have chimed in, I'd
like to give you another chance to chime in before I ACK.

jeff

ps.  FWIW, the gimple FE seems to really dislike constant strings in MEM
expressions like we've been working with.  It also seems to go into an
infinite loop if you've got an extra closing paren on the RHS..  It was
still useful to poke at things a bit.  One could argue that if we get
the FE to a suitable state that it could define what is and what is not
valid gimple.  That would likely be incredibly help for this kind of stuff.

Reply via email to