This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR35518
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 25 Jun 2008 10:36:24 +0200 (CEST)
- Subject: [PATCH] Fix PR35518
This patch fixes PR35518 by making sure to strip BIT_FIELD_REFs that
just returns its operand and by making SRA fold the BIT_FIELD_REFs
it creates.
Bootstrapped and tested on x86_64-unknown-linux-gnu, David tested
this on hhpa-unknown-linux-gnu and hppa64-hp-hpux11.11.
Applied to trunk.
Richard.
2008-06-23 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35518
* fold-const.c (fold_ternary): Strip trivial BIT_FIELD_REFs.
* tree-sra.c (instantiate_element): Use fold_build3 to build
BIT_FIELD_REFs.
(try_instantiate_multiple_fields): Likewise.
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c (revision 137037)
--- gcc/fold-const.c (working copy)
*************** fold_ternary (enum tree_code code, tree
*** 13117,13122 ****
--- 13117,13129 ----
return fold_convert (type, integer_zero_node);
}
}
+
+ /* A bit-field-ref that referenced the full argument can be stripped. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_PRECISION (TREE_TYPE (arg0)) == tree_low_cst (arg1, 1)
+ && integer_zerop (op2))
+ return fold_convert (type, arg0);
+
return NULL_TREE;
default:
Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c (revision 137037)
--- gcc/tree-sra.c (working copy)
*************** instantiate_element (struct sra_elt *elt
*** 1284,1296 ****
DECL_SIZE_UNIT (var) = DECL_SIZE_UNIT (elt->element);
elt->in_bitfld_block = 1;
! elt->replacement = build3 (BIT_FIELD_REF, elt->type, var,
! DECL_SIZE (var),
! BYTES_BIG_ENDIAN
! ? size_binop (MINUS_EXPR,
! TYPE_SIZE (elt->type),
! DECL_SIZE (var))
! : bitsize_int (0));
}
/* For vectors, if used on the left hand side with BIT_FIELD_REF,
--- 1284,1296 ----
DECL_SIZE_UNIT (var) = DECL_SIZE_UNIT (elt->element);
elt->in_bitfld_block = 1;
! elt->replacement = fold_build3 (BIT_FIELD_REF, elt->type, var,
! DECL_SIZE (var),
! BYTES_BIG_ENDIAN
! ? size_binop (MINUS_EXPR,
! TYPE_SIZE (elt->type),
! DECL_SIZE (var))
! : bitsize_int (0));
}
/* For vectors, if used on the left hand side with BIT_FIELD_REF,
*************** try_instantiate_multiple_fields (struct
*** 1698,1705 ****
type = build_nonstandard_integer_type (size, 1);
gcc_assert (type);
var = build3 (BIT_FIELD_REF, type, NULL_TREE,
! bitsize_int (size),
! bitsize_int (bit));
block = instantiate_missing_elements_1 (elt, var, type);
gcc_assert (block && block->is_scalar);
--- 1698,1704 ----
type = build_nonstandard_integer_type (size, 1);
gcc_assert (type);
var = build3 (BIT_FIELD_REF, type, NULL_TREE,
! bitsize_int (size), bitsize_int (bit));
block = instantiate_missing_elements_1 (elt, var, type);
gcc_assert (block && block->is_scalar);
*************** try_instantiate_multiple_fields (struct
*** 1709,1718 ****
if ((bit & ~alchk)
|| (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
{
! block->replacement = build3 (BIT_FIELD_REF,
! TREE_TYPE (block->element), var,
! bitsize_int (size),
! bitsize_int (bit & ~alchk));
}
block->in_bitfld_block = 2;
--- 1708,1717 ----
if ((bit & ~alchk)
|| (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
{
! block->replacement = fold_build3 (BIT_FIELD_REF,
! TREE_TYPE (block->element), var,
! bitsize_int (size),
! bitsize_int (bit & ~alchk));
}
block->in_bitfld_block = 2;
*************** try_instantiate_multiple_fields (struct
*** 1727,1740 ****
gcc_assert (fld && fld->is_scalar && !fld->replacement);
! fld->replacement = build3 (BIT_FIELD_REF, field_type, var,
! DECL_SIZE (f),
! bitsize_int
! ((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f))
! * BITS_PER_UNIT
! + (TREE_INT_CST_LOW
! (DECL_FIELD_BIT_OFFSET (f))))
! & ~alchk));
fld->in_bitfld_block = 1;
}
--- 1726,1739 ----
gcc_assert (fld && fld->is_scalar && !fld->replacement);
! fld->replacement = fold_build3 (BIT_FIELD_REF, field_type, var,
! DECL_SIZE (f),
! bitsize_int
! ((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f))
! * BITS_PER_UNIT
! + (TREE_INT_CST_LOW
! (DECL_FIELD_BIT_OFFSET (f))))
! & ~alchk));
fld->in_bitfld_block = 1;
}