<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jun 26, 2014 at 9:11 AM, Arthur O'Dwyer <span dir="ltr"><<a href="mailto:arthur.j.odwyer@gmail.com" target="_blank">arthur.j.odwyer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On Thu, Jun 26, 2014 at 4:10 AM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>

> On Wed, Jun 25, 2014 at 7:34 PM, Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br>
>> On Wed, Jun 25, 2014 at 3:26 PM, Sanjin Sijaric <<a href="mailto:ssijaric@codeaurora.org">ssijaric@codeaurora.org</a>> wrote:<br>
>> ><br>
>> >>     int *p;<br>
>> >>     typedef struct {<br>
>> >>       char a;<br>
>> >>       char b[100];<br>
>> >>       char c;<br>
>> >>     } S;<br>
>> >><br>
>> >>     S x;<br>
>> >><br>
>> >>     void func1 (char d) {<br>
>> >>       for (int i = 0; i < 100; i++) {<br>
>> >>         x.b[i] += 1;<br>
>> >>         d = *p;<br>
>> >>         x.a += d;<br>
>> >>       }<br>
>> >>     }<br>
>> >><br>
>> >> It seems like you want the compiler to hoist the read of `*p` above the<br>
>> >> write to `x.b[i]`.<br>
>> >> But that isn't generally possible, is it? because the caller might have<br>
>> >> executed<br>
>> >><br>
>> >>    p = &x.b[3];<br>
>> >><br>
>> >> before the call to func1.<br>
</div>[…]<br>
<div class="">> I think that's backwards from the intent: if you swap over 'int' and 'char'<br>
> in the example, we cannot do the reordering, because p could point to (some<br>
> byte of) one of the ints.<br>
><br>
> With the test as-is, we *can* reorder the *p load (and even move it out of<br>
> the loop):<br>
>   -- *p cannot alias x.b[i], because if 'x.b[i] += 1' has defined behavior,<br>
> then x is an object of type S and x.b is an object of type char[100] and 0<br>
> <= i < 100, and therefore there is no int object aliased by that store<br>
<br>
</div>You left out one step there, which needs to be made explicit IMO: the<br>
fact that we *store* into a *single byte* of x.b is important.<br>
Obviously we could not do the same optimization on<br>
<br>
    size_t nbytes = sizeof(int);<br>
<div class="">    for (int i = 0; i < 100; i++) {<br>
</div>      __builtin_memcpy(x.b, &i, nbytes);<br>
<div class="">      d = *p;<br>
      x.a += d;<br>
    }<br>
<br>
</div>because that would basically nerf "omnipotent char" (and "placement<br>
new" in general).</blockquote><div><br></div><div>Even in this case, you can in principle hoist out the load. The expression 'x.b' would have undefined behavior if there weren't an S object at that address, and if there's an S object, there's not an int. This is probably more than we want to optimize -- it'll break too much real world code -- even with -fstruct-path-tbaa.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If the compiler can actually detect that the size<br>
of the last access was incommensurate with the size of the load being<br>
reordered, then I withdraw my objection, but otherwise it really seems<br>
like this is a super dangerous optimization.<br>
<div class=""><br>
<br>
>   -- *p cannot alias x.a, because if 'x.a += d' has defined behavior, then x<br>
> is an object of type S, so a store to S::a cannot alias any int object.<br>
<br>
</div>This one I agree with your logic, btw. A named object of type 'char'<br>
(being only one byte in size) clearly cannot alias with type 'int'<br>
(being four bytes in size).  My objections apply only to cases<br>
analogous to<br>
<br>
    template<class T><br>
    struct Container {<br>
        char data[N + sizeof T];<br>
    };<br>
<br>
–Arthur<br>
</blockquote></div><br></div></div>