From: Richard Biener Date: Tue, 19 Jul 2016 10:19:46 +0000 (+0000) Subject: re PR tree-optimization/71901 (ice in find_or_generate_expression) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cef5388d95009657bd34179e4086da5074c67dcd;p=gcc.git re PR tree-optimization/71901 (ice in find_or_generate_expression) 2016-07-19 Richard Biener PR tree-optimization/71901 * tree-ssa-sccvn.h (struct vn_reference_op_struct): Add align member, group stuff with the bitfield. (vn_ref_op_align_unit): New inline. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): For ARRAY_REFs record element alignment and operand 3 unchanged. (ao_ref_init_from_vn_reference): Adjust. (valueize_refs_1): Likewise. * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise. * gcc.dg/torture/pr71901.c: New testcase. From-SVN: r238468 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c57adc9543..271706c0200 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,16 @@ -2016-07-18 Richard Biener +2016-07-19 Richard Biener + + PR tree-optimization/71901 + * tree-ssa-sccvn.h (struct vn_reference_op_struct): Add + align member, group stuff with the bitfield. + (vn_ref_op_align_unit): New inline. + * tree-ssa-sccvn.c (copy_reference_ops_from_ref): For ARRAY_REFs + record element alignment and operand 3 unchanged. + (ao_ref_init_from_vn_reference): Adjust. + (valueize_refs_1): Likewise. + * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise. + +2016-07-19 Richard Biener PR tree-optimization/71908 * tree-ssa-structalias.c (get_constraint_for_component_ref): Handle diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0a3fcb3764..457eb1094db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ -2016-07-18 Richard Biener +2016-07-19 Richard Biener + + PR tree-optimization/71901 + * gcc.dg/torture/pr71901.c: New testcase. + +2016-07-19 Richard Biener PR tree-optimization/71908 * gcc.dg/torture/pr71908.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr71901.c b/gcc/testsuite/gcc.dg/torture/pr71901.c new file mode 100644 index 00000000000..0be1d73b38c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71901.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +typedef struct { int _mp_size; } mpz_t[1]; +int a, b; +void fn1() +{ + mpz_t c[1][b]; + for (;;) { + int d = 0 >= 0 ? 0 == 0 ? c[0][0]->_mp_size ? -1 : 0 : 0 : 0, + e = 0 >= 0 ? 0 == 0 ? c[1][1]->_mp_size ? -1 : 0 : 0 : 0; + if (d != e) + a++; + } +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index c59aab8d0ff..a5f34862417 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -2570,15 +2570,14 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, here as the element alignment may be not visible. See PR43783. Simply drop the element size for constant sizes. */ - if (tree_int_cst_equal (genop3, TYPE_SIZE_UNIT (elmt_type))) + if (TREE_CODE (genop3) == INTEGER_CST + && TREE_CODE (TYPE_SIZE_UNIT (elmt_type)) == INTEGER_CST + && wi::eq_p (wi::to_offset (TYPE_SIZE_UNIT (elmt_type)), + (wi::to_offset (genop3) + * vn_ref_op_align_unit (currop)))) genop3 = NULL_TREE; else { - genop3 = size_binop (EXACT_DIV_EXPR, genop3, - size_int (TYPE_ALIGN_UNIT (elmt_type))); - /* We may have a useless conversion added by - array_ref_element_size via copy_reference_opts_from_ref. */ - STRIP_USELESS_TYPE_CONVERSION (genop3); genop3 = find_or_generate_expression (block, genop3, stmts); if (!genop3) return NULL_TREE; diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b1f10d50771..e6853420b6c 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -805,24 +805,30 @@ copy_reference_ops_from_ref (tree ref, vec *result) break; case ARRAY_RANGE_REF: case ARRAY_REF: - /* Record index as operand. */ - temp.op0 = TREE_OPERAND (ref, 1); - /* Always record lower bounds and element size. */ - temp.op1 = array_ref_low_bound (ref); - temp.op2 = array_ref_element_size (ref); - /* array_ref_element_size forces the result to sizetype - even if that is the same as bitsizetype. */ - STRIP_USELESS_TYPE_CONVERSION (temp.op2); - if (TREE_CODE (temp.op0) == INTEGER_CST - && TREE_CODE (temp.op1) == INTEGER_CST - && TREE_CODE (temp.op2) == INTEGER_CST) - { - offset_int off = ((wi::to_offset (temp.op0) - - wi::to_offset (temp.op1)) - * wi::to_offset (temp.op2)); - if (wi::fits_shwi_p (off)) - temp.off = off.to_shwi(); - } + { + tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0))); + /* Record index as operand. */ + temp.op0 = TREE_OPERAND (ref, 1); + /* Always record lower bounds and element size. */ + temp.op1 = array_ref_low_bound (ref); + /* But record element size in units of the type alignment. */ + temp.op2 = TREE_OPERAND (ref, 3); + temp.align = eltype->type_common.align; + if (! temp.op2) + temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype), + size_int (TYPE_ALIGN_UNIT (eltype))); + if (TREE_CODE (temp.op0) == INTEGER_CST + && TREE_CODE (temp.op1) == INTEGER_CST + && TREE_CODE (temp.op2) == INTEGER_CST) + { + offset_int off = ((wi::to_offset (temp.op0) + - wi::to_offset (temp.op1)) + * wi::to_offset (temp.op2) + * vn_ref_op_align_unit (&temp)); + if (wi::fits_shwi_p (off)) + temp.off = off.to_shwi(); + } + } break; case VAR_DECL: if (DECL_HARD_REGISTER (ref)) @@ -1021,7 +1027,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, offset_int woffset = wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1), TYPE_PRECISION (TREE_TYPE (op->op0))); - woffset *= wi::to_offset (op->op2); + woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op); woffset <<= LOG2_BITS_PER_UNIT; offset += woffset; } @@ -1471,7 +1477,8 @@ valueize_refs_1 (vec orig, bool *valueized_anything) { offset_int off = ((wi::to_offset (vro->op0) - wi::to_offset (vro->op1)) - * wi::to_offset (vro->op2)); + * wi::to_offset (vro->op2) + * vn_ref_op_align_unit (vro)); if (wi::fits_shwi_p (off)) vro->off = off.to_shwi (); } diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 92c255d93d2..d77dbaf42c0 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -81,22 +81,29 @@ typedef const struct vn_phi_s *const_vn_phi_t; typedef struct vn_reference_op_struct { ENUM_BITFIELD(tree_code) opcode : 16; - /* 1 for instrumented calls. */ - unsigned with_bounds : 1; /* Dependence info, used for [TARGET_]MEM_REF only. */ unsigned short clique; unsigned short base; + /* 1 for instrumented calls. */ + unsigned with_bounds : 1; + unsigned reverse : 1; + /* For storing TYPE_ALIGN for array ref element size computation. */ + unsigned align : 6; /* Constant offset this op adds or -1 if it is variable. */ HOST_WIDE_INT off; tree type; tree op0; tree op1; tree op2; - bool reverse; } vn_reference_op_s; typedef vn_reference_op_s *vn_reference_op_t; typedef const vn_reference_op_s *const_vn_reference_op_t; +inline unsigned +vn_ref_op_align_unit (vn_reference_op_t op) +{ + return op->align ? ((unsigned)1 << (op->align - 1)) / BITS_PER_UNIT : 0; +} /* A reference operation in the hashtable is representation as the vuse, representing the memory state at the time of