--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+[[gnu::noipa]] bool
+foo (unsigned x)
+{
+ x &= 0x499a750a;
+ x |= 0x5a7c04f;
+ x = __builtin_bitreverse32 (x);
+ return (x & ~0x351848) == 0x4fc0a705;
+}
+
+[[gnu::noipa]] bool
+bar (unsigned x)
+{
+ x &= 0x499a750a;
+ x |= 0x5a7c04f;
+ x = __builtin_bitreverse32 (x);
+ return (x & ~0xac1812) == 0xf203e5a0;
+}
+#endif
+
+int
+main ()
+{
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+ if (foo (~0) || !bar (~0))
+ __builtin_abort ();
+#endif
+}
case BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP64:
case BUILT_IN_BSWAP128:
- case BUILT_IN_BITREVERSE8:
- case BUILT_IN_BITREVERSE16:
- case BUILT_IN_BITREVERSE32:
- case BUILT_IN_BITREVERSE64:
val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
if (val.lattice_val == UNDEFINED)
break;
val.mask = -1;
break;
+ case BUILT_IN_BITREVERSE8:
+ case BUILT_IN_BITREVERSE16:
+ case BUILT_IN_BITREVERSE32:
+ case BUILT_IN_BITREVERSE64:
+ val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
+ if (val.lattice_val == UNDEFINED)
+ break;
+ else if (val.lattice_val == CONSTANT
+ && val.value
+ && TREE_CODE (val.value) == INTEGER_CST)
+ {
+ tree type = TREE_TYPE (gimple_call_lhs (stmt));
+ int prec = TYPE_PRECISION (type);
+ wide_int wval = wi::to_wide (val.value);
+ wval = wide_int::from (wval, prec, UNSIGNED);
+ wide_int wmask = wide_int::from (val.mask, prec, UNSIGNED);
+ val.value = wide_int_to_tree (type, wi::bitreverse (wval));
+ val.mask = widest_int::from (wi::bitreverse (wmask),
+ UNSIGNED);
+ if (wi::sext (val.mask, prec) != -1)
+ break;
+ }
+ val.lattice_val = VARYING;
+ val.value = NULL_TREE;
+ val.mask = -1;
+ break;
+
default:;
}
}