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] 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;
      }


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