Commit cef5388d by Richard Biener Committed by Richard Biener

re PR tree-optimization/71901 (ice in find_or_generate_expression)

2016-07-19  Richard Biener  <rguenther@suse.de>

	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
parent 9a4cb973
2016-07-18 Richard Biener <rguenther@suse.de> 2016-07-19 Richard Biener <rguenther@suse.de>
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 <rguenther@suse.de>
PR tree-optimization/71908 PR tree-optimization/71908
* tree-ssa-structalias.c (get_constraint_for_component_ref): Handle * tree-ssa-structalias.c (get_constraint_for_component_ref): Handle
......
2016-07-18 Richard Biener <rguenther@suse.de> 2016-07-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/71901
* gcc.dg/torture/pr71901.c: New testcase.
2016-07-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/71908 PR tree-optimization/71908
* gcc.dg/torture/pr71908.c: New testcase. * gcc.dg/torture/pr71908.c: New testcase.
......
/* { 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++;
}
}
...@@ -2570,15 +2570,14 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, ...@@ -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 here as the element alignment may be not visible. See
PR43783. Simply drop the element size for constant PR43783. Simply drop the element size for constant
sizes. */ 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; genop3 = NULL_TREE;
else 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); genop3 = find_or_generate_expression (block, genop3, stmts);
if (!genop3) if (!genop3)
return NULL_TREE; return NULL_TREE;
......
...@@ -805,24 +805,30 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) ...@@ -805,24 +805,30 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
break; break;
case ARRAY_RANGE_REF: case ARRAY_RANGE_REF:
case ARRAY_REF: case ARRAY_REF:
/* Record index as operand. */ {
temp.op0 = TREE_OPERAND (ref, 1); tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
/* Always record lower bounds and element size. */ /* Record index as operand. */
temp.op1 = array_ref_low_bound (ref); temp.op0 = TREE_OPERAND (ref, 1);
temp.op2 = array_ref_element_size (ref); /* Always record lower bounds and element size. */
/* array_ref_element_size forces the result to sizetype temp.op1 = array_ref_low_bound (ref);
even if that is the same as bitsizetype. */ /* But record element size in units of the type alignment. */
STRIP_USELESS_TYPE_CONVERSION (temp.op2); temp.op2 = TREE_OPERAND (ref, 3);
if (TREE_CODE (temp.op0) == INTEGER_CST temp.align = eltype->type_common.align;
&& TREE_CODE (temp.op1) == INTEGER_CST if (! temp.op2)
&& TREE_CODE (temp.op2) == INTEGER_CST) temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
{ size_int (TYPE_ALIGN_UNIT (eltype)));
offset_int off = ((wi::to_offset (temp.op0) if (TREE_CODE (temp.op0) == INTEGER_CST
- wi::to_offset (temp.op1)) && TREE_CODE (temp.op1) == INTEGER_CST
* wi::to_offset (temp.op2)); && TREE_CODE (temp.op2) == INTEGER_CST)
if (wi::fits_shwi_p (off)) {
temp.off = off.to_shwi(); 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; break;
case VAR_DECL: case VAR_DECL:
if (DECL_HARD_REGISTER (ref)) if (DECL_HARD_REGISTER (ref))
...@@ -1021,7 +1027,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1021,7 +1027,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
offset_int woffset offset_int woffset
= wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1), = wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1),
TYPE_PRECISION (TREE_TYPE (op->op0))); 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; woffset <<= LOG2_BITS_PER_UNIT;
offset += woffset; offset += woffset;
} }
...@@ -1471,7 +1477,8 @@ valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything) ...@@ -1471,7 +1477,8 @@ valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything)
{ {
offset_int off = ((wi::to_offset (vro->op0) offset_int off = ((wi::to_offset (vro->op0)
- wi::to_offset (vro->op1)) - 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)) if (wi::fits_shwi_p (off))
vro->off = off.to_shwi (); vro->off = off.to_shwi ();
} }
......
...@@ -81,22 +81,29 @@ typedef const struct vn_phi_s *const_vn_phi_t; ...@@ -81,22 +81,29 @@ typedef const struct vn_phi_s *const_vn_phi_t;
typedef struct vn_reference_op_struct typedef struct vn_reference_op_struct
{ {
ENUM_BITFIELD(tree_code) opcode : 16; ENUM_BITFIELD(tree_code) opcode : 16;
/* 1 for instrumented calls. */
unsigned with_bounds : 1;
/* Dependence info, used for [TARGET_]MEM_REF only. */ /* Dependence info, used for [TARGET_]MEM_REF only. */
unsigned short clique; unsigned short clique;
unsigned short base; 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. */ /* Constant offset this op adds or -1 if it is variable. */
HOST_WIDE_INT off; HOST_WIDE_INT off;
tree type; tree type;
tree op0; tree op0;
tree op1; tree op1;
tree op2; tree op2;
bool reverse;
} vn_reference_op_s; } vn_reference_op_s;
typedef vn_reference_op_s *vn_reference_op_t; typedef vn_reference_op_s *vn_reference_op_t;
typedef const vn_reference_op_s *const_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 /* A reference operation in the hashtable is representation as
the vuse, representing the memory state at the time of the vuse, representing the memory state at the time of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment