public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/113665] New: Regular for Loop results in Endless Loop with -O2
@ 2024-01-29 23:11 christoph at muppetnet dot net
  2024-01-29 23:14 ` [Bug c++/113665] " christoph at muppetnet dot net
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: christoph at muppetnet dot net @ 2024-01-29 23:11 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 113665
           Summary: Regular for Loop results in Endless Loop with -O2
           Product: gcc
           Version: 11.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: christoph at muppetnet dot net
  Target Milestone: ---

Compiling the example code below with GCC 11.4.0 (I actually encountered this
bug in all versions >= 11 which I tried but not in older ones) and -O2 (other
optimization levels seem to work) results in an endless loop and finally a
segmentation fault due to an out-of-bounds access.

We can clearly argue about issues in the implementation of the bitfield class
(it is based on a real implementation of such a class I encountered in existing
codebase) but the main problem here is that the simple for loop in bug() is
generated into an endless loop. I think regardless of how the test method is
implemented, this loop should always terminate correctly.

#include <cstdint>
#include <cstddef>
#include <array>
#include <climits>

template<size_t S>
class bitfield
{
private:
    using Element = uint8_t;

    static constexpr uint32_t C = (S - 1u) / 8u;

private:
    std::array<Element, C + 1> m_Array;

public:
    bool test(size_t i) const
    {   
        if (i >= S){
            return false;
        }

        const size_t index = static_cast<uint32_t>(i) / 8u;
        const Element bitmask = 1u << (i % 8u);
        return (m_Array[index] & bitmask) != 0u;
    }
};

void bug2(const bitfield<0x120u> &b)
{
    if (!b.test(1u))
    {
        volatile int test = 1;
    }
}

void bug(const bitfield<0x250u> &b)
{
    for (uint16_t i = 0u; i < 0x250u; i++)
    {
        // this loop seems to not properly terminate
        if (!b.test(i))
        {
            volatile int test = i;
        }
    }
}

int main()
{
    bitfield<0x250u> b;
    bug(b);
    return 0;
}

Looking at the generated assembler code (in this example ARM64 generated in
godbolt.org, the same issue is also present on my x86-64 machine) we can see,
that the check for i < 0x250 is completely lost. Actually, at .L9 we do the
increment of the loop variable and then unconditionally jump back to .L10 for
the next iteration.

bug(bitfield<592ul> const&):
        sub     sp, sp, #16
        mov     w2, 0
        mov     w4, 1
.L10:
        lsr     w3, w2, 3
        and     w1, w2, 7
        lsl     w1, w4, w1
        ldrb    w3, [x0, w3, uxtw]
        and     w1, w1, w3
        tst     w1, 255
        bne     .L9
        str     w2, [sp, 12]
.L9:
        add     w2, w2, 1
        b       .L10

During testing of different variants of the code I encountered that there seem
to be different (but totally unexpected) ways to solve the issue:

- adding -fno-tree-vrp or -fno-guess-branch-probability
- deleting method bug2
- changing the type of i to size_t

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-03-09 17:10 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-29 23:11 [Bug c++/113665] New: Regular for Loop results in Endless Loop with -O2 christoph at muppetnet dot net
2024-01-29 23:14 ` [Bug c++/113665] " christoph at muppetnet dot net
2024-01-30  0:25 ` [Bug ipa/113665] " pinskia at gcc dot gnu.org
2024-01-30  6:01 ` [Bug ipa/113665] [11/12/13/14 regression] " sjames at gcc dot gnu.org
2024-01-30  6:04 ` pinskia at gcc dot gnu.org
2024-01-30  8:11 ` rguenth at gcc dot gnu.org
2024-01-30  8:16 ` rguenth at gcc dot gnu.org
2024-01-30  9:12 ` [Bug ipa/113665] [11/12/13/14 regression] Regular for Loop results in Endless Loop with -O2 since r11-4987-g602c6cfc79ce4a sjames at gcc dot gnu.org
2024-01-30 17:21 ` hubicka at ucw dot cz
2024-01-31  7:35 ` rguenth at gcc dot gnu.org
2024-03-09 17:10 ` law at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).