From 86f023fe9da95c7a8a292e91555fb7891d4971a5 Mon Sep 17 00:00:00 2001 From: rguenth Date: Sat, 14 May 2005 12:53:20 +0000 Subject: [PATCH] 2005-05-14 Richard Guenther * fold-const.c (div_if_zero_remainder): New function. (try_move_mult_to_index): Use it. * g++.dg/tree-ssa/tmmti-2.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99694 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 ++++ gcc/fold-const.c | 42 ++++++++++++++++++++++++++------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C | 22 +++++++++++++++++ 4 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91e3078..365ac33 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-05-14 Richard Guenther + + * fold-const.c (div_if_zero_remainder): New function. + (try_move_mult_to_index): Use it. + 2005-05-14 Kazu Hirata * tree-eh.c (leh_tf_state): Change the type of dest_array to diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a6ed0fa..b19dd85 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -831,6 +831,33 @@ div_and_round_double (enum tree_code code, int uns, add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem); return overflow; } + +/* If ARG2 divides ARG1 with zero remainder, carries out the division + of type CODE and returns the quotient. + Otherwise returns NULL_TREE. */ + +static tree +div_if_zero_remainder (enum tree_code code, tree arg1, tree arg2) +{ + unsigned HOST_WIDE_INT int1l, int2l; + HOST_WIDE_INT int1h, int2h; + unsigned HOST_WIDE_INT quol, reml; + HOST_WIDE_INT quoh, remh; + tree type = TREE_TYPE (arg1); + int uns = TYPE_UNSIGNED (type); + + int1l = TREE_INT_CST_LOW (arg1); + int1h = TREE_INT_CST_HIGH (arg1); + int2l = TREE_INT_CST_LOW (arg2); + int2h = TREE_INT_CST_HIGH (arg2); + + div_and_round_double (code, uns, int1l, int1h, int2l, int2h, + &quol, &quoh, &reml, &remh); + if (remh != 0 || reml != 0) + return NULL_TREE; + + return build_int_cst_wide (type, quol, quoh); +} /* Return true if built-in mathematical function specified by CODE preserves the sign of it argument, i.e. -f(x) == f(-x). */ @@ -6311,6 +6338,10 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1) { if (TREE_CODE (ref) == ARRAY_REF) { + itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0))); + if (! itype) + continue; + step = array_ref_element_size (ref); if (TREE_CODE (step) != INTEGER_CST) continue; @@ -6323,17 +6354,12 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1) else { /* Try if delta is a multiple of step. */ - tree mod = int_const_binop (TRUNC_MOD_EXPR, delta, step, 0); - if (!integer_zerop (mod)) + tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, delta, step); + if (! tmp) continue; - - delta = int_const_binop (EXACT_DIV_EXPR, delta, step, 0); + delta = tmp; } - itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0))); - if (! itype) - continue; - break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47c6771..e3897d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-05-14 Richard Guenther + + * g++.dg/tree-ssa/tmmti-2.C: New testcase. + 2005-05-13 Julian Brown * gcc.c-torture/execute/20041218-2.c: Add __attribute__((packed)). diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C new file mode 100644 index 0000000..9735adc --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options { -O -fdump-tree-optimized } } */ + +int a[4][8]; + +int foo(int i) +{ + return *(&a[0][0] + i*8); // a[i][0] +} + +struct Foo { double x, y; }; + +Foo b[4]; + +double bar(int i) +{ + return *(&b[0].x + i*2); // b[i].x +} + +/* { dg-final { scan-tree-dump "a\\\[.*i.*\\\]\\\[0\\\]" "optimized" } } */ +/* { dg-final { scan-tree-dump "b\\\[.*i.*\\\].x" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ -- 2.7.4