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