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>
* 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)
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. */
if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
mdim = true;
/* Only fold here if we can verify we do not overflow one
dimension of a multi-dimensional array. */
if (mdim)
{
tree tmp;
domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
if (! domain)
continue;
itype = TREE_TYPE (domain);
if (!TYPE_MIN_VALUE (domain)
|| !TYPE_MAX_VALUE (domain)
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
goto cont;
step = array_ref_element_size (ref);
if (TREE_CODE (step) != INTEGER_CST)
continue;
tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype,
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)
{
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;
}
/* We found a suitable component reference. */
/* Only fold here if we can verify we do not overflow one
dimension of a multi-dimensional array. */
if (mdim)
{
tree tmp;
pref = TREE_OPERAND (addr, 0);
ret = copy_node (pref);
SET_EXPR_LOCATION (ret, loc);
if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
|| !TYPE_MAX_VALUE (domain)
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
continue;
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);
}
tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
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;
}
cont:
break;
}
else if (TREE_CODE (ref) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
for (;; ref = TREE_OPERAND (ref, 0))
{
if (TREE_CODE (ref) == ARRAY_REF)
{
tree domain;
......@@ -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)
mdim = true;
domain = TYPE_DOMAIN (TREE_TYPE (ref));
domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
if (! domain)
continue;
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)
continue;
......@@ -6920,16 +6937,17 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
{
tree tmp;
if (!TYPE_MIN_VALUE (domain)
if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
|| !TYPE_MAX_VALUE (domain)
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
continue;
tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype,
TYPE_MIN_VALUE (domain)),
TREE_OPERAND (ref, 1)),
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))
continue;
}
......@@ -6958,29 +6976,11 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
pos = TREE_OPERAND (pos, 0);
}
if (TREE_CODE (ref) == ARRAY_REF)
{
TREE_OPERAND (pos, 1)
= fold_build2_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)),
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 ();
TREE_OPERAND (pos, 1)
= fold_build2_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)),
fold_convert_loc (loc, itype, delta));
return fold_build1_loc (loc, ADDR_EXPR, TREE_TYPE (addr), ret);
}
......
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>
* 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