aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@multimania.com>2002-05-30 21:33:32 +0000
committerRichard Henderson <rth@gcc.gnu.org>2002-05-30 14:33:32 -0700
commitce60bf25b22ac87577c2e4efdc5a1bdacaa05151 (patch)
treedd32c83a5ab688b1765c9c952a826e5e04b594de /gcc/expmed.c
parentd18b1ed89ece9698c8e3d0a90534bbf9fe103951 (diff)
downloadgcc-ce60bf25b22ac87577c2e4efdc5a1bdacaa05151.zip
gcc-ce60bf25b22ac87577c2e4efdc5a1bdacaa05151.tar.gz
gcc-ce60bf25b22ac87577c2e4efdc5a1bdacaa05151.tar.bz2
expmed.c (const_mult_add_overflow_p): New.
* expmed.c (const_mult_add_overflow_p): New. * expr.h: Declare it. * loop.c (maybe_eliminate_biv_1) [COMPARE]: Use it. Don't eliminate the biv if the giv has a constant multiplier and the rhs argument of the comparison does satisfy the predicate. Use expand_mult_add to compute the replacement constant. From-SVN: r54075
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 5a4c24e..9419681 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -4156,6 +4156,44 @@ make_tree (type, x)
}
}
+/* Check whether the multiplication X * MULT + ADD overflows.
+ X, MULT and ADD must be CONST_*.
+ MODE is the machine mode for the computation.
+ X and MULT must have mode MODE. ADD may have a different mode.
+ So can X (defaults to same as MODE).
+ UNSIGNEDP is non-zero to do unsigned multiplication. */
+
+bool
+const_mult_add_overflow_p (x, mult, add, mode, unsignedp)
+ rtx x, mult, add;
+ enum machine_mode mode;
+ int unsignedp;
+{
+ tree type, mult_type, add_type, result;
+
+ type = (*lang_hooks.types.type_for_mode) (mode, unsignedp);
+
+ /* In order to get a proper overflow indication from an unsigned
+ type, we have to pretend that it's a sizetype. */
+ mult_type = type;
+ if (unsignedp)
+ {
+ mult_type = copy_node (type);
+ TYPE_IS_SIZETYPE (mult_type) = 1;
+ }
+
+ add_type = (GET_MODE (add) == VOIDmode ? mult_type
+ : (*lang_hooks.types.type_for_mode) (GET_MODE (add), unsignedp));
+
+ result = fold (build (PLUS_EXPR, mult_type,
+ fold (build (MULT_EXPR, mult_type,
+ make_tree (mult_type, x),
+ make_tree (mult_type, mult))),
+ make_tree (add_type, add)));
+
+ return TREE_CONSTANT_OVERFLOW (result);
+}
+
/* Return an rtx representing the value of X * MULT + ADD.
TARGET is a suggestion for where to store the result (an rtx).
MODE is the machine mode for the computation.