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]

[graphite] Fix PR39335: problem in canonicalize_loop_ivs


Hi,

As explained in the PR this bug is due to the IV canonicalization that
may introduce loop exit conditions that contain operands with types of
different precision.  The attached patch fixes the problem.  The patch
passed regstrap on amd64-linux.  Okay for trunk?

Thanks,
Sebastian Pop
--
AMD - GNU Tools
2009-03-02  Sebastian Pop  <sebastian.pop@amd.com>

	PR middle-end/39335
	* tree-parloops.c (canonicalize_loop_ivs): Call fold_convert
	when the type precision of the induction variable should be
	larger than the type precision of nit.
	(gen_parallel_loop): Update use of canonicalize_loop_ivs.
	* graphite.c (graphite_loop_normal_form): Same.
	* tree-flow.h (canonicalize_loop_ivs): Update declaration.

	* testsuite/gcc.dg/graphite/pr39335_1.c: New.
	* testsuite/gcc.dg/graphite/pr39335.c: New.

Index: testsuite/gcc.dg/graphite/pr39335_1.c
===================================================================
--- testsuite/gcc.dg/graphite/pr39335_1.c	(revision 0)
+++ testsuite/gcc.dg/graphite/pr39335_1.c	(revision 0)
@@ -0,0 +1,9 @@
+/* { dg-options "-O2 -floop-interchange" } */
+
+void crash_me(int num1, int num2, char * in, char * out)
+{
+ int i, j;
+ for (j = 0; j < num1; j++)
+   for (i = 0; i < num2; i++)
+     *out++ = *in++;
+}
Index: testsuite/gcc.dg/graphite/pr39335.c
===================================================================
--- testsuite/gcc.dg/graphite/pr39335.c	(revision 0)
+++ testsuite/gcc.dg/graphite/pr39335.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -floop-interchange" } */
+
+typedef unsigned char byte;
+typedef struct gx_device_s gx_device;
+typedef struct gs_devn_params_s gs_devn_params;
+typedef struct gs_devn_params_s {
+   struct compressed_color_list_s * compressed_color_list;
+} gs_devn_params_t;
+int devn_unpack_row(gx_device * dev, int num_comp,
+                   gs_devn_params * pdevn_params, int width, byte * in,
+                   byte * out)
+{
+ int i, comp_num, pixel_num;
+ if (pdevn_params->compressed_color_list == ((void *)0))
+   {
+     for (pixel_num = 0; pixel_num < width; pixel_num++)
+       for (i = 0; i < num_comp; i++)
+         *out++ = *in++;
+   }
+}
Index: tree-parloops.c
===================================================================
--- tree-parloops.c	(revision 144544)
+++ tree-parloops.c	(working copy)
@@ -1328,9 +1328,10 @@ create_loop_fn (void)
    variable that was created.  */
 
 tree
-canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
+canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit)
 {
-  unsigned precision = TYPE_PRECISION (TREE_TYPE (nit));
+  unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit));
+  unsigned original_precision = precision;
   tree res, type, var_before, val, atype, mtype;
   gimple_stmt_iterator gsi, psi;
   gimple phi, stmt;
@@ -1338,6 +1339,7 @@ canonicalize_loop_ivs (struct loop *loop
   affine_iv iv;
   edge exit = single_dom_exit (loop);
   struct reduction_info *red;
+  gimple_seq stmts;
 
   for (psi = gsi_start_phis (loop->header);
        !gsi_end_p (psi); gsi_next (&psi))
@@ -1351,6 +1353,14 @@ canonicalize_loop_ivs (struct loop *loop
 
   type = lang_hooks.types.type_for_size (precision, 1);
 
+  if (original_precision != precision)
+    {
+      *nit = fold_convert (type, *nit);
+      *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE);
+      if (stmts)
+	gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+    }
+
   gsi = gsi_last_bb (loop->latch);
   create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE,
 	     loop, &gsi, true, &var_before, NULL);
@@ -1410,7 +1420,7 @@ canonicalize_loop_ivs (struct loop *loop
     }
   gimple_cond_set_code (stmt, LT_EXPR);
   gimple_cond_set_lhs (stmt, var_before);
-  gimple_cond_set_rhs (stmt, nit);
+  gimple_cond_set_rhs (stmt, *nit);
   update_stmt (stmt);
 
   return var_before;
@@ -1760,7 +1770,7 @@ gen_parallel_loop (struct loop *loop, ht
   free_original_copy_tables ();
 
   /* Base all the induction variables in LOOP on a single control one.  */
-  canonicalize_loop_ivs (loop, reduction_list, nit);
+  canonicalize_loop_ivs (loop, reduction_list, &nit);
 
   /* Ensure that the exit condition is the first statement in the loop.  */
   transform_to_exit_first_loop (loop, reduction_list, nit);
Index: graphite.c
===================================================================
--- graphite.c	(revision 144544)
+++ graphite.c	(working copy)
@@ -2395,7 +2395,7 @@ graphite_loop_normal_form (loop_p loop)
   if (nb_reductions_in_loop (loop) > 0)
     return NULL_TREE;
 
-  return canonicalize_loop_ivs (loop, NULL, nit);
+  return canonicalize_loop_ivs (loop, NULL, &nit);
 }
 
 /* Record LOOP as occuring in SCOP.  Returns true when the operation
Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 144544)
+++ tree-flow.h	(working copy)
@@ -991,7 +991,7 @@ unsigned int tree_ssa_prefetch_arrays (v
 unsigned int remove_empty_loops (void);
 void tree_ssa_iv_optimize (void);
 unsigned tree_predictive_commoning (void);
-tree canonicalize_loop_ivs (struct loop *, htab_t, tree);
+tree canonicalize_loop_ivs (struct loop *, htab_t, tree *);
 bool parallelize_loops (void);
 
 bool loop_only_exit_p (const struct loop *, const_edge);

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