https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66790
--- Comment #8 from Pierre-Marie de Rodat <derodat at adacore dot com> --- (In reply to Richard Biener from comment #7) > It would be certainly good to see why we have this UNDEF in the first place. Sure: here is a C translation of what happens in my Ada reproducer (only wrt. UNDEF: this is not a reproducer for the original bug). #include <stdint.h> struct option_t { uint16_t is_present; uint16_t value; }; struct option_t foo (uint16_t a, uint16_t b) { struct option_t result; result.is_present = b != 0; if (result.is_present) result.value = a / b; return result; } On x86, foo's return value is the 32-bit value in $eax. If b == 0, its lower half is undefined while its upper one is supposed to be 0. In other words, even though the value field is uninitialized, the is_present one must be 0. Although a trunk GCC produces no zero-extension at -O2 for this example, this simply exposes the source use case for the "half-initialized" value business. > But yes, I have to agree that zext UNDEF >> 16 should be zero. Unlike > sext UNDEF which is always undefined as the sign-bit is undefined. Good point! The patch I submitted previously pessimized the sign-extension case. The one I'm going to upload fixes this: bootstrapped and regtested successfuly on x86_64-linux.