From d6366157deac0b526ce7ecfd2821745eecce06c8 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Mon, 8 Apr 2019 11:52:18 +0000 Subject: [PATCH] re PR middle-end/89725 (ICE in get_fnname_from_decl, at varasm.c:1723) 2019-04-01 Bin Cheng PR tree-optimization/89725 * tree-chrec.c (chrec_contains_symbols): New parameter. Handle outer loop's chrec as invariant symbol. * tree-chrec.h (chrec_contains_symbols): New parameter. * tree-data-ref.c (analyze_miv_subscript): Pass new argument. (build_classic_dist_vector_1, add_other_self_distances): Bypass access function of loops not in DDR's loop_nest. * tree-data-ref.h (index_in_loop_nest): Add unreachable check. * gcc.dg/tree-ssa/pr89725.c: New test. From-SVN: r270203 --- gcc/ChangeLog | 11 ++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/pr89725.c | 28 +++++++++++++++++++++++++ gcc/tree-chrec.c | 22 ++++++++++++++----- gcc/tree-chrec.h | 2 +- gcc/tree-data-ref.c | 25 ++++++++++++++++++++-- gcc/tree-data-ref.h | 7 +++---- 7 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr89725.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73d8a325a14..a4c5520ecc1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-04-01 Bin Cheng + + PR tree-optimization/89725 + * tree-chrec.c (chrec_contains_symbols): New parameter. Handle outer + loop's chrec as invariant symbol. + * tree-chrec.h (chrec_contains_symbols): New parameter. + * tree-data-ref.c (analyze_miv_subscript): Pass new argument. + (build_classic_dist_vector_1, add_other_self_distances): Bypass access + function of loops not in DDR's loop_nest. + * tree-data-ref.h (index_in_loop_nest): Add unreachable check. + 2019-04-08 Chenghua Xu PR target/89623 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94bc0f1104c..c8f538b26e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-01 Bin Cheng + + PR tree-optimization/89725 + * gcc.dg/tree-ssa/pr89725.c: New test. + 2019-04-08 Martin Liska * gcc.target/riscv/arch-1.c: Fix expected scanned pattern. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89725.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89725.c new file mode 100644 index 00000000000..ad826d90b86 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89725.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -floop-interchange -fno-tree-dce" } */ +int abs (int); +int find_sad_16x16(int *intra_mode) +{ + int current_intra_sad_2,best_intra_sad2; + int M1[16][16],M0[4][4][4][4],M3[4],M4[4][4]; + int i,j,k; + int ii,jj; + int up_avail, left_avail, left_up_avail; + for (i=0;i<17;i++) + if (left_up_avail) + { + for (jj=0;jj<4;jj++) + for (ii=0;ii<4;ii++) + for (j=0;j<4;j++) + for (i=0;i<4;i++) + { + M0[i][ii][2][jj]=M3[0]-M3[1]; + M0[i][ii][1][jj]=M3[2]+M3[3]; + current_intra_sad_2 += abs(M0[i][ii][j][jj]); + } + + if(current_intra_sad_2 < best_intra_sad2) + best_intra_sad2=current_intra_sad_2; + } + return 0; +} diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 3987041ac19..8b5371a29a7 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -932,10 +932,12 @@ is_multivariate_chrec (const_tree chrec) return false; } -/* Determines whether the chrec contains symbolic names or not. */ +/* Determines whether the chrec contains symbolic names or not. If LOOP isn't + NULL, we also consider chrec wrto outer loops of LOOP as symbol. */ static bool -chrec_contains_symbols (const_tree chrec, hash_set &visited) +chrec_contains_symbols (const_tree chrec, hash_set &visited, + struct loop *loop) { int i, n; @@ -952,18 +954,28 @@ chrec_contains_symbols (const_tree chrec, hash_set &visited) || TREE_CODE (chrec) == FIELD_DECL) return true; + if (loop != NULL + && TREE_CODE (chrec) == POLYNOMIAL_CHREC + && flow_loop_nested_p (get_chrec_loop (chrec), loop)) + return true; + n = TREE_OPERAND_LENGTH (chrec); for (i = 0; i < n; i++) - if (chrec_contains_symbols (TREE_OPERAND (chrec, i), visited)) + if (chrec_contains_symbols (TREE_OPERAND (chrec, i), visited, loop)) return true; return false; } +/* Return true if CHREC contains any symbols. If LOOP is not NULL, check if + CHREC contains any chrec which is invariant wrto the loop (nest), in other + words, chrec defined by outer loops of loop, so from LOOP's point of view, + the chrec is considered as a SYMBOL. */ + bool -chrec_contains_symbols (const_tree chrec) +chrec_contains_symbols (const_tree chrec, struct loop* loop) { hash_set visited; - return chrec_contains_symbols (chrec, visited); + return chrec_contains_symbols (chrec, visited, loop); } /* Determines whether the chrec contains undetermined coefficients. */ diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h index 6c793223639..258b5d53f8b 100644 --- a/gcc/tree-chrec.h +++ b/gcc/tree-chrec.h @@ -80,7 +80,7 @@ extern bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple *, /* Observers. */ extern bool eq_evolutions_p (const_tree, const_tree); extern bool is_multivariate_chrec (const_tree); -extern bool chrec_contains_symbols (const_tree); +extern bool chrec_contains_symbols (const_tree, struct loop * = NULL); extern bool chrec_contains_symbols_defined_in_loop (const_tree, unsigned); extern bool chrec_contains_undetermined (const_tree); extern bool tree_contains_chrecs (const_tree, int *); diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index e536b463e96..51da181c1f1 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -4060,9 +4060,9 @@ analyze_miv_subscript (tree chrec_a, } else if (evolution_function_is_affine_in_loop (chrec_a, loop_nest->num) - && !chrec_contains_symbols (chrec_a) + && !chrec_contains_symbols (chrec_a, loop_nest) && evolution_function_is_affine_in_loop (chrec_b, loop_nest->num) - && !chrec_contains_symbols (chrec_b)) + && !chrec_contains_symbols (chrec_b, loop_nest)) { /* testsuite/.../ssa-chrec-35.c {0, +, 1}_2 vs. {0, +, 1}_3 @@ -4272,6 +4272,7 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr, { unsigned i; lambda_vector init_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); + struct loop *loop = DDR_LOOP_NEST (ddr)[0]; for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++) { @@ -4302,6 +4303,15 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr, return false; } + /* When data references are collected in a loop while data + dependences are analyzed in loop nest nested in the loop, we + would have more number of access functions than number of + loops. Skip access functions of loops not in the loop nest. + + See PR89725 for more information. */ + if (flow_loop_nested_p (get_loop (cfun, var_a), loop)) + continue; + dist = int_cst_value (SUB_DISTANCE (subscript)); index = index_in_loop_nest (var_a, DDR_LOOP_NEST (ddr)); *index_carry = MIN (index, *index_carry); @@ -4413,6 +4423,7 @@ add_other_self_distances (struct data_dependence_relation *ddr) unsigned i; int index_carry = DDR_NB_LOOPS (ddr); subscript *sub; + struct loop *loop = DDR_LOOP_NEST (ddr)[0]; FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub) { @@ -4442,6 +4453,16 @@ add_other_self_distances (struct data_dependence_relation *ddr) return; } + /* When data references are collected in a loop while data + dependences are analyzed in loop nest nested in the loop, we + would have more number of access functions than number of + loops. Skip access functions of loops not in the loop nest. + + See PR89725 for more information. */ + if (flow_loop_nested_p (get_loop (cfun, CHREC_VARIABLE (access_fun)), + loop)) + continue; + index_carry = MIN (index_carry, index_in_loop_nest (CHREC_VARIABLE (access_fun), DDR_LOOP_NEST (ddr))); diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 11aa806a64d..2a5082db398 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -580,12 +580,11 @@ index_in_loop_nest (int var, vec loop_nest) struct loop *loopi; int var_index; - for (var_index = 0; loop_nest.iterate (var_index, &loopi); - var_index++) + for (var_index = 0; loop_nest.iterate (var_index, &loopi); var_index++) if (loopi->num == var) - break; + return var_index; - return var_index; + gcc_unreachable (); } /* Returns true when the data reference DR the form "A[i] = ..." -- 2.30.2