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] Avoid creating VLA involving casts in split_constant_offset (PR tree-optimization/33680)


Hi!

GCC ICEs on the attached testcase on e.g. x86_64 -O3.
We have:
  D.1561_21 = __builtin_alloca (D.1559_20);
  newcentroid.1_22 = (int[3][0:D.1554] *) D.1561_21;
  D.1563_24 = &(*newcentroid.1_22)[0]{lb: 0 sz: D.1555_11 * 4};
  D.1564_26 = D.1555_11 * 8;
  D.1565_27 = D.1563_24 + D.1564_26;
When split_constant_offset is called on D.1565_27, it creates
(int[0:D.1554] *) newcentroid.1_22 + (long unsigned int) dim_4(D) * 8
from this (and 0 as the constant offset).  The problem is that
D.1554 (max index) and D.1557 (TYPE_UNIT_SIZE) at this point are optimized
out and while e.g. all corresponding ARRAY_REF's 3rd arguments have been
updated to have valid element size, TYPE_SIZE_UNIT still refers to
something that no longer exist.

When vect_create_addr_base_for_vector_ref calls force_gimple_operand
on this, the (int[0:D.1554] *) newcentroid.1_22 cast is optimized
by gimplify_conversion into
&(*newcentroid.1_22)[0]
for which it needs to compute the element size, which it assumes is
D.1623_98 = D.1557 /[ex] 4;
&(*newcentroid.1_22)[0]{lb: 0 sz: D.1623_98 * 4};
but D.1557 isn't defined.

The patch below just punts instead of creating a conversion with variable
length type (20071108-1.c as well as the 2 vectorization testcases involving
VLAs already in the testsuite (vect3.f90 and pr19049.f90) can still be
vectorized just fine).
Alternatively, we could
1) export gimplify_conversion
2) run it on fold_convert (type, base) in the ADDR_EXPR case
then if something changed, find all ADDR_EXPRs and try to set their element
types from element types of the original exp contained ADDR_EXPRs, if it
doesn't manage to find all, just punt, otherwise return what we got.
But that's certainly more involved, so I'd prefer if the following would
be acceptable at least for 4.3.  We don't recurse further into base using
split_constant_offset, so punting in the VLA cases is probably not a big
deal anyway.

Regtested on x86_64-linux, ok for trunk?

2007-11-08  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/33680
	* tree-data-ref.c (split_constant_offset) <case ADDR_EXPR>: Punt
	if the added cast involves variable length types.

	* gcc.c-torture/compile/20071108-1.c: New test.

--- gcc/tree-data-ref.c.jj	2007-11-05 09:43:20.000000000 +0100
+++ gcc/tree-data-ref.c	2007-11-08 18:02:13.000000000 +0100
@@ -560,7 +560,27 @@ split_constant_offset (tree exp, tree *v
 				fold_convert (TREE_TYPE (base), poffset));
 	  }
 
-	*var = fold_convert (type, base);
+	var0 = fold_convert (type, base);
+
+	/* If variable length types are involved, punt, otherwise casts
+	   might be converted into ARRAY_REFs in gimplify_conversion.
+	   To compute that ARRAY_REF's element size TYPE_SIZE_UNIT, which
+	   possibly no longer appears in current GIMPLE, might resurface.
+	   This perhaps could run
+	   if (TREE_CODE (var0) == NOP_EXPR
+	       || TREE_CODE (var0) == CONVERT_EXPR)
+	     {
+	       gimplify_conversion (&var0);
+	       // Attempt to fill in any within var0 found ARRAY_REF's
+	       // element size from corresponding op embedded ARRAY_REF,
+	       // if unsuccessful, just punt.
+	     }  */
+	while (POINTER_TYPE_P (type))
+	  type = TREE_TYPE (type);
+	if (int_size_in_bytes (type) < 0)
+	  break;
+
+	*var = var0;
 	*off = off0;
 	return;
       }
--- gcc/testsuite/gcc.c-torture/compile/20071108-1.c.jj	2007-11-08 18:21:06.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/20071108-1.c	2007-11-08 18:19:55.000000000 +0100
@@ -0,0 +1,13 @@
+/* PR tree-optimization/33680 */
+
+int
+f (int dim, int *b, int *c)
+{
+  int newcentroid[3][dim];
+  int *a = newcentroid[2];
+  int i, dist = 0;
+  __builtin_memcpy (newcentroid, c, sizeof (newcentroid));
+  for (i = 0; i < dim; i++)
+    dist += (a[i] - b[i]) * (a[i] - b[i]);
+  return dist;
+}

	Jakub


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