diff mbox

Fix target/68124

Message ID 563268D1.6030706@redhat.com
State New
Headers show

Commit Message

Richard Henderson Oct. 29, 2015, 6:43 p.m. UTC
My fix for PR 67609 caused problems for -m32 -march=corei7,
a combination that I hadn't tested.

My feeling is that for post-reload splitters that want to
frob a register to a different mode, we ought to use something
more specific than gen_lowpart.  Perhaps adjust_reg_mode, or
perhaps something new and more specific.  But I'm not going to
try to audit the whole backend at this stage.

Anyway, I've tightened the test to the exact conditions that
caused 67609 problems in the expander; one can hope that everything
else is intentional in the backend and won't cause problems...

Committed.


r~
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.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 82fd054..8476677 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;
 }