[Bug c/65892] gcc fails to implement N685 aliasing of union members

david at westcontrol dot com gcc-bugzilla@gcc.gnu.org
Sat Apr 21 13:38:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #37 from David Brown <david at westcontrol dot com> ---
(In reply to Martin Sebor from comment #35)
> Here are the proposed changes:
> 
> Pointer Provenance:
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2219.htm#proposed-technical-
> corrigendum
> 
> Trap Representations:
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2220.htm#proposed-technical-
> corrigendum
> 
> Unspecified Values:
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2221.htm#proposed-technical-
> corrigendum

I am a little unsure of the suggestions for unspecified values here.  Can I
give some examples, to see if my interpretation is correct?

Let's use a new gcc builtin "__builtin_unspecified()" that returns an
unspecified value of int type, with no possible traps (no gcc target has trap
representations for int types, AFAIK).

    int x = __builtin_unspecified();
    int y = __builtin_unspecified();

    if (x == y) doThis();  // The compiler can skip doThis()
    if (x != y) doThat();  // The compiler can skip doThat() too

    if (x == y) doThis(); else doThat();  
    // The compiler can choose to doThis() or doThat(),
    // but must do one or the other

    if (x == x) doThis();  // This compiler must doThis()
    if (x != x) doThat();  // The compiler cannot doThat()

    if (x == 3) doThis();  // The compiler can choose to doThis()
    // if the compiler does choose to doThis() the it fixes the value of x as 3

    if (x & 0x01) doThis(); else doThat();
    // The compiler can choose do doThis() or doThat(),
    // but that choice fixes the LSB of x

This could allow for a range of possible optimisations, especially if there is
a nice way to make unspecified values like __builtin_unspecified(). 
(Unspecified values of other types could be made by casts.)  For example:

    struct opt_int { bool valid; int value; };
    struct opt_int safe_sqrt(struct opt_int x) {
        opt_int y;
        if (!x.valid || x.value < 0) {
            y.valid = false;
            y.value = __builtin_unspecified();
        } else {
            y.valid = true;
            y.value = unsafe_sqrt(x.value);
        }
        return y;
     }

This kind of structure would mean minimal effort when you only need part of a
struct to contain specified values.


More information about the Gcc-bugs mailing list