This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR target/32000: struct-layout-1.exp fails at -O2
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: "GCC Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 25 Mar 2008 14:51:07 -0700
- Subject: 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