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.

Reply via email to