diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-30 21:33:32 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-30 21:33:32 +0000 |
commit | 9ae13cc6f4a8b8e94ee762813b673191a94280b1 (patch) | |
tree | dd32c83a5ab688b1765c9c952a826e5e04b594de /gcc/expmed.c | |
parent | cb59f96973826a295b4f864bcda38b240ba33e44 (diff) | |
download | gcc-9ae13cc6f4a8b8e94ee762813b673191a94280b1.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54075 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 5a4c24ea68a..9419681dcae 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. |