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

--- Comment #18 from Thiago Macieira <thiago at kde dot org> ---
(In reply to Richard Biener from comment #16)
> Oh, and checking whether the original Qt issue is solved as well is of
> course appreciated!

No, it looks like it hasn't fixed the problem.

With the Qt reproducer from the original report, I still see ud2:

$ ~/dev/gcc/bin/g++ -I $QTOBJDIR/include -S -o - -O2 -g0 qstringview-repro.cpp
        .file   "qstringview-repro.cpp"
        .text
        .section       
.text._ZN7Scanner12scanForSignsEv,"axG",@progbits,_ZN7Scanner12scanForSignsEv,comdat
        .align 2
        .p2align 4
        .weak   _ZN7Scanner12scanForSignsEv
        .type   _ZN7Scanner12scanForSignsEv, @function
_ZN7Scanner12scanForSignsEv:
.LFB7687:
        .cfi_startproc
        ud2
        .cfi_endproc

You only need the Qt 6.11 headers for this, no need to link.

In any case, the AI created a new, C-only reproducer which still has the
problem:

$ cat r7.c
typedef struct { long size; const short *data; } SV;
typedef struct { SV given; } Scanner;
long findString(SV h, long from, SV n);
const short *strchr16(const short *b, const short *e, short c);

static inline long findChar(SV h, long from, short c)
{
    if ((unsigned long)from < (unsigned long)h.size) {
        const short *n = strchr16(h.data + from, h.data + h.size, c);
        if (n != h.data + h.size)
            return n - h.data;
    }
    return -1;
}

static inline long indexOf(const SV *h, SV n, long from)
{
    if (__builtin_constant_p(n.size) && n.size == 1)
        return findChar(*h, from, n.data[0]);
    return findString(*h, from, n);
}

static int scanForToken(Scanner *s, SV sought)
{
    long n = sought.size;
    long idx = -n;
    int count = 0;
    while ((idx = indexOf(&s->given, sought, idx + n)) >= 0)
        ++count;
    return count;
}

__attribute__((noinline)) int scanForSigns(Scanner *s)
{
    static const short minus[] = { 0x2212 };
    SV m = { 1, minus };
    return scanForToken(s, m);
}

int f(SV h)
{
    Scanner s = { h };
    return scanForSigns(&s);
}

$ ~/dev/gcc/bin/gcc -S -o - -O2 r7.c
        .file   "r7.c"
        .text
        .p2align 4
        .globl  scanForSigns
        .type   scanForSigns, @function
scanForSigns:
.LFB3:
        .cfi_startproc
        ud2
        .cfi_endproc

The insight from the AI (wrongly or not) was:
• The inlined char search has a bounds check,  if ((unsigned long)from <
(unsigned long)h.size) . Removing it makes the test pass.
• The haystack is read through a pointer ( &s->given ).

Reply via email to