http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50168
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-08-24 09:21:11 UTC --- But it is just undefined value, not undefined behavior. If you do: --- rtlanal.c 2011-08-23 19:46:13.000000000 +0200 +++ rtlanal.c 2011-08-24 11:18:01.720582231 +0200 @@ -4256,21 +4256,17 @@ nonzero_bits1 (const_rtx x, enum machine case CLZ: /* If CLZ has a known value at zero, then the nonzero bits are that value, plus the number of bits in the mode minus one. */ - if (CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) - nonzero - |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; - else - nonzero = -1; + if (!CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) + nonzero = 0; + nonzero |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; break; case CTZ: /* If CTZ has a known value at zero, then the nonzero bits are that value, plus the number of bits in the mode minus one. */ - if (CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) - nonzero - |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; - else - nonzero = -1; + if (!CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero)) + nonzero = 0; + nonzero |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1; break; case CLRSB: then __builtin_clzl (x) & 0xff will happily give 0xdeadbeef as result if x happens to be 0. Similarly long y = (short) __builtin_clzl (x) will result in y being any value from LONG_MIN to LONG_MAX, instead of any value from SHORT_MIN to SHORT_MAX.