From: rguenth Date: Tue, 27 Mar 2012 12:50:29 +0000 (+0000) Subject: 2012-03-27 Richard Guenther X-Git-Tag: upstream/4.9.2~13563 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=902123ad9f063e8daf780139598ae669d039e1fc;p=platform%2Fupstream%2Flinaro-gcc.git 2012-03-27 Richard Guenther PR middle-end/52720 * fold-const.c (try_move_mult_to_index): Handle &x.array more explicitely. * gcc.dg/torture/pr52720.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185865 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf370df..e9acac3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-03-27 Richard Guenther + + PR middle-end/52720 + * fold-const.c (try_move_mult_to_index): Handle &x.array more + explicitely. + 2012-03-27 Eric Botcazou * 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 1e91bac..df0c05c 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 63de5d4..408184a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-03-27 Richard Guenther + + PR middle-end/52720 + * gcc.dg/torture/pr52720.c: New testcase. + 2012-03-27 Eric Botcazou * 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 0000000..528aa16 --- /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); + } +} +