This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid creating useless BIT_FIELD_REFs (PR middle-end/19858)


Hi!

The following testcase ICEs at -O1+ on IA-32.  The problem is that
verify_expr mandates that BIT_FIELD_REF's inner tree is either
handled_component_p, a CONSTANT_CLASS_P or an gimple lvalue,
but for !(((size_t) &foo & 3) == 0 && !((size_t) &foo & 1))
fold_truthop creates BIT_FIELD_REF <ADDR_EXPR <something>, 32, 0>
where that ADDR_EXPR is neither constant, nor an lvalue.
But we IMHO shouldn't be creating such bogus BIT_FIELD_REF at all,
simply fold_converting ADDR_EXPR in this case to the desired type
is enough, as the bit field covers the whole value.
This can either be done in several places of fold_truthop,
or in make_bit_field_ref as done in the patch below.
Doing it in make_bit_field_ref avoids code duplication.

2005-02-10  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/19858
	* fold-const.c (make_bit_field_ref): If bitpos == 0 and bitsize
	is number of inner's bits, avoid creating a BIT_FIELD_REF.

	* gcc.c-torture/compile/20050210-1.c: New test.

--- gcc/fold-const.c.jj	2005-02-10 12:59:39.000000000 +0100
+++ gcc/fold-const.c	2005-02-10 17:41:52.257220736 +0100
@@ -3076,8 +3076,18 @@ static tree
 make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
 		    int unsignedp)
 {
-  tree result = build3 (BIT_FIELD_REF, type, inner,
-			size_int (bitsize), bitsize_int (bitpos));
+  tree result;
+
+  if (bitpos == 0)
+    {
+      tree size = TYPE_SIZE (TREE_TYPE (inner));
+      if (host_integerp (size, 0) 
+	  && tree_low_cst (size, 0) == bitsize)
+	return fold_convert (type, inner);
+    }
+
+  result = build3 (BIT_FIELD_REF, type, inner,
+		   size_int (bitsize), bitsize_int (bitpos));
 
   BIT_FIELD_REF_UNSIGNED (result) = unsignedp;
 
--- gcc/testsuite/gcc.c-torture/compile/20050210-1.c	2005-01-27 14:27:08.338732320 +0100
+++ gcc/testsuite/gcc.c-torture/compile/20050210-1.c	2005-02-10 17:44:41.141063751 +0100
@@ -0,0 +1,8 @@
+/* PR middle-end/19858 */
+
+typedef __SIZE_TYPE__ size_t;
+union U { int c; } foo;
+int bar (void)
+{
+  return !(((size_t) &foo & 3) == 0 && !((size_t) &foo & 1));
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]