[PATCH] Disallow i?86/x86_64 movstrict<mode> for subregs of non-MODE_INT regs (PR target/48678)

Jakub Jelinek jakub@redhat.com
Tue Apr 19 16:07:00 GMT 2011


Hi!

Since MEM_REF has been added, we can unlike in 4.5 and earlier, arbitrary
VCEs on the LHS.  Reload isn't able to reload
(strict_low_part (subreg:HI (reg:V2DI ...)))
on the LHS, while it probably should be taught to do that, such
movstrict[qh]i IMHO will only very rarely lead to good code,
unless pinsrw/pinsrq can be used (currently we have not a suitable
movstrict* pattern using pinsr*).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6?

2011-04-19  Jakub Jelinek  <jakub@redhat.com>

	PR target/48678
	* config/i386/i386.md (movstrict<mode>): FAIL if operands[0]
	is a SUBREG with non-MODE_INT mode inside of it.

	* gcc.target/i386/pr48678.c: New test.

--- gcc/config/i386/i386.md.jj	2011-04-06 16:33:26.000000000 +0200
+++ gcc/config/i386/i386.md	2011-04-19 14:08:55.000000000 +0200
@@ -2427,6 +2427,9 @@ (define_expand "movstrict<mode>"
 {
   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
     FAIL;
+  if (GET_CODE (operands[0]) == SUBREG
+      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
+    FAIL;
   /* Don't generate memory->memory moves, go through a register */
   if (MEM_P (operands[0]) && MEM_P (operands[1]))
     operands[1] = force_reg (<MODE>mode, operands[1]);
--- gcc/testsuite/gcc.target/i386/pr48678.c.jj	2011-04-19 14:02:33.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr48678.c	2011-04-19 14:07:08.000000000 +0200
@@ -0,0 +1,16 @@
+/* PR target/48678 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2" } */
+
+#include <emmintrin.h>
+
+typedef short T __attribute__((may_alias));
+struct S { __m128i d; };
+
+__m128i
+foo (short *x, struct S *y, __m128i *z)
+{
+  struct S s = *y;
+  ((T *) &s.d)[0] = *x;
+  return _mm_cmpeq_epi16 (s.d, *z);
+}

	Jakub



More information about the Gcc-patches mailing list