Where and how to report an optimisation issue that doesn't cause a crash

Hi David,

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.
I also added this in the stackoverflow question at the bottom.
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:

typedef struct
{
    event_t                     queue[256]; // changed from pointer to array with max size
    size_t                      size;
    uint16_t                    num_of_items;
    uint8_t                     rd_idx;
    uint8_t                     wr_idx;
} queue_t;

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?
However the generated assembly code still contained the same re-reads...
Any idea why would this happen even with the new "queue_t" struct definition?

P.S.
I can easily reproduce it and provide any additional data which can be gathered during the compilation process, if it helps.

Thanks,
Alex.

Here’s a simpler version which I believe still captures the essence of the issue: https://godbolt.org/z/BUoLq1

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)

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: https://godbolt.org/z/Ax62Fv which avoids reloading size after the assignment to the array.

‪On Thu, Oct 24, 2019 at 12:53 PM ‫אלכס לופ’‬‎ <alex_lop@walla.com> wrote:‬