If the optimiser does such a reordering it is still bound to the C specification, so such a reordering would become:
uint64_t u64_z = (uint64_t)u32_x + (uint64_t)u32_y + u64_a;
Rationale:
We start with
uint64_t u64_z = u32_x + u64_a + u32_y;
Addition is performed left-to-right.
The integer promotion rules state that in the first addition in the original expression, u32_x be promoted to uint64_t. In the second addition, u32_y will also be promoted to uint64_t.
So, in order to be compliant with the C specification, any optimiser must promote u32_x and u32_y to 64 bit unsigned values. This is equivalent to adding a cast. (The actual optimising is not done at the C level, but I use C notation because that is a notation that we understand.)