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: x86 backend uses aligned load on unaligned memory


Hi,

movti may generate SSE vector move for TDmode. When TDmode is
aligned at 1 byte, movti generates aligned load on unaligned
memory.  This patch adds a new predicate and uses it to check
misaligned operand to generate unaligned move if needed.


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

	PR target/32000
	* config/i386/i386.md (*movti_internal): Emit unaligned SSE
	load/store if memory is unaligned.
	(*movti_rex64): Likewise.

	* config/i386/predicates.md (misaligned_operand): New.

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

	PR target/32000
	* gcc.target/i386/pr32000-1.c: New.
	* gcc.target/i386/pr32000-2.c: Likewise.
	* gcc.target/i386/pr32000-3.c: Likewise.
	* gcc.target/i386/pr32000-4.c: Likewise.
	* gcc.target/i386/pr32000-5.c: Likewise.
	* gcc.target/i386/pr32000-6.c: Likewise.

--- gcc/config/i386/i386.md.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/config/i386/i386.md	2008-03-30 10:07:59.000000000 -0700
@@ -2387,10 +2387,23 @@
 	return "pxor\t%0, %0";
     case 1:
     case 2:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      /* TDmode values are passed as TImode on the stack.  Moving them
+	 to stack may result in unaligned memory access.  */
+      if (misaligned_operand (operands[0], TImode)
+	  || misaligned_operand (operands[1], TImode))
+	{ 
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	 else
+	   return "movdqu\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{ 
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	 else
+	   return "movdqa\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
@@ -2424,10 +2437,23 @@
 	return "pxor\t%0, %0";
     case 3:
     case 4:
-      if (get_attr_mode (insn) == MODE_V4SF)
-	return "movaps\t{%1, %0|%0, %1}";
+      /* TDmode values are passed as TImode on the stack.  Moving them
+	 to stack may result in unaligned memory access.  */
+      if (misaligned_operand (operands[0], TImode)
+	  || misaligned_operand (operands[1], TImode))
+	{ 
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movups\t{%1, %0|%0, %1}";
+	 else
+	   return "movdqu\t{%1, %0|%0, %1}";
+	}
       else
-	return "movdqa\t{%1, %0|%0, %1}";
+	{ 
+	  if (get_attr_mode (insn) == MODE_V4SF)
+	    return "movaps\t{%1, %0|%0, %1}";
+	 else
+	   return "movdqa\t{%1, %0|%0, %1}";
+	}
     default:
       gcc_unreachable ();
     }
--- gcc/config/i386/predicates.md.td	2008-03-30 08:33:33.000000000 -0700
+++ gcc/config/i386/predicates.md	2008-03-30 10:07:59.000000000 -0700
@@ -1043,3 +1043,8 @@
 
 (define_predicate "absneg_operator"
   (match_code "abs,neg"))
+
+;; Return 1 if OP is misaligned memory operand
+(define_predicate "misaligned_operand"
+  (and (match_code "mem")
+       (match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
--- gcc/testsuite/gcc.target/i386/pr32000-1.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-1.c	2008-03-30 10:07:59.000000000 -0700
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-O -msse2 -std=gnu99" } */
+
+#include "sse2-check.h"
+
+int __attribute__((noinline))
+iszero (_Decimal128 x)
+{
+  return x == 0;
+}
+
+typedef struct { _Decimal128 f __attribute__((packed)); } packed;
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
+{
+  return iszero (y.f);
+}
+
+void
+sse2_test (void)
+{
+  if (!foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, (packed) { 0 }))
+    abort ();
+}
--- gcc/testsuite/gcc.target/i386/pr32000-2.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-2.c	2008-03-30 10:07:59.000000000 -0700
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-O -msse2 -std=gnu99" } */
+
+#include "sse2-check.h"
+
+int __attribute__((noinline))
+iszero (_Decimal128 x)
+{
+  return x == 0;
+}
+
+typedef _Decimal128 unaligned __attribute__((aligned(1)));
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
+{
+  return iszero (y);
+}
+
+void
+sse2_test (void)
+{
+  if (!foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0))
+    abort ();
+}
--- gcc/testsuite/gcc.target/i386/pr32000-3.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-3.c	2008-03-30 10:07:59.000000000 -0700
@@ -0,0 +1,19 @@
+/* Test that we don't generate aligned load when memory is unaligned.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=x86-64 -mtune=generic -std=gnu99" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+/* { dg-final { scan-assembler "movdqu" } } */
+
+extern int iszero (_Decimal128);
+
+typedef struct { _Decimal128 f __attribute__((packed)); } packed;
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
+{
+  return iszero (y.f);
+}
--- gcc/testsuite/gcc.target/i386/pr32000-4.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-4.c	2008-03-30 10:07:59.000000000 -0700
@@ -0,0 +1,19 @@
+/* Test that we don't generate aligned load when memory is unaligned.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=x86-64 -mtune=generic -std=gnu99" } */
+/* { dg-final { scan-assembler-not "movdqa" } } */
+/* { dg-final { scan-assembler "movdqu" } } */
+
+extern int iszero (_Decimal128);
+
+typedef _Decimal128 unaligned __attribute__((aligned(1)));
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
+{
+  return iszero (y);
+}
--- gcc/testsuite/gcc.target/i386/pr32000-5.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-5.c	2008-03-30 12:35:35.000000000 -0700
@@ -0,0 +1,19 @@
+/* Test that we generate aligned load when memory is aligned.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=x86-64 -mtune=generic -std=gnu99" } */
+/* { dg-final { scan-assembler-not "movdqu" } } */
+/* { dg-final { scan-assembler "movdqa" } } */
+
+extern int iszero (_Decimal128);
+
+typedef struct { _Decimal128 f; } aligned;
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, aligned y)
+{
+  return iszero (y.f);
+}
--- gcc/testsuite/gcc.target/i386/pr32000-6.c.td	2008-03-30 10:07:59.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/pr32000-6.c	2008-03-30 10:07:59.000000000 -0700
@@ -0,0 +1,17 @@
+/* Test that we generate aligned load when memory is aligned.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=x86-64 -mtune=generic -std=gnu99" } */
+/* { dg-final { scan-assembler-not "movdqu" } } */
+/* { dg-final { scan-assembler "movdqa" } } */
+
+extern int iszero (_Decimal128);
+
+int __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, _Decimal128 y)
+{
+  return iszero (y);
+}

----- End forwarded message -----


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