Before I added the previous optimization, I got this warning and code on mingw:
$ gcc-3 -mno-cygwin -DHAVE_CONFIG_H -I. -I.. -DGNULIB_STRICT_CHECKING=1 -I/usr/local/mingw/include -Wall -S -O2 ffsl.c In file included from ffsl.c:3: ffsl.h: In function `ffsl': ffsl.h:44: warning: right shift count >= width of type $ cat ffsl.s .file "ffsl.c" .text .p2align 4,,15 .globl _ffsl .def _ffsl; .scl 2; .type 32; .endef _ffsl: pushl %ebp xorl %eax, %eax movl %esp, %ebp movl 8(%ebp), %edx testl %edx, %edx je L1 xorl %ecx, %ecx bsfl %edx, %eax sete %cl negl %ecx orl %ecx, %eax incl %eax L1: popl %ebp ret This is considerably longer than necessary. With the patch below, the code boils down to $ cat ffsl.s .file "ffsl.c" .text .p2align 4,,15 .globl _ffsl .def _ffsl; .scl 2; .type 32; .endef _ffsl: pushl %ebp xorl %edx, %edx movl %esp, %ebp bsfl 8(%ebp), %eax sete %dl negl %edx popl %ebp orl %edx, %eax incl %eax ret Also, the warning goes away by use of a valid shift count, even in dead code. And let me add a comment about a tempting code change that would provoke a test failure on Solaris 10/x86 with "cc -O" (only when -O is present - a clear indication for a compiler bug). 2011-10-13 Bruno Haible <br...@clisp.org> ffsl: Optimize on 32-bit platforms. * lib/ffsl.h (FUNC): If TYPE has the same representation as 'int', just use ffs() without a loop. *** lib/ffsl.h.orig Fri Oct 14 02:10:41 2011 --- lib/ffsl.h Fri Oct 14 02:09:43 2011 *************** *** 34,51 **** #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined GCC_BUILTIN return GCC_BUILTIN (i); #else ! int result = 0; ! unsigned TYPE j = i; ! ! /* GCC has __builtin_ffs, but it is limited to int. */ ! if (!i) ! return 0; ! while (1) { ! if ((unsigned int) j) ! return result + ffs ((unsigned int) j); ! j >>= CHAR_BIT * sizeof (unsigned int); ! result += CHAR_BIT * sizeof (unsigned int); } #endif } --- 34,67 ---- #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined GCC_BUILTIN return GCC_BUILTIN (i); #else ! if (sizeof (TYPE) == sizeof (int)) ! return ffs (i); ! else { ! unsigned TYPE j = i; ! /* Split j into chunks, and look at one chunk after the other. */ ! /* Define chunk_bits so as to avoid a GCC warning ! "right shift count >= width of type" ! if sizeof (TYPE) == sizeof (int). */ ! enum ! { ! chunk_bits = (sizeof (TYPE) != sizeof (int) ! ? CHAR_BIT * sizeof (unsigned int) ! : 0) ! }; ! int result = 0; ! ! /* It is tempting to write if (!j) here, but if we do this, ! Solaris 10/x86 "cc -O" miscompiles the code. */ ! if (!i) ! return 0; ! while (1) ! { ! if ((unsigned int) j) ! return result + ffs ((unsigned int) j); ! j >>= chunk_bits; ! result += chunk_bits; ! } } #endif } -- In memoriam Bekir Çoban-zade <http://en.wikipedia.org/wiki/Bekir_Çoban-zade>