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
This commit is contained in:
parent
a59b038cc8
commit
005aa1b4fb
4 changed files with 116 additions and 77 deletions
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
154
gcc/fold-const.c
154
gcc/fold-const.c
|
@ -6826,6 +6826,78 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
|
|||
s = integer_one_node;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Only fold here if we can verify we do not overflow one
|
||||
dimension of a multi-dimensional array. */
|
||||
if (mdim)
|
||||
{
|
||||
tree tmp;
|
||||
|
||||
if (!TYPE_MIN_VALUE (domain)
|
||||
|| !TYPE_MAX_VALUE (domain)
|
||||
|| TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
|
||||
goto cont;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* We found a suitable component reference. */
|
||||
|
||||
pref = TREE_OPERAND (addr, 0);
|
||||
ret = copy_node (pref);
|
||||
SET_EXPR_LOCATION (ret, loc);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
cont:
|
||||
|
||||
for (;; ref = TREE_OPERAND (ref, 0))
|
||||
{
|
||||
if (TREE_CODE (ref) == ARRAY_REF)
|
||||
|
@ -6880,60 +6952,6 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
|
|||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (TREE_CODE (ref) == COMPONENT_REF
|
||||
&& TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
itype = TREE_TYPE (domain);
|
||||
|
||||
step = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
|
||||
if (TREE_CODE (step) != INTEGER_CST)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Only fold here if we can verify we do not overflow one
|
||||
dimension of a multi-dimensional array. */
|
||||
if (mdim)
|
||||
{
|
||||
tree tmp;
|
||||
|
||||
if (!TYPE_MIN_VALUE (domain)
|
||||
|| !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)),
|
||||
fold_convert_loc (loc, itype, delta));
|
||||
if (TREE_CODE (tmp) != INTEGER_CST
|
||||
|| tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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.
|
||||
|
|
28
gcc/testsuite/gcc.dg/torture/pr52720.c
Normal file
28
gcc/testsuite/gcc.dg/torture/pr52720.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* { 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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue