diff mbox

Make sizetypes no longer sign-extending

Message ID 201205071011.23506.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou May 7, 2012, 8:11 a.m. UTC
> > Sure, no opposition by me to applying the whole set of patches.
>
> Done now.

This has introduced a couple of ACATS failures on x86:

FAIL:   c52102a
FAIL:   c52102c

The problem is that a builtin_memmove is wrongly folded into an assignment 
between MEM_EXPRs, although source and destination are slices which overlap.

In fold_builtin_memory_op:

(gdb) p debug_generic_expr(destvar)
a[0 ...]{lb: 4294967292 sz: 4}
$14 = void
(gdb) p debug_generic_expr(dest_base)
a
$15 = void
(gdb) p dest_offset
$16 = -137438953344

get_ref_base_and_extent (unlike get_inner_reference) doesn't correctly compute 
the offset for ARRAY_REF/ARRAY_RANGE_REF.  The code is also duplicated in 
fold_const_aggregate_ref_1.  Fixing this yields another ACATS failure:

FAIL:   cd2a31a

because fold_array_ctor_reference needs to be adjusted backwards for the now 
correct offset computed by get_ref_base_and_extent.

Tentative fix attached.  Tested on x86_64-suse-linux and i586-suse-linux.


2012-05-07  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset
	computation using the precision of the index type.
	* gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise.
	(fold_array_ctor_reference): Do index computations in the index type.

Comments

Richard Biener May 7, 2012, 9:06 a.m. UTC | #1
On Mon, 7 May 2012, Eric Botcazou wrote:

> > > Sure, no opposition by me to applying the whole set of patches.
> >
> > Done now.
> 
> This has introduced a couple of ACATS failures on x86:
> 
> FAIL:   c52102a
> FAIL:   c52102c
> 
> The problem is that a builtin_memmove is wrongly folded into an assignment 
> between MEM_EXPRs, although source and destination are slices which overlap.
> 
> In fold_builtin_memory_op:
> 
> (gdb) p debug_generic_expr(destvar)
> a[0 ...]{lb: 4294967292 sz: 4}
> $14 = void
> (gdb) p debug_generic_expr(dest_base)
> a
> $15 = void
> (gdb) p dest_offset
> $16 = -137438953344
> 
> get_ref_base_and_extent (unlike get_inner_reference) doesn't correctly compute 
> the offset for ARRAY_REF/ARRAY_RANGE_REF.  The code is also duplicated in 
> fold_const_aggregate_ref_1.  Fixing this yields another ACATS failure:
> 
> FAIL:   cd2a31a
> 
> because fold_array_ctor_reference needs to be adjusted backwards for the now 
> correct offset computed by get_ref_base_and_extent.
> 
> Tentative fix attached.  Tested on x86_64-suse-linux and i586-suse-linux.

Yeah, this kind of fallout is expected.

The patch is ok.

Thanks,
Richard.
diff mbox

Patch

Index: gimple-fold.c
===================================================================
--- gimple-fold.c	(revision 187216)
+++ gimple-fold.c	(working copy)
@@ -2745,7 +2745,7 @@  fold_array_ctor_reference (tree type, tr
   double_int low_bound, elt_size;
   double_int index, max_index;
   double_int access_index;
-  tree domain_type = NULL_TREE;
+  tree domain_type = NULL_TREE, index_type = NULL_TREE;
   HOST_WIDE_INT inner_offset;
 
   /* Compute low bound and elt size.  */
@@ -2755,6 +2755,7 @@  fold_array_ctor_reference (tree type, tr
     {
       /* Static constructors for variably sized objects makes no sense.  */
       gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
+      index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
       low_bound = tree_to_double_int (TYPE_MIN_VALUE (domain_type));
     }
   else
@@ -2778,6 +2779,10 @@  fold_array_ctor_reference (tree type, tr
   access_index = double_int_udiv (uhwi_to_double_int (offset / BITS_PER_UNIT),
 				  elt_size, TRUNC_DIV_EXPR);
   access_index = double_int_add (access_index, low_bound);
+  if (index_type)
+    access_index = double_int_ext (access_index,
+				   TYPE_PRECISION (index_type),
+				   TYPE_UNSIGNED (index_type));
 
   /* And offset within the access.  */
   inner_offset = offset % (double_int_to_uhwi (elt_size) * BITS_PER_UNIT);
@@ -2788,6 +2793,11 @@  fold_array_ctor_reference (tree type, tr
     return NULL_TREE;
 
   index = double_int_sub (low_bound, double_int_one);
+  if (index_type)
+    index = double_int_ext (index,
+			    TYPE_PRECISION (index_type),
+			    TYPE_UNSIGNED (index_type));
+
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
     {
       /* Array constructor might explicitely set index, or specify range
@@ -2805,7 +2815,14 @@  fold_array_ctor_reference (tree type, tr
 	    }
 	}
       else
-	max_index = index = double_int_add (index, double_int_one);
+	{
+	  index = double_int_add (index, double_int_one);
+	  if (index_type)
+	    index = double_int_ext (index,
+				    TYPE_PRECISION (index_type),
+				    TYPE_UNSIGNED (index_type));
+	  max_index = index;
+	}
 
       /* Do we have match?  */
       if (double_int_cmp (access_index, index, 1) >= 0
@@ -2960,18 +2977,23 @@  fold_const_aggregate_ref_1 (tree t, tree
       if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
 	  && valueize
 	  && (idx = (*valueize) (TREE_OPERAND (t, 1)))
-	  && host_integerp (idx, 0))
+	  && TREE_CODE (idx) == INTEGER_CST)
 	{
 	  tree low_bound, unit_size;
+	  double_int doffset;
 
 	  /* If the resulting bit-offset is constant, track it.  */
 	  if ((low_bound = array_ref_low_bound (t),
-	       host_integerp (low_bound, 0))
+	       TREE_CODE (low_bound) == INTEGER_CST)
 	      && (unit_size = array_ref_element_size (t),
-		  host_integerp (unit_size, 1)))
+		  host_integerp (unit_size, 1))
+	      && (doffset = double_int_sext
+			    (double_int_sub (TREE_INT_CST (idx),
+					     TREE_INT_CST (low_bound)),
+			     TYPE_PRECISION (TREE_TYPE (idx))),
+		  double_int_fits_in_shwi_p (doffset)))
 	    {
-	      offset = TREE_INT_CST_LOW (idx);
-	      offset -= TREE_INT_CST_LOW (low_bound);
+	      offset = double_int_to_shwi (doffset);
 	      offset *= TREE_INT_CST_LOW (unit_size);
 	      offset *= BITS_PER_UNIT;
 
Index: tree-dfa.c
===================================================================
--- tree-dfa.c	(revision 187216)
+++ tree-dfa.c	(working copy)
@@ -814,21 +814,24 @@  get_ref_base_and_extent (tree exp, HOST_
 	  {
 	    tree index = TREE_OPERAND (exp, 1);
 	    tree low_bound, unit_size;
+	    double_int doffset;
 
 	    /* If the resulting bit-offset is constant, track it.  */
 	    if (TREE_CODE (index) == INTEGER_CST
-		&& host_integerp (index, 0)
 		&& (low_bound = array_ref_low_bound (exp),
-		    host_integerp (low_bound, 0))
+ 		    TREE_CODE (low_bound) == INTEGER_CST)
 		&& (unit_size = array_ref_element_size (exp),
-		    host_integerp (unit_size, 1)))
+		    host_integerp (unit_size, 1))
+		&& (doffset = double_int_sext
+			      (double_int_sub (TREE_INT_CST (index),
+					       TREE_INT_CST (low_bound)),
+			       TYPE_PRECISION (TREE_TYPE (index))),
+		    double_int_fits_in_shwi_p (doffset)))
 	      {
-		HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
-
-		hindex -= TREE_INT_CST_LOW (low_bound);
-		hindex *= TREE_INT_CST_LOW (unit_size);
-		hindex *= BITS_PER_UNIT;
-		bit_offset += hindex;
+		HOST_WIDE_INT hoffset = double_int_to_shwi (doffset);
+		hoffset *= TREE_INT_CST_LOW (unit_size);
+		hoffset *= BITS_PER_UNIT;
+		bit_offset += hoffset;
 
 		/* An array ref with a constant index up in the structure
 		   hierarchy will constrain the size of any variable array ref