Commit 005aa1b4 by Richard Guenther Committed by Richard Biener

re PR middle-end/52720 (internal compiler error: in try_move_mult_to_index)

2012-03-27  Richard Guenther  <rguenther@suse.de>

	PR middle-end/52720
	* fold-const.c (try_move_mult_to_index): Handle &x.array more
	explicitely.

	* gcc.dg/torture/pr52720.c: New testcase.

From-SVN: r185865
parent a59b038c
2012-03-27 Richard Guenther <rguenther@suse.de>
PR middle-end/52720
* fold-const.c (try_move_mult_to_index): Handle &x.array more
explicitely.
2012-03-27 Eric Botcazou <ebotcazou@adacore.com> 2012-03-27 Eric Botcazou <ebotcazou@adacore.com>
* expmed.c (store_bit_field): Assert that BITREGION_START is a multiple * expmed.c (store_bit_field): Assert that BITREGION_START is a multiple
......
...@@ -6826,64 +6826,81 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) ...@@ -6826,64 +6826,81 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
s = integer_one_node; s = integer_one_node;
} }
for (;; ref = TREE_OPERAND (ref, 0)) /* Handle &x.array the same as we would handle &x.array[0]. */
if (TREE_CODE (ref) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
{ {
if (TREE_CODE (ref) == ARRAY_REF) tree domain;
/* Remember if this was a multi-dimensional array. */
if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
mdim = true;
domain = TYPE_DOMAIN (TREE_TYPE (ref));
if (! domain)
goto cont;
itype = TREE_TYPE (domain);
step = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
if (TREE_CODE (step) != INTEGER_CST)
goto cont;
if (s)
{ {
tree domain; if (! tree_int_cst_equal (step, s))
goto cont;
}
else
{
/* Try if delta is a multiple of step. */
tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, op1, step);
if (! tmp)
goto cont;
delta = tmp;
}
/* Remember if this was a multi-dimensional array. */ /* Only fold here if we can verify we do not overflow one
if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF) dimension of a multi-dimensional array. */
mdim = true; if (mdim)
{
tree tmp;
domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0))); if (!TYPE_MIN_VALUE (domain)
if (! domain) || !TYPE_MAX_VALUE (domain)
continue; || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
itype = TREE_TYPE (domain); goto cont;
step = array_ref_element_size (ref); tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
if (TREE_CODE (step) != INTEGER_CST) fold_convert_loc (loc, itype,
continue; TYPE_MIN_VALUE (domain)),
fold_convert_loc (loc, itype, delta));
if (TREE_CODE (tmp) != INTEGER_CST
|| tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
goto cont;
}
if (s) /* We found a suitable component reference. */
{
if (! tree_int_cst_equal (step, s))
continue;
}
else
{
/* Try if delta is a multiple of step. */
tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, op1, step);
if (! tmp)
continue;
delta = tmp;
}
/* Only fold here if we can verify we do not overflow one pref = TREE_OPERAND (addr, 0);
dimension of a multi-dimensional array. */ ret = copy_node (pref);
if (mdim) SET_EXPR_LOCATION (ret, loc);
{
tree tmp;
if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST ret = build4_loc (loc, ARRAY_REF, TREE_TYPE (TREE_TYPE (ref)), ret,
|| !TYPE_MAX_VALUE (domain) fold_build2_loc
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST) (loc, PLUS_EXPR, itype,
continue; fold_convert_loc (loc, itype,
TYPE_MIN_VALUE
(TYPE_DOMAIN (TREE_TYPE (ref)))),
fold_convert_loc (loc, itype, delta)),
NULL_TREE, NULL_TREE);
return build_fold_addr_expr_loc (loc, ret);
}
tmp = fold_binary_loc (loc, PLUS_EXPR, itype, cont:
fold_convert_loc (loc, itype,
TREE_OPERAND (ref, 1)),
fold_convert_loc (loc, itype, delta));
if (!tmp
|| TREE_CODE (tmp) != INTEGER_CST
|| tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
continue;
}
break; for (;; ref = TREE_OPERAND (ref, 0))
} {
else if (TREE_CODE (ref) == COMPONENT_REF if (TREE_CODE (ref) == ARRAY_REF)
&& TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
{ {
tree domain; tree domain;
...@@ -6891,12 +6908,12 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) ...@@ -6891,12 +6908,12 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF) if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
mdim = true; mdim = true;
domain = TYPE_DOMAIN (TREE_TYPE (ref)); domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
if (! domain) if (! domain)
continue; continue;
itype = TREE_TYPE (domain); itype = TREE_TYPE (domain);
step = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref))); step = array_ref_element_size (ref);
if (TREE_CODE (step) != INTEGER_CST) if (TREE_CODE (step) != INTEGER_CST)
continue; continue;
...@@ -6920,16 +6937,17 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) ...@@ -6920,16 +6937,17 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
{ {
tree tmp; tree tmp;
if (!TYPE_MIN_VALUE (domain) if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
|| !TYPE_MAX_VALUE (domain) || !TYPE_MAX_VALUE (domain)
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST) || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
continue; continue;
tmp = fold_binary_loc (loc, PLUS_EXPR, itype, tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype, fold_convert_loc (loc, itype,
TYPE_MIN_VALUE (domain)), TREE_OPERAND (ref, 1)),
fold_convert_loc (loc, itype, delta)); fold_convert_loc (loc, itype, delta));
if (TREE_CODE (tmp) != INTEGER_CST if (!tmp
|| TREE_CODE (tmp) != INTEGER_CST
|| tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp)) || tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
continue; continue;
} }
...@@ -6958,29 +6976,11 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) ...@@ -6958,29 +6976,11 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
pos = TREE_OPERAND (pos, 0); pos = TREE_OPERAND (pos, 0);
} }
if (TREE_CODE (ref) == ARRAY_REF) TREE_OPERAND (pos, 1)
{ = fold_build2_loc (loc, PLUS_EXPR, itype,
TREE_OPERAND (pos, 1) fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)),
= fold_build2_loc (loc, PLUS_EXPR, itype, fold_convert_loc (loc, itype, delta));
fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)), return fold_build1_loc (loc, ADDR_EXPR, TREE_TYPE (addr), ret);
fold_convert_loc (loc, itype, delta));
return fold_build1_loc (loc, ADDR_EXPR, TREE_TYPE (addr), ret);
}
else if (TREE_CODE (ref) == COMPONENT_REF)
{
gcc_assert (ret == pos);
ret = build4_loc (loc, ARRAY_REF, TREE_TYPE (TREE_TYPE (ref)), ret,
fold_build2_loc
(loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype,
TYPE_MIN_VALUE
(TYPE_DOMAIN (TREE_TYPE (ref)))),
fold_convert_loc (loc, itype, delta)),
NULL_TREE, NULL_TREE);
return build_fold_addr_expr_loc (loc, ret);
}
else
gcc_unreachable ();
} }
......
2012-03-27 Richard Guenther <rguenther@suse.de>
PR middle-end/52720
* gcc.dg/torture/pr52720.c: New testcase.
2012-03-27 Eric Botcazou <ebotcazou@adacore.com> 2012-03-27 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack17.adb: New test. * gnat.dg/pack17.adb: New test.
......
/* { dg-do compile } */
/* { dg-options "-march=k8-sse3" { target x86_64-*-* } } */
struct alu_bank_swizzle {
int hw_gpr[3][4];
int hw_cfile_addr[4];
};
static void init_bank_swizzle(struct alu_bank_swizzle *bs)
{
int i, cycle, component;
for (cycle = 0; cycle < 3; cycle++)
for (component = 0; component < 4; component++)
bs->hw_gpr[cycle][component] = -1;
for (i = 0; i < 4; i++)
bs->hw_cfile_addr[i] = -1;
}
int check_and_set_bank_swizzle(int max_slots, int *slots)
{
struct alu_bank_swizzle bs;
int i;
for (i = 0; i < max_slots; i++)
{
init_bank_swizzle(&bs);
if (slots[i])
check_vector(&bs);
}
}
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