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

            Bug ID: 119428
           Summary: [15 Regression] wrong code on e2fsprogs-1.47.2 since
                    r15-8478-ge8a5f747cfa9c7
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: slyfox at gcc dot gnu.org
  Target Milestone: ---

Initially observed as a test suite failure of e2fsprogs-1.47.2 against
r15-8478-ge8a5f747cfa9c7 (bisected):

LD_LIBRARY_PATH="../../lib:${LD_LIBRARY_PATH}"
DYLD_LIBRARY_PATH="../../lib:${DYLD_LIBRARY_PATH}" ./tst_bitmaps -l -f
./tst_bitmaps_cmds > tst_bitmaps_out
Illegal block number passed to ext2fs_test_block_bitmap #0 for block bitmap
Illegal block number passed to ext2fs_test_block_bitmap #1 for block bitmap
Illegal block number passed to ext2fs_test_block_bitmap #13 for block bitmap
Illegal inode number passed to ext2fs_test_inode_bitmap #0 for inode bitmap
Illegal inode number passed to ext2fs_test_inode_bitmap #1 for inode bitmap
diff ./tst_bitmaps_exp tst_bitmaps_out
75c75
< Blocks 12 to 18 are all clear.
---
> Blocks 12 to 18 are NOT all clear.
83c83
< Blocks 12 to 18 are all clear.
---
> Blocks 12 to 18 are NOT all clear.

I was not able to extract the exact reproducer yet, but I think I narrowed the
miscompilation down to

    void ext2fs_fast_clear_bit_(unsigned int nr, void * addr)
    {
        unsigned char   *ADDR = (unsigned char *) addr;

        ADDR += nr >> 3;
        *ADDR &= (unsigned char) ~(1 << (nr & 0x07));
    }

-O1 build passes all tests while -O2 breaks the bit resetting.

I was not able to extract exact compiler options, but I think these are:

COLLECT_GCC_OPTIONS='-fPIC' '-fstack-clash-protection' '-O2' '-U'
'_FORTIFY_SOURCE' '-Wformat=1' '-Wformat-security' '-Werror=format-security'
'-fzero-call-used-regs=used-gpr' '-fstack-protector-strong'
'--param=ssp-buffer-size=4' '-fno-strict-overflow' '-I' '.' '-I' '../../lib'
'-I' '../../lib' '-g' '-O2' '-pthread' '-D' 'HAVE_CONFIG_H' '-c' '-o'
'gen_bitmap.o' '-v' '-U' '_FORTIFY_SOURCE' '-D' '_FORTIFY_SOURCE=3'

$ gcc -v |& unnix
Using built-in specs.
COLLECT_GCC=/<<NIX>>/gcc-15.0.1/bin/gcc
COLLECT_LTO_WRAPPER=/<<NIX>>/gcc-15.0.1/libexec/gcc/x86_64-unknown-linux-gnu/15.0.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../source/configure --prefix=/<<NIX>>/gcc-15.0.1
--with-gmp-include=/<<NIX>>/gmp-6.3.0-dev/include
--with-gmp-lib=/<<NIX>>/gmp-6.3.0/lib
--with-mpfr-include=/<<NIX>>/mpfr-4.2.2-dev/include
--with-mpfr-lib=/<<NIX>>/mpfr-4.2.2/lib --with-mpc=/<<NIX>>/libmpc-1.3.1
--with-native-system-header-dir=/<<NIX>>/glibc-2.41-4-dev/include
--with-build-sysroot=/
--with-gxx-include-dir=/<<NIX>>/gcc-15.0.1/include/c++/15.0.1/
--program-prefix= --enable-lto --disable-libstdcxx-pch
--without-included-gettext --with-system-zlib --enable-checking=release
--enable-static --enable-languages=c,c++ --disable-multilib --enable-plugin
--disable-libcc1 --with-isl=/<<NIX>>/isl-0.20 --disable-bootstrap
--build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu
--target=x86_64-unknown-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.0.1 99999999 (experimental) (GCC)

Pasting generated assembly of that function in case it's obvious what is broken
(unmasked `btr` against the register looks off):

ok:

00000000000017a0 <ext2fs_fast_clear_bit_>:
    17a0:       mov    %edi,%ecx
    17a2:       mov    %edi,%edx
    17a4:       shr    $0x3,%edx
    17a7:       mov    %edx,%edx
    17a9:       and    $0x7,%ecx
    17ac:       mov    $0x1,%eax
    17b1:       shl    %cl,%eax
    17b3:       not    %eax
    17b5:       and    %al,(%rsi,%rdx,1)
    17b8:       xor    %eax,%eax
    17ba:       xor    %edx,%edx
    17bc:       xor    %ecx,%ecx
    17be:       xor    %esi,%esi
    17c0:       xor    %edi,%edi
    17c2:       ret

bad:

00000000000017a0 <ext2fs_fast_clear_bit_>:
    17a0:       mov    %edi,%edx
    17a2:       shr    $0x3,%edx
    17a5:       movzbl (%rsi,%rdx,1),%eax
    17a9:       btr    %edi,%eax ; is it ok?
    17ac:       mov    %al,(%rsi,%rdx,1)
    17af:       xor    %eax,%eax
    17b1:       xor    %edx,%edx
    17b3:       xor    %esi,%esi
    17b5:       xor    %edi,%edi
    17b7:       ret

Reply via email to