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

            Bug ID: 123300
           Summary: Adding [[assume((1<<i) > 0)]] generates an infinite
                    loop
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pieter.p.dev at outlook dot com
  Target Milestone: ---

GCC 14 and 15 generate an infinite loop for the following correct code when
compiling with -O2 -DNDEBUG.

https://godbolt.org/z/bh9hcaG19

    #include <cstdio>
    #include <cassert>

    #ifndef NDEBUG
    #define INVARIANT(x) assert(x)
    #else
    #define INVARIANT(x) [[assume(x)]]
    #endif

    [[gnu::noinline]] void foo(int n, bool do_print) {
        for (int i = n; i-- > 0;) {
            const int x = 1 << i;
            INVARIANT(x > 0);
            if (do_print) std::printf("i=%d x=%d\n", i, x);
        }
    }

    int main() {
        foo(4, true);
        std::puts("Ok");
    }

The loop itself is fine, and x=1<<i is valid and positive for all i in [0, 30],
so the assumption is satisfied (as can be verified by removing -DNDEBUG).
Minor changes (such as removing the assumption, changing the loop direction, or
making the printing unconditional) result in the correct code being generated.

Reply via email to