summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-03-27 12:50:29 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-03-27 12:50:29 +0000
commit005aa1b4fba54dfc9f8a532ee82a8ac5f7257b9f (patch)
tree8dd9d34e7c52146f545feb63ff4f16d11ba4d954 /gcc
parenta59b038cc8edf2e34d5c9544a8805bf9b3450709 (diff)
downloadgcc-005aa1b4fba54dfc9f8a532ee82a8ac5f7257b9f.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c152
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr52720.c28
4 files changed, 115 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bf370df44ec..e9acac3165b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1e91bac9970..df0c05c6e02 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 63de5d4e7ba..408184a26b8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/torture/pr52720.c b/gcc/testsuite/gcc.dg/torture/pr52720.c
new file mode 100644
index 00000000000..528aa161b13
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr52720.c
@@ -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);
+ }
+}
+