This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR target/32000: struct-layout-1.exp fails at -O2


We may generate unaligned access with those *mov*_internal patterns.
But we never check if memory access is aligned or not. This patch
adds the alignment check for those *mov*_internal patterns.

H.J.
2008-03-25  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/32000

	* config/i386/i386-protos.h (ix86_aligned_p): Removed.
	(ix86_mode_aligned_access_p): New.

	* config/i386/i386.c (ix86_mode_aligned_access_p): New.

	* config/i386/i386.md (*movti_internal): Emit unaligned SSE
	load/store if memory is unaligned.
	(*movti_rex64): Likewise.
	(*movtf_internal): Likewise.
	* config/i386/sse.md (*mov<mode>_internal): Likewise.
	(*movv4sf_internal): Likewise.
	(*movv2df_internal): Likewise.

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 1917)
+++ config/i386/i386.md	(working copy)
@@ -2387,10 +2387,20 @@
 	return "pxor\t%0, %0";
     case 1:
     case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[0], operands[1]))
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqa\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqu\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
@@ -2424,10 +2434,20 @@
 	return "pxor\t%0, %0";
     case 3:
     case 4:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[0], operands[1]))
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqa\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqu\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
@@ -3223,10 +3243,20 @@
     {
     case 0:
     case 1:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[1], operands[0]))
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqa\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqu\t{%1, %0|%0, %1}";
+	}
     case 2:
       if (get_attr_mode (insn) == MODE_V4SF)
 	return "xorps\t%0, %0";
Index: config/i386/sse.md
===================================================================
--- config/i386/sse.md	(revision 1917)
+++ config/i386/sse.md	(working copy)
@@ -86,10 +86,20 @@
       return standard_sse_constant_opcode (insn, operands[1]);
     case 1:
     case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[1], operands[0]))
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqa\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	  else
+	    return "movdqu\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
@@ -162,7 +172,10 @@
       return standard_sse_constant_opcode (insn, operands[1]);
     case 1:
     case 2:
-      return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[1], operands[0]))
+	return "movaps\t{%1, %0|%0, %1}";
+      else
+	return "movups\t{%1, %0|%0, %1}";
     default:
       gcc_unreachable ();
     }
@@ -197,10 +210,20 @@
       return standard_sse_constant_opcode (insn, operands[1]);
     case 1:
     case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      if (ix86_mode_aligned_access_p (operands[1], operands[0]))
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	  else
+	    return "movapd\t{%1, %0|%0, %1}";
+	}
       else
-	return "movapd\t{%1, %0|%0, %1}";
+	{
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	  else
+	    return "movupd\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
Index: config/i386/i386-protos.h
===================================================================
--- config/i386/i386-protos.h	(revision 1917)
+++ config/i386/i386-protos.h	(working copy)
@@ -36,8 +36,7 @@ extern void ix86_output_addr_vec_elt (FI
 extern void ix86_output_addr_diff_elt (FILE *, int, int);
 
 #ifdef RTX_CODE
-extern int ix86_aligned_p (rtx);
-
+extern bool ix86_mode_aligned_access_p (rtx, rtx);
 extern int standard_80387_constant_p (rtx);
 extern const char *standard_80387_constant_opcode (rtx);
 extern rtx standard_80387_constant_rtx (int);
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 1917)
+++ config/i386/i386.c	(working copy)
@@ -25459,6 +25459,24 @@ x86_builtin_vectorization_cost (bool run
     return 0;
 }
 
+/* Return true if memmory access to SRC or DEST is aligned by their
+   mode.  */
+
+bool
+ix86_mode_aligned_access_p (rtx dest, rtx src)
+{
+  rtx mem;
+
+  if (MEM_P (src))
+    mem = src;
+  else if (MEM_P (dest))
+    mem = dest;
+  else
+    return true;
+
+  return MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (GET_MODE (mem));
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]