From 4ed04e93c2c9a8266be6a1cb6b11858add8aad70 Mon Sep 17 00:00:00 2001
From: Uros Bizjak <uros@gcc.gnu.org>
Date: Tue, 17 Jan 2017 20:44:53 +0100
Subject: [PATCH] i386.h (MASK_CLASS_P): New define.

	* config/i386/i386.h (MASK_CLASS_P): New define.
	* config/i386/i386.c (inline_secondary_memory_needed): Ensure that
	there are no registers from different register sets also when
	mask registers are used.  Update function comment.
	* config/i386/i386.md (*movsi_internal): Split (*k/*krm) alternative
	to (*k/*r) and (*k/*km) alternatives.

From-SVN: r244548
---
 gcc/ChangeLog           | 27 ++++++++++++++++++---------
 gcc/config/i386/i386.c  | 25 ++++++++++++++-----------
 gcc/config/i386/i386.h  |  2 ++
 gcc/config/i386/i386.md |  6 +++---
 4 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8ba01c5f05d..15a07182aa49 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2017-01-17  Uros Bizjak  <ubizjak@gmail.com>
+
+	* config/i386/i386.h (MASK_CLASS_P): New define.
+	* config/i386/i386.c (inline_secondary_memory_needed): Ensure that
+	there are no registers from different register sets also when
+	mask registers are used.  Update function comment.
+	* config/i386/i386.md (*movsi_internal): Split (*k/*krm) alternative
+	to (*k/*r) and (*k/*km) alternatives.
+
 2017-01-17  Wilco Dijkstra  <wdijkstr@arm.com>
 
 	* config/aarch64/aarch64.md (eh_return): Remove pattern and splitter.
@@ -216,7 +225,7 @@
 	definitions accordingly.
 
 2017-01-17  Kito Cheng  <kito.cheng@gmail.com>
-            Kuan-Lin Chen  <kuanlinchentw@gmail.com>
+	    Kuan-Lin Chen  <kuanlinchentw@gmail.com>
 
 	PR target/79079
 	* internal-fn.c (expand_mul_overflow): Use convert_modes instead of
@@ -295,14 +304,14 @@
 
 	Revert:
 	2016-12-02  Tadek Kijkowski  <tkijkowski@gmail.com>
-        * Makefile.in (PREPROCESSOR_DEFINES): Add a level of indirection
-        for several include directories that may be relative to sysroot.
-        * config/i386/x-mingw32 (gplus_includedir): Define.
-        (gplus_tool_includedir, gplus_backward_include_dir): Likewise.
-        (native_system_includedir): Likewise.
-        * config/i386/mingw32.h (STANDARD_STARTFILE_PREFIX_1): Do not
-        override if TARGET_SYSTEM_ROOT is defined.
-        (NATIVE_SYSTEM_HEADER_DIR): Likewise.
+	* Makefile.in (PREPROCESSOR_DEFINES): Add a level of indirection
+	for several include directories that may be relative to sysroot.
+	* config/i386/x-mingw32 (gplus_includedir): Define.
+	(gplus_tool_includedir, gplus_backward_include_dir): Likewise.
+	(native_system_includedir): Likewise.
+	* config/i386/mingw32.h (STANDARD_STARTFILE_PREFIX_1): Do not
+	override if TARGET_SYSTEM_ROOT is defined.
+	(NATIVE_SYSTEM_HEADER_DIR): Likewise.
 
 	PR tree-optimization/79090
 	PR tree-optimization/33562
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index eccb5d2cb22e..eb4781d9239c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -39868,18 +39868,18 @@ ix86_class_likely_spilled_p (reg_class_t rclass)
   return false;
 }
 
-/* If we are copying between general and FP registers, we need a memory
-   location. The same is true for SSE and MMX registers.
+/* If we are copying between registers from different register sets
+   (e.g. FP and integer), we may need a memory location.
 
-   To optimize register_move_cost performance, allow inline variant.
-
-   The macro can't work reliably when one of the CLASSES is class containing
-   registers from multiple units (SSE, MMX, integer).  We avoid this by never
-   combining those units in single alternative in the machine description.
+   The function can't work reliably when one of the CLASSES is a class
+   containing registers from multiple sets.  We avoid this by never combining
+   different sets in a single alternative in the machine description.
    Ensure that this constraint holds to avoid unexpected surprises.
 
-   When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
-   enforce these sanity checks.  */
+   When STRICT is false, we are being called from REGISTER_MOVE_COST,
+   so do not enforce these sanity checks.
+
+   To optimize register_move_cost performance, define inline variant.  */
 
 static inline bool
 inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
@@ -39887,12 +39887,15 @@ inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
 {
   if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
     return false;
+
   if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
       || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
       || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
       || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
-      || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
+      || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
+      || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
+      || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
     {
       gcc_assert (!strict || lra_in_progress);
       return true;
@@ -39902,7 +39905,7 @@ inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
     return true;
 
   /* Between mask and general, we have moves no larger than word size.  */
-  if ((MAYBE_MASK_CLASS_P (class1) != MAYBE_MASK_CLASS_P (class2))
+  if ((MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
       && (GET_MODE_SIZE (mode) > UNITS_PER_WORD))
   return true;
 
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index df3a134fdebc..aeacf0f29dab 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1378,6 +1378,8 @@ enum reg_class
   reg_class_subset_p ((CLASS), ALL_SSE_REGS)
 #define MMX_CLASS_P(CLASS) \
   ((CLASS) == MMX_REGS)
+#define MASK_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), MASK_REGS)
 #define MAYBE_INTEGER_CLASS_P(CLASS) \
   reg_classes_intersect_p ((CLASS), GENERAL_REGS)
 #define MAYBE_FLOAT_CLASS_P(CLASS) \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 01815170d230..1d58ceb773ab 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2324,9 +2324,9 @@
 
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-			"=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
+			"=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k,*k ,*rm")
 	(match_operand:SI 1 "general_operand"
-			"g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
+			"g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*r,*km,*k"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (get_attr_type (insn))
@@ -2403,7 +2403,7 @@
 	      (const_string "sselog1")
 	    (eq_attr "alternative" "7,8,9,10,12")
 	      (const_string "ssemov")
-	    (eq_attr "alternative" "13,14")
+	    (eq_attr "alternative" "13,14,15")
 	      (const_string "mskmov")
 	    (and (match_operand 0 "register_operand")
 		 (match_operand 1 "pic_32bit_operand"))
-- 
GitLab