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

felix <felix.von.s at posteo dot de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |felix.von.s at posteo dot de

--- Comment #1 from felix <felix.von.s at posteo dot de> ---
> Unfortunately the macro trick is arcane and has one potential issue: the 
> compiler may actually generate code to check `cond` at run-time if it cannot 
> deduce that it's a pure function.

Oh, don't worry; the Other Compiler’s solution isn’t perfect either :)

    __builtin_assume(({ for (;;) {}; 1; }));

This emits code for the infinite loop. For a less silly example:

    __attribute__((__const__,__always_inline__))
    inline static int is_pow2(unsigned j) {
        __auto_type i = j;

        for (int c = 0; c < CHAR_BIT * sizeof(i); ++c) {
            i = (i >> 1) | ((i & 1) << (CHAR_BIT * sizeof(i) - 1));
            if (i == 1)
                break;
        }

        return i == 1;
    }

    int foo(void) {
        extern unsigned bar(void);
        __auto_type x = bar();

        __builtin_assume(is_pow2(x));

        return __builtin_popcount(x);
    }

This will also emit code for the loop, even though the result is not used at
runtime. The code is not very idiomatic, but I don’t believe it’s wrong either:
the __attribute__((const)) on is_pow2 I consider correct, because the side
effects do not escape the function.

If anyone takes this up, it would be nice if GCC at least did not outright
pessimise such code.

Reply via email to