Fix target/68124
authorRichard Henderson <rth@redhat.com>
Thu, 29 Oct 2015 18:36:39 +0000 (11:36 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 29 Oct 2015 18:36:39 +0000 (11:36 -0700)
        PR target/68124
        PR rtl-opt/67609
        * config/i386/i386.c (ix86_cannot_change_mode_class): Tighten
        sse check to the exact conditions of PR 67609.

From-SVN: r229550

gcc/ChangeLog
gcc/config/i386/i386.c

index 1f32c9dfa5904f5f95e18d5ceebb18baca32ba81..fa3e95651deb6dc174861febb55d8d3be8e09af9 100644 (file)
@@ -1,3 +1,10 @@
+2015-10-29  Richard Henderson  <rth@redhat.com>
+
+       PR target/68124
+       PR rtl-opt/67609
+       * config/i386/i386.c (ix86_cannot_change_mode_class): Tighten
+       sse check to the exact conditions of PR 67609.
+
 2015-10-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000.c (rs6000_init_libfuncs): Split libfunc
index 82fd05412ac62228a546ba0bf0d24ed33adc5b66..8476677f1c17ada54b41c3af84a825d11f5240c8 100644 (file)
@@ -43031,22 +43031,28 @@ ix86_cannot_change_mode_class (machine_mode from, machine_mode to,
   if (MAYBE_FLOAT_CLASS_P (regclass))
     return true;
 
-  /* Vector registers do not support QI or HImode loads.  If we don't
-     disallow a change to these modes, reload will assume it's ok to
-     drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
-     the vec_dupv4hi pattern.
-
-     Further, we cannot allow word_mode subregs of full vector modes.
-     Otherwise the middle-end will assume it's ok to store to
-     (subreg:DI (reg:TI 100) 0) in order to modify only the low 64 bits
-     of the 128-bit register.  However, after reload the subreg will
-     be dropped leaving a plain DImode store.  This is indistinguishable
-     from a "normal" DImode move, and so we're justified to use movsd,
-     which modifies the entire 128-bit register.
-
-     Combining these two conditions, disallow all narrowing mode changes.  */
   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
-    return GET_MODE_SIZE (to) < GET_MODE_SIZE (from);
+    {
+      int from_size = GET_MODE_SIZE (from);
+      int to_size = GET_MODE_SIZE (to);
+
+      /* Vector registers do not support QI or HImode loads.  If we don't
+        disallow a change to these modes, reload will assume it's ok to
+        drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
+        the vec_dupv4hi pattern.  */
+      if (from_size < 4)
+       return true;
+
+      /* Further, we cannot allow word_mode subregs of full vector modes.
+         Otherwise the middle-end will assume it's ok to store to
+         (subreg:DI (reg:TI 100) 0) in order to modify only the low 64 bits
+         of the 128-bit register.  However, after reload the subreg will
+         be dropped leaving a plain DImode store.  This is indistinguishable
+         from a "normal" DImode move, and so we're justified to use movsd,
+         which modifies the entire 128-bit register.  */
+      if (to_size == UNITS_PER_WORD && from_size > UNITS_PER_WORD)
+       return true;
+    }
 
   return false;
 }