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.

Reply via email to