This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Avoid creating useless BIT_FIELD_REFs (PR middle-end/19858)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Feb 2005 11:56:18 -0500
- Subject: [PATCH] Avoid creating useless BIT_FIELD_REFs (PR middle-end/19858)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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