This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR target/32000: x86 backend uses aligned load on unaligned memory
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 30 Mar 2008 14:27:21 -0700
- Subject: 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 -----