Commit ebe4bf41 by Marek Polacek Committed by Jakub Jelinek

re PR c++/83659 (ICE on compilable C++ code: in tree_to_shwi, at tree.c:6821)

	PR c++/83659
	* fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro.
	Formatting fixes.  Verify first that tree_fits_poly_int64_p (op01).
	Sync some changes from cxx_fold_indirect_ref.

	* constexpr.c (cxx_fold_indirect_ref): Sync some changes from
	fold_indirect_ref_1, including poly_*int64.  Verify first that
	tree_fits_poly_int64_p (op01).  Formatting fixes.

	* g++.dg/torture/pr83659.C: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r257512
parent 58006663
2018-02-09 Marek Polacek <polacek@redhat.com>
Jakub Jelinek <jakub@redhat.com>
PR c++/83659
* fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro.
Formatting fixes. Verify first that tree_fits_poly_int64_p (op01).
Sync some changes from cxx_fold_indirect_ref.
2018-02-09 Alexandre Oliva <aoliva@redhat.com> 2018-02-09 Alexandre Oliva <aoliva@redhat.com>
* cfgexpand.c (expand_gimple_basic_block): Handle inline entry * cfgexpand.c (expand_gimple_basic_block): Handle inline entry
......
2018-02-09 Marek Polacek <polacek@redhat.com>
Jakub Jelinek <jakub@redhat.com>
PR c++/83659
* constexpr.c (cxx_fold_indirect_ref): Sync some changes from
fold_indirect_ref_1, including poly_*int64. Verify first that
tree_fits_poly_int64_p (op01). Formatting fixes.
2018-02-08 Paolo Carlini <paolo.carlini@oracle.com> 2018-02-08 Paolo Carlini <paolo.carlini@oracle.com>
* constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P. * constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P.
......
...@@ -3025,9 +3025,10 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, ...@@ -3025,9 +3025,10 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
static tree static tree
cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
{ {
tree sub, subtype; tree sub = op0;
tree subtype;
poly_uint64 const_op01;
sub = op0;
STRIP_NOPS (sub); STRIP_NOPS (sub);
subtype = TREE_TYPE (sub); subtype = TREE_TYPE (sub);
if (!POINTER_TYPE_P (subtype)) if (!POINTER_TYPE_P (subtype))
...@@ -3082,7 +3083,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) ...@@ -3082,7 +3083,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
{ {
tree part_width = TYPE_SIZE (type); tree part_width = TYPE_SIZE (type);
tree index = bitsize_int (0); tree index = bitsize_int (0);
return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width,
index);
} }
/* Also handle conversion to an empty base class, which /* Also handle conversion to an empty base class, which
is represented with a NOP_EXPR. */ is represented with a NOP_EXPR. */
...@@ -3107,7 +3109,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) ...@@ -3107,7 +3109,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
} }
} }
else if (TREE_CODE (sub) == POINTER_PLUS_EXPR else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
&& TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01))
{ {
tree op00 = TREE_OPERAND (sub, 0); tree op00 = TREE_OPERAND (sub, 0);
tree op01 = TREE_OPERAND (sub, 1); tree op01 = TREE_OPERAND (sub, 1);
...@@ -3121,29 +3123,37 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) ...@@ -3121,29 +3123,37 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
/* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
if (VECTOR_TYPE_P (op00type) if (VECTOR_TYPE_P (op00type)
&& (same_type_ignoring_top_level_qualifiers_p && same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (op00type)))) (type, TREE_TYPE (op00type))
/* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
but we want to treat offsets with MSB set as negative.
For the code below negative offsets are invalid and
TYPE_SIZE of the element is something unsigned, so
check whether op01 fits into poly_int64, which implies
it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and
then just use poly_uint64 because we want to treat the
value as unsigned. */
&& tree_fits_poly_int64_p (op01))
{ {
HOST_WIDE_INT offset = tree_to_shwi (op01);
tree part_width = TYPE_SIZE (type); tree part_width = TYPE_SIZE (type);
unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT; poly_uint64 max_offset
unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; = (tree_to_uhwi (part_width) / BITS_PER_UNIT
tree index = bitsize_int (indexi); * TYPE_VECTOR_SUBPARTS (op00type));
if (known_lt (const_op01, max_offset))
if (known_lt (offset / part_widthi, {
TYPE_VECTOR_SUBPARTS (op00type))) tree index = bitsize_int (const_op01 * BITS_PER_UNIT);
return fold_build3_loc (loc, return fold_build3_loc (loc,
BIT_FIELD_REF, type, op00, BIT_FIELD_REF, type, op00,
part_width, index); part_width, index);
}
} }
/* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
else if (TREE_CODE (op00type) == COMPLEX_TYPE else if (TREE_CODE (op00type) == COMPLEX_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (op00type)))) (type, TREE_TYPE (op00type))))
{ {
tree size = TYPE_SIZE_UNIT (type); if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
if (tree_int_cst_equal (size, op01)) const_op01))
return fold_build1_loc (loc, IMAGPART_EXPR, type, op00); return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
} }
/* ((foo *)&fooarray)[1] => fooarray[1] */ /* ((foo *)&fooarray)[1] => fooarray[1] */
...@@ -3198,7 +3208,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) ...@@ -3198,7 +3208,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
{ {
tree type_domain; tree type_domain;
tree min_val = size_zero_node; tree min_val = size_zero_node;
tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); tree newsub
= cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
if (newsub) if (newsub)
sub = newsub; sub = newsub;
else else
......
...@@ -14115,6 +14115,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) ...@@ -14115,6 +14115,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
{ {
tree op = TREE_OPERAND (sub, 0); tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op); tree optype = TREE_TYPE (op);
/* *&CONST_DECL -> to the value of the const decl. */ /* *&CONST_DECL -> to the value of the const decl. */
if (TREE_CODE (op) == CONST_DECL) if (TREE_CODE (op) == CONST_DECL)
return DECL_INITIAL (op); return DECL_INITIAL (op);
...@@ -14148,12 +14149,13 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) ...@@ -14148,12 +14149,13 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
&& type == TREE_TYPE (optype)) && type == TREE_TYPE (optype))
return fold_build1_loc (loc, REALPART_EXPR, type, op); return fold_build1_loc (loc, REALPART_EXPR, type, op);
/* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */ /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
else if (TREE_CODE (optype) == VECTOR_TYPE else if (VECTOR_TYPE_P (optype)
&& type == TREE_TYPE (optype)) && type == TREE_TYPE (optype))
{ {
tree part_width = TYPE_SIZE (type); tree part_width = TYPE_SIZE (type);
tree index = bitsize_int (0); tree index = bitsize_int (0);
return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width,
index);
} }
} }
...@@ -14171,8 +14173,17 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) ...@@ -14171,8 +14173,17 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
op00type = TREE_TYPE (op00); op00type = TREE_TYPE (op00);
/* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
if (TREE_CODE (op00type) == VECTOR_TYPE if (VECTOR_TYPE_P (op00type)
&& type == TREE_TYPE (op00type)) && type == TREE_TYPE (op00type)
/* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
but we want to treat offsets with MSB set as negative.
For the code below negative offsets are invalid and
TYPE_SIZE of the element is something unsigned, so
check whether op01 fits into poly_int64, which implies
it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and
then just use poly_uint64 because we want to treat the
value as unsigned. */
&& tree_fits_poly_int64_p (op01))
{ {
tree part_width = TYPE_SIZE (type); tree part_width = TYPE_SIZE (type);
poly_uint64 max_offset poly_uint64 max_offset
...@@ -14199,16 +14210,16 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) ...@@ -14199,16 +14210,16 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
&& type == TREE_TYPE (op00type)) && type == TREE_TYPE (op00type))
{ {
tree type_domain = TYPE_DOMAIN (op00type); tree type_domain = TYPE_DOMAIN (op00type);
tree min = size_zero_node; tree min_val = size_zero_node;
if (type_domain && TYPE_MIN_VALUE (type_domain)) if (type_domain && TYPE_MIN_VALUE (type_domain))
min = TYPE_MIN_VALUE (type_domain); min_val = TYPE_MIN_VALUE (type_domain);
offset_int off = wi::to_offset (op01); offset_int off = wi::to_offset (op01);
offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type)); offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type));
offset_int remainder; offset_int remainder;
off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder); off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder);
if (remainder == 0 && TREE_CODE (min) == INTEGER_CST) if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST)
{ {
off = off + wi::to_offset (min); off = off + wi::to_offset (min_val);
op01 = wide_int_to_tree (sizetype, off); op01 = wide_int_to_tree (sizetype, off);
return build4_loc (loc, ARRAY_REF, type, op00, op01, return build4_loc (loc, ARRAY_REF, type, op00, op01,
NULL_TREE, NULL_TREE); NULL_TREE, NULL_TREE);
......
2018-02-09 Marek Polacek <polacek@redhat.com>
Jakub Jelinek <jakub@redhat.com>
PR c++/83659
* g++.dg/torture/pr83659.C: New test.
2018-02-08 David Malcolm <dmalcolm@redhat.com> 2018-02-08 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/84136 PR tree-optimization/84136
......
// PR c++/83659
// { dg-do compile }
typedef int V __attribute__ ((__vector_size__ (16)));
V a;
V b[2];
int
foo ()
{
return reinterpret_cast <int *> (&a)[-1] += 1;
}
int
bar ()
{
return reinterpret_cast <int *> (&a[1])[-1];
}
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