<div dir="ltr"><div dir="ltr">Here's a simpler version which I believe still captures the essence of the issue: <a href="https://godbolt.org/z/BUoLq1" target="_blank">https://godbolt.org/z/BUoLq1</a><br><br>Yep, looks like GCC manages this optimization and Clang does not - the runtime bound on the array is stopping clang from going further here (perhaps that's intentional - maybe to allow the array indexed store to possibly exceed the bounds of the array and assign to 'size' that comes after it - UB, but I don't know just how far non-strict aliasing goes)<br><br>Yeah, looks like it might be something like that ^ if you change the index to be unsigned, and reorder the members so 'size' comes before the array (so indexing into the array can't alias 'size'), you do get: <a href="https://godbolt.org/z/Ax62Fv" target="_blank">https://godbolt.org/z/Ax62Fv</a> which avoids reloading size after the assignment to the array.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">‪On Thu, Oct 24, 2019 at 12:53 PM ‫אלכס לופ'‬‎ <<a href="mailto:alex_lop@walla.com" target="_blank">alex_lop@walla.com</a>> wrote:‬<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="rtl"><div dir="ltr">Hi David,<br><br></div>
<div dir="ltr"> </div>
<div dir="ltr">Thanks for your reply. The fact that "queue_ptr->queue[queue_ptr->wr_idx++]" could be somewhere in the object pointed by "queue_ptr" came to my mind too.</div>
<div dir="ltr">I also added this in the stackoverflow question at the bottom.</div>
<div dir="ltr">In such case, I assumed, that if I change the struct "queue_t" to have an array of "event_t" instead of just pointer to "event_t", like this:</div>
<div dir="ltr"> </div>
<div dir="ltr">
<pre><code><span>typedef</span> <span>struct</span>
<span>{</span>
    <span>event_t</span>                     <span>queue</span><span>[</span><span>256</span><span>];</span> <span>// changed from pointer to array with max size</span>
    <span>size_t</span><span>                      size</span><span>;</span>
    <span>uint16_t</span><span>                    num_of_items</span><span>;</span>
    <span>uint8_t</span><span>                     rd_idx</span><span>;</span>
    <span>uint8_t</span><span>                     wr_idx</span><span>;</span>
<span>}</span> <span>queue_t</span><span>;</span></code><br><br>there would be no valid way (without breaking the C standard definitions) that "queue_ptr->queue[queue_ptr->wr_idx++]" ends up somewhere inside "*queue_ptr", right?<br>However the generated assembly code still contained the same re-reads...<br>Any idea why would this happen even with the new "queue_t" struct definition?<br><br>P.S.<br>I can easily reproduce it and provide any additional data which can be gathered during the compilation process, if it helps.<br><br>Thanks,<br>Alex.</pre>
</div>
<div id="gmail-m_6399794515280957024gmail-m_-1659663878248091923gtx-trans"> </div></div>
</blockquote></div>
</div>