Hi!

The attached testcase ICEs, because gimple_regimplify_operands ignores
lb: and sz: operands on ARRAY*_REF (and last operand on COMPONENT_REF),
assuming that if it is non-NULL, it is valid GIMPLE and doesn't need
further processing.  That is true for gimplification, as FEs/generic
leave those operands NULL and only gimplification sets them, but when
we need to regimplify them, e.g. for OpenMP (or perhaps inlining etc.),
it wouldn't do anything.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk and 4.6 branch.

2011-07-07  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/49640
        * gimplify.c (gimplify_compound_lval): For last 2 ARRAY_*REF
        operands and last COMPONENT_REF operand call gimplify_expr on it
        if non-NULL.

        * gcc.dg/gomp/pr49640.c: New test.

--- gcc/gimplify.c.jj   2011-06-17 11:02:19.000000000 +0200
+++ gcc/gimplify.c      2011-07-07 10:56:30.000000000 +0200
@@ -2010,8 +2010,14 @@ gimplify_compound_lval (tree *expr_p, gi
                  ret = MIN (ret, tret);
                }
            }
+         else
+           {
+             tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+                                   is_gimple_reg, fb_rvalue);
+             ret = MIN (ret, tret);
+           }
 
-         if (!TREE_OPERAND (t, 3))
+         if (TREE_OPERAND (t, 3) == NULL_TREE)
            {
              tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
              tree elmt_size = unshare_expr (array_ref_element_size (t));
@@ -2031,11 +2037,17 @@ gimplify_compound_lval (tree *expr_p, gi
                  ret = MIN (ret, tret);
                }
            }
+         else
+           {
+             tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
+                                   is_gimple_reg, fb_rvalue);
+             ret = MIN (ret, tret);
+           }
        }
       else if (TREE_CODE (t) == COMPONENT_REF)
        {
          /* Set the field offset into T and gimplify it.  */
-         if (!TREE_OPERAND (t, 2))
+         if (TREE_OPERAND (t, 2) == NULL_TREE)
            {
              tree offset = unshare_expr (component_ref_field_offset (t));
              tree field = TREE_OPERAND (t, 1);
@@ -2054,6 +2066,12 @@ gimplify_compound_lval (tree *expr_p, gi
                  ret = MIN (ret, tret);
                }
            }
+         else
+           {
+             tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+                                   is_gimple_reg, fb_rvalue);
+             ret = MIN (ret, tret);
+           }
        }
     }
 
--- gcc/testsuite/gcc.dg/gomp/pr49640.c.jj      2011-07-07 11:07:08.000000000 
+0200
+++ gcc/testsuite/gcc.dg/gomp/pr49640.c 2011-07-07 11:05:19.000000000 +0200
@@ -0,0 +1,29 @@
+/* PR middle-end/49640 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=gnu99 -fopenmp" } */
+
+void
+foo (int N, int M, int K, int P, int Q, int R, int i, int j, int k,
+     unsigned char x[P][Q][R], int y[N][M][K])
+{
+  int ii, jj, kk;
+
+#pragma omp parallel for private(ii,jj,kk)
+  for (ii = 0; ii < P; ++ii)
+    for (jj = 0; jj < Q; ++jj)
+      for (kk = 0; kk < R; ++kk)
+       y[i + ii][j + jj][k + kk] = x[ii][jj][kk];
+}
+
+void
+bar (int N, int M, int K, int P, int Q, int R, int i, int j, int k,
+     unsigned char x[P][Q][R], float y[N][M][K], float factor, float zero)
+{
+  int ii, jj, kk;
+
+#pragma omp parallel for private(ii,jj,kk)
+  for (ii = 0; ii < P; ++ii)
+    for (jj = 0; jj < Q; ++jj)
+      for (kk = 0; kk < R; ++kk)
+       y[i + ii][j + jj][k + kk] = factor * x[ii][jj][kk] + zero;
+}

        Jakub

Reply via email to