summaryrefslogtreecommitdiff
path: root/gcc/optabs-query.c
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2018-02-23 22:36:54 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2018-02-23 22:36:54 +0000
commit88a3ea34080ad3087a8191fbf479543153175d59 (patch)
tree34eaec34d3588e09f9a77abba776266f124dc823 /gcc/optabs-query.c
parent25e15aaed275cdfef34b3ee6eb3cb4b43a48d44f (diff)
parente65055a558093bd4fc0b1b0024b7814cc187b8e8 (diff)
downloadgccgo.tar.gz
Merge from trunk revision 257954.gccgo
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gccgo@257955 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs-query.c')
-rw-r--r--gcc/optabs-query.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index a8e10e6decc..5e5d620d437 100644
--- a/gcc/optabs-query.c
+++ b/gcc/optabs-query.c
@@ -473,9 +473,23 @@ find_widening_optab_handler_and_mode (optab op, machine_mode to_mode,
machine_mode from_mode,
machine_mode *found_mode)
{
- gcc_checking_assert (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode));
- gcc_checking_assert (from_mode < to_mode);
- FOR_EACH_MODE (from_mode, from_mode, to_mode)
+ machine_mode limit_mode = to_mode;
+ if (is_a <scalar_int_mode> (from_mode))
+ {
+ gcc_checking_assert (is_a <scalar_int_mode> (to_mode)
+ && known_lt (GET_MODE_PRECISION (from_mode),
+ GET_MODE_PRECISION (to_mode)));
+ /* The modes after FROM_MODE are all MODE_INT, so the only
+ MODE_PARTIAL_INT mode we consider is FROM_MODE itself.
+ If LIMIT_MODE is MODE_PARTIAL_INT, stop at the containing
+ MODE_INT. */
+ if (GET_MODE_CLASS (limit_mode) == MODE_PARTIAL_INT)
+ limit_mode = GET_MODE_WIDER_MODE (limit_mode).require ();
+ }
+ else
+ gcc_checking_assert (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
+ && from_mode < to_mode);
+ FOR_EACH_MODE (from_mode, from_mode, limit_mode)
{
enum insn_code handler = convert_optab_handler (op, to_mode, from_mode);