diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1992-05-25 06:28:09 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1992-05-25 06:28:09 -0400 |
commit | 3b998c11fb4b43c4547bb7aa3f714ce89fe0c922 (patch) | |
tree | 20a3a7c01f2515050b05f012690cb27e34ff094a /gcc/fold-const.c | |
parent | 1ce634c39faa75856b8a0468b6f39943a6c8e687 (diff) | |
download | gcc-3b998c11fb4b43c4547bb7aa3f714ce89fe0c922.zip gcc-3b998c11fb4b43c4547bb7aa3f714ce89fe0c922.tar.gz gcc-3b998c11fb4b43c4547bb7aa3f714ce89fe0c922.tar.bz2 |
*** empty log message ***
From-SVN: r1079
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index fcabebd..ba44e20 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3140,6 +3140,49 @@ fold (expr) return non_lvalue (convert (type, arg0)); if (integer_zerop (arg1)) return t; + + /* If we have ((a * C1) / C2) and C1 % C2 == 0, we can replace this with + (a * (C1/C2). Also look for when we have a SAVE_EXPR in + between. */ + if (TREE_CODE (arg1) == INTEGER_CST + && TREE_INT_CST_LOW (arg1) > 0 && TREE_INT_CST_HIGH (arg1) == 0 + && TREE_CODE (arg0) == MULT_EXPR + && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST + && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) > 0 + && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0 + && 0 == (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) + % TREE_INT_CST_LOW (arg1))) + { + tree new_op + = build_int_2 (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) + / TREE_INT_CST_LOW (arg1)); + + TREE_TYPE (new_op) = type; + return build (MULT_EXPR, type, TREE_OPERAND (arg0, 0), new_op); + } + + else if (TREE_CODE (arg1) == INTEGER_CST + && TREE_INT_CST_LOW (arg1) > 0 && TREE_INT_CST_HIGH (arg1) == 0 + && TREE_CODE (arg0) == SAVE_EXPR + && TREE_CODE (TREE_OPERAND (arg0, 0)) == MULT_EXPR + && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + == INTEGER_CST) + && (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + > 0) + && (TREE_INT_CST_HIGH (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + == 0) + && (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + % TREE_INT_CST_LOW (arg1)) == 0) + { + tree new_op + = build_int_2 (TREE_INT_CST_LOW (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + / TREE_INT_CST_LOW (arg1)); + + TREE_TYPE (new_op) = type; + return build (MULT_EXPR, type, + TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), new_op); + } + #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) #ifndef REAL_INFINITY if (TREE_CODE (arg1) == REAL_CST |