Make integer_all_onesp use TYPE_PRECISION, do not truncate BIT_*_EXPR to bitfield precision, fix PR18908

Message ID alpine.LNX.2.00.1107191158360.810@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener July 19, 2011, 10:01 a.m.
This patch fixes PR18908, both the redundant bitfield truncation and
the allegedly missing tree simplification of Bool ^ 1 to ~Bool.  The
former is because we for no reason truncate the result of bitwise
binary expressions again (not needed, operands are already truncated).
The latter is because integer_all_onesp uses the mode precision
to determine if all bits are set for an unsigned constant - that's
never true for all non-mode precision types (and thus Bool).  There
is no reason for this restriction now that expansion of BIT_NOT_EXPR
is fixed.

Bootstrapped and tested on x86_64-unknown-linux-gnu, leaving a bit
for comments in case there are some.


2011-07-19  Richard Guenther  <>

	PR middle-end/18908
	* tree.c (integer_all_onesp): Use TYPE_PRECISION, not MODE_PRECISION.
	* expr.c (expand_expr_real_2): Do not unnecessarily truncate the
	result of BIT_*_EXPR to bitfield precision.


Index: gcc/tree.c
--- gcc/tree.c	(revision 176399)
+++ gcc/tree.c	(working copy)
@@ -1759,9 +1759,7 @@  integer_all_onesp (const_tree expr)
   if (!uns)
     return 0;
-  /* Note that using TYPE_PRECISION here is wrong.  We care about the
-     actual bits, not the (arbitrary) range of the type.  */
+  prec = TYPE_PRECISION (TREE_TYPE (expr));
   if (prec >= HOST_BITS_PER_WIDE_INT)
       HOST_WIDE_INT high_value;
Index: gcc/expr.c
--- gcc/expr.c	(revision 176399)
+++ gcc/expr.c	(working copy)
@@ -8319,6 +8319,12 @@  expand_expr_real_2 (sepops ops, rtx targ
   temp = expand_binop (mode, this_optab, op0, op1, target,
 		       unsignedp, OPTAB_LIB_WIDEN);
   gcc_assert (temp);
+  /* Bitwise operations do not need bitfield reduction as we expect their
+     operands being properly truncated.  */
+  if (code == BIT_XOR_EXPR
+      || code == BIT_AND_EXPR
+      || code == BIT_IOR_EXPR)
+    return temp;
   return REDUCE_BIT_FIELD (temp);