aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-02-20 19:11:34 +0000
committerJeff Law <law@gcc.gnu.org>2018-02-20 12:11:34 -0700
commit2fad0cf503f695d737bcabb2dad5c4d10852cca6 (patch)
treefa807849e74c330eb4c83653fede33ed0db07e80 /gcc
parente506dc87a0d7d0f55a6b727885e170dcc2948014 (diff)
downloadgcc-2fad0cf503f695d737bcabb2dad5c4d10852cca6.zip
gcc-2fad0cf503f695d737bcabb2dad5c4d10852cca6.tar.gz
gcc-2fad0cf503f695d737bcabb2dad5c4d10852cca6.tar.bz2
re PR target/84406 ([MSP430] ICE on valid code in find_widening_optab_handler_and_mode, at optabs-query.c:476)
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. From-SVN: r257858
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/optabs-query.c20
2 files changed, 25 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77d0dc3..b2622df 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-02-20 Richard Sandiford <richard.sandiford@linaro.org>
+
+ 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.
+
2018-02-20 Jeff Law <law@redhat.com>
PR middle-end/82123
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index a8e10e6..5e5d620 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);