aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2008-03-31 13:32:38 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2008-03-31 06:32:38 -0700
commit66e1ecfeefc91ddc92c8a9ce62a6383afd92bca2 (patch)
treeabf2f98f5cbb58d08ed990748f37f097440d04ed /gcc
parent9b1b8df212720add1ad9c702a5c0d0fd8b9d9ac3 (diff)
downloadgcc-66e1ecfeefc91ddc92c8a9ce62a6383afd92bca2.zip
gcc-66e1ecfeefc91ddc92c8a9ce62a6383afd92bca2.tar.gz
gcc-66e1ecfeefc91ddc92c8a9ce62a6383afd92bca2.tar.bz2
re PR target/32000 (x86 backend uses aligned load on unaligned memory)
gcc/ 2008-03-31 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. gcc/testsuite/ 2008-03-31 H.J. Lu <hongjiu.lu@intel.com> PR target/32000 * gcc.target/i386/pr32000-1.c: New. From-SVN: r133753
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/i386/i386.md38
-rw-r--r--gcc/config/i386/predicates.md5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr32000-1.c26
5 files changed, 77 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f7be8f1..0a426b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-03-31 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-31 Andrew Pinski <pinskia@gmail.com>
PR tree-opt/35431
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 8b0a280..1135799 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2385,10 +2385,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 ();
}
@@ -2422,10 +2435,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 ();
}
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 7ba7289..5389aa9 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -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)")))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 06b43d9..4353823 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/32000
+ * gcc.target/i386/pr32000-1.c: New.
+
2008-03-31 Andrew Pinski <pinskia@gmail.com>
PR tree-opt/35431
diff --git a/gcc/testsuite/gcc.target/i386/pr32000-1.c b/gcc/testsuite/gcc.target/i386/pr32000-1.c
new file mode 100644
index 0000000..483d24a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32000-1.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-O -msse2 -std=gnu99" } */
+
+#include "sse2-check.h"
+
+typedef struct { _Decimal128 f __attribute__((packed)); } packed;
+
+_Decimal128 __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 y.f;
+}
+
+void
+sse2_test (void)
+{
+ packed x;
+ _Decimal128 y = -1;
+ x.f = y;
+ y = foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, -1, x);
+ if (__builtin_memcmp (&y, &x.f, sizeof (y)))
+ abort ();
+}