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 PR49937


This fixes PR49937 - callers of get_{pointer,object}_alignment
probably should not use BIGGEST_ALIGNMENT to limit what these
functions return (why do they do that?  Maybe because formerly
the routines returned TYPE_ALIGN?  But why wasn't that bound by
BIGGEST_ALIGNMENT?) - some targets define that as 8 (such as cris or avr).

At least CCP shouldn't care and with the following patch simply
trusts what DECL_ALIGN and friend tells us (which hopefully is correct 
...).

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Anybody know about BIGGEST_ALIGNMENTs implication on correctness?

Thanks,
Richard.

2011-08-09  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/49937
	* tree-ssa-ccp.c (get_value_from_alignment): Re-implement
	using get_object_alignment_1.

Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c	(revision 177558)
--- gcc/tree-ssa-ccp.c	(working copy)
*************** value_to_double_int (prop_value_t val)
*** 505,578 ****
  static prop_value_t
  get_value_from_alignment (tree expr)
  {
    prop_value_t val;
!   HOST_WIDE_INT bitsize, bitpos;
!   tree base, offset;
!   enum machine_mode mode;
!   int align;
  
    gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
  
!   base = get_inner_reference (TREE_OPERAND (expr, 0),
! 			      &bitsize, &bitpos, &offset,
! 			      &mode, &align, &align, false);
!   if (TREE_CODE (base) == MEM_REF)
!     val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr),
! 			   TREE_OPERAND (base, 0), TREE_OPERAND (base, 1));
!   else if (base
! 	   && ((align = get_object_alignment (base, BIGGEST_ALIGNMENT))
! 		> BITS_PER_UNIT))
!     {
!       val.lattice_val = CONSTANT;
!       /* We assume pointers are zero-extended.  */
!       val.mask = double_int_and_not
! 	           (double_int_mask (TYPE_PRECISION (TREE_TYPE (expr))),
! 		    uhwi_to_double_int (align / BITS_PER_UNIT - 1));
!       val.value = build_int_cst (TREE_TYPE (expr), 0);
!     }
    else
!     {
!       val.lattice_val = VARYING;
!       val.mask = double_int_minus_one;
!       val.value = NULL_TREE;
!     }
!   if (bitpos != 0)
!     {
!       double_int value, mask;
!       bit_value_binop_1 (PLUS_EXPR, TREE_TYPE (expr), &value, &mask,
! 			 TREE_TYPE (expr), value_to_double_int (val), val.mask,
! 			 TREE_TYPE (expr),
! 			 shwi_to_double_int (bitpos / BITS_PER_UNIT),
! 			 double_int_zero);
!       val.lattice_val = double_int_minus_one_p (mask) ? VARYING : CONSTANT;
!       val.mask = mask;
!       if (val.lattice_val == CONSTANT)
! 	val.value = double_int_to_tree (TREE_TYPE (expr), value);
!       else
! 	val.value = NULL_TREE;
!     }
!   /* ???  We should handle i * 4 and more complex expressions from
!      the offset, possibly by just expanding get_value_for_expr.  */
!   if (offset != NULL_TREE)
!     {
!       double_int value, mask;
!       prop_value_t oval = get_value_for_expr (offset, true);
!       bit_value_binop_1 (PLUS_EXPR, TREE_TYPE (expr), &value, &mask,
! 			 TREE_TYPE (expr), value_to_double_int (val), val.mask,
! 			 TREE_TYPE (expr), value_to_double_int (oval),
! 			 oval.mask);
!       val.mask = mask;
!       if (double_int_minus_one_p (mask))
! 	{
! 	  val.lattice_val = VARYING;
! 	  val.value = NULL_TREE;
! 	}
!       else
! 	{
! 	  val.lattice_val = CONSTANT;
! 	  val.value = double_int_to_tree (TREE_TYPE (expr), value);
! 	}
!     }
  
    return val;
  }
--- 505,530 ----
  static prop_value_t
  get_value_from_alignment (tree expr)
  {
+   tree type = TREE_TYPE (expr);
    prop_value_t val;
!   unsigned HOST_WIDE_INT bitpos;
!   unsigned int align;
  
    gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
  
!   align = get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitpos);
!   gcc_assert ((bitpos & (align-1)) == bitpos);
!   val.mask
!     = double_int_and_not (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
! 			  ? double_int_mask (TYPE_PRECISION (type))
! 			  : double_int_minus_one,
! 			  uhwi_to_double_int (align / BITS_PER_UNIT - 1));
!   val.lattice_val = double_int_minus_one_p (val.mask) ? VARYING : CONSTANT;
!   if (val.lattice_val == CONSTANT)
!     val.value
!       = double_int_to_tree (type, uhwi_to_double_int (bitpos / BITS_PER_UNIT));
    else
!     val.value = NULL_TREE;
  
    return val;
  }


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