https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110790
Bug ID: 110790 Summary: [14 Regression] gcc -m32 generates invalid bit test code on gmp-6.2.1 Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: slyfox at gcc dot gnu.org Target Milestone: --- Initially observed test failures on gmp-6.2.1 when building with gcc r14-2736-gd07504725973cc Extracted reproducer: // $ cat /tmp/a.c typedef unsigned long int mp_limb_t; typedef const mp_limb_t * mp_srcptr; __attribute__((noipa)) int refmpn_tstbit_bad (mp_srcptr ptr, unsigned long bit) { return (((ptr)[(bit)/(32 - 0)] & (((mp_limb_t) 1L) << ((bit)%(32 - 0)))) != 0); } __attribute__((noipa, optimize(0))) int refmpn_tstbit_good (mp_srcptr ptr, unsigned long bit) { return (((ptr)[(bit)/(32 - 0)] & (((mp_limb_t) 1L) << ((bit)%(32 - 0)))) != 0); } __attribute__((noipa)) int refmpn_tstbit (mp_srcptr ptr, unsigned long bit) { if (refmpn_tstbit_bad (ptr, bit) != refmpn_tstbit_good (ptr, bit)) { __builtin_trap(); } return refmpn_tstbit_bad (ptr, bit); } int main(){ unsigned long num[] = { 0x3801ff9f, 0x0, 0x0, 0x0 }; refmpn_tstbit(num, 0); } $ gcc -m32 -fomit-frame-pointer /tmp/a.c -o /tmp/a -O2 && /tmp/a Illegal instruction (core dumped) $ gcc -m32 -fomit-frame-pointer /tmp/a.c -o /tmp/a && /tmp/a # ok It looks like refmpn_tstbit_bad() does something odd with bit shifts: Dump of assembler code for function refmpn_tstbit_bad: 0x08049200 <+0>: mov 0x8(%esp),%eax ; bit 0x08049204 <+4>: mov 0x4(%esp),%edx ; ptr 0x08049208 <+8>: mov %eax,%ecx 0x0804920a <+10>: shr $0x5,%ecx ; ecx = bit / 32 (limbs) 0x0804920d <+13>: mov (%edx,%ecx,4),%edx ; edx = ptr[ecx] 0x08049210 <+16>: bt %eax,%edx ; might be ok if 'bit' does not overflow? 0x08049213 <+19>: setae %al 0x08049216 <+22>: movzbl %al,%eax 0x08049219 <+25>: ret I can't see any problems with this code on the data we pass here. $ gcc -v Using built-in specs. COLLECT_GCC=/<<NIX>>/xgcc-14.0.0/bin/gcc COLLECT_LTO_WRAPPER=/<<NIX>>/xgcc-14.0.0/libexec/gcc/i686-unknown-linux-gnu/14.0.0/lto-wrapper Target: i686-unknown-linux-gnu Configured with: ../source/configure --prefix=/<<NIX>>/xgcc-14.0.0 --with-gmp-include=/<<NIX>>/gmp-6.2.1-dev/include --with-gmp-lib=/<<NIX>>/gmp-6.2.1/lib --with-mpfr-include=/<<NIX>>/mpfr-4.2.0-dev/include --with-mpfr-lib=/<<NIX>>/mpfr-4.2.0/lib --with-mpc=/<<NIX>>/libmpc-1.3.1 --with-native-system-header-dir=/<<NIX>>/bootstrap-stage0-glibc-bootstrapFiles/include --with-build-sysroot=/ --program-prefix= --disable-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 --with-arch=i686 --with-native-system-header-dir=/include --with-build-sysroot=/<<NIX>>/bootstrap-stage0-glibc-bootstrapFiles --build=i686-unknown-linux-gnu --host=i686-unknown-linux-gnu --target=i686-unknown-linux-gnu Thread model: posix Supported LTO compression algorithms: zlib gcc version 14.0.0 99999999 (experimental) (GCC) refmpn_tstbit_bad() gets compile