From 13e61f3e50b9662efbe350470ef5be477ceaac2d Mon Sep 17 00:00:00 2001 From: law Date: Tue, 20 Feb 2018 19:11:34 +0000 Subject: PR middle-end/84406 * optabs-query.c (find_widening_optab_handler_and_mode): If from_mode is a scalar_int_mode, assert that to_mode is a scalar_int_mode with greater precision. If to_mode is a MODE_PARTIAL_INT, stop the search at the associated MODE_INT. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257858 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/optabs-query.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'gcc/optabs-query.c') 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 (from_mode)) + { + gcc_checking_assert (is_a (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); -- cgit v1.2.1