re PR target/84406 ([MSP430] ICE on valid code in find_widening_optab_handler_and_mod...
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 20 Feb 2018 19:11:34 +0000 (19:11 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 20 Feb 2018 19:11:34 +0000 (12:11 -0700)
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

gcc/ChangeLog
gcc/optabs-query.c

index 77d0dc3a3de3ecfdb084175959002d590a8eb9c6..b2622df859a2bc02cfe32e3df8427920035707be 100644 (file)
@@ -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
index a8e10e6deccb85c08c032b0f88115341bc638e35..5e5d620d4377d5fd89969468612c375edac4500e 100644 (file)
@@ -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);