-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
* 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
* gcc.dg/torture/pr71908.c: New testcase.
--- /dev/null
+/* { 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++;
+ }
+}
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;
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))
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;
}
{
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 ();
}
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