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

--- Comment #3 from acsawdey at gcc dot gnu.org ---
It appears that gcc decided to split the bdnzt generated by the memcmp
expansion because the destination was out of range, and produced this:

        bdz $+12
        beq 0,$+8
        b $+8;b .L939
        bne 0,.L937 ; --> to setb code

So after the second iteration the bdz should branch to the bne which branches
to a setb if there was a difference or falls through and does an overlapping
compare to get the last 4 bytes of the 36 being compared.

But the disassembly when I look at things in gdb has an extra branch in there
which messes things up:

   0x0000000010008b90 <constant+33360>: bdz     0x10008b9c <constant+33372>
   0x0000000010008b94 <constant+33364>: beq     0x10008b9c <constant+33372>
   0x0000000010008b98 <constant+33368>: b       0x10008ba0 <constant+33376>
   0x0000000010008b9c <constant+33372>: b       0x10000b8c <constant+588>
   0x0000000010008ba0 <constant+33376>: bne     0x10000bac <constant+620>

So now the bdz branches to a branch to b8c which is back to the top of the loop
to compare another 16 bytes which is of course wrong.

It's possible this all happened because I didn't generate labels in the
splitter, so multiple conditional branches had to be split because they were
out of range.

Reply via email to