Patchwork [SH] PR 52483 - Fix volatile mem stores

login
register
mail settings
Submitter Oleg Endo
Date Oct. 22, 2013, 8:09 p.m.
Message ID <1382472552.2445.137.camel@yam-132-YW-E178-FTW>
Download mbox | patch
Permalink /patch/285490/
State New
Headers show

Comments

Oleg Endo - Oct. 22, 2013, 8:09 p.m.
Hello,

The attached patch fixes volatile mem stores on SH so that they won't
result in redundant sign/zero extensions and will utilize available
addressing modes.  This is similar to what has been done to fix memory
loads in http://gcc.gnu.org/ml/gcc-patches/2013-06/msg01315.html

Tested on rev 203909 with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

and no new failures.
However, the test result summary showed a bunch of "WARNING: program
timed out."  Kaz, could you please add it to your test queue and let me
know if it's OK for trunk?

Cheers,
Oleg

gcc/ChangeLog:
	PR target/52483
	* config/sh/predicates.md (general_movdst_operand): Allow
	reg+reg addressing, do not use general_operand for memory 
	operands.

testsuite/ChangeLog:
	PR target/52483
	* gcc.target/sh/pr52483-1.c: Add tests for memory stores.
	* gcc.target/sh/pr52483-2.c: Likewise.
	* gcc.target/sh/pr52483-3.c: Likewise.
	* gcc.target/sh/pr52483-4.c: Likewise.
Kaz Kojima - Oct. 25, 2013, 3:31 a.m.
Oleg Endo <oleg.endo@t-online.de> wrote:
> The attached patch fixes volatile mem stores on SH so that they won't
> result in redundant sign/zero extensions and will utilize available
> addressing modes.  This is similar to what has been done to fix memory
> loads in http://gcc.gnu.org/ml/gcc-patches/2013-06/msg01315.html
> 
> Tested on rev 203909 with
> make -k check RUNTESTFLAGS="--target_board=sh-sim
> \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"
> 
> and no new failures.
> However, the test result summary showed a bunch of "WARNING: program
> timed out."  Kaz, could you please add it to your test queue and let me
> know if it's OK for trunk?

There are no new failures on my sh4-unknown-linux-gnu tests and
I can't see extra "program timed out" cases for my sh-elf build
on unified tree.

The patch itself looks fine and Ok for trunk.

Regards,
	kaz

Patch

Index: gcc/config/sh/predicates.md
===================================================================
--- gcc/config/sh/predicates.md	(revision 203857)
+++ gcc/config/sh/predicates.md	(working copy)
@@ -550,17 +550,36 @@ 
       && ! (reload_in_progress || reload_completed))
     return 0;
 
-  if ((mode == QImode || mode == HImode)
-      && mode == GET_MODE (op)
-      && (MEM_P (op)
-	  || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
+  if (mode == GET_MODE (op)
+      && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
     {
-      rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0);
+      rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
+      rtx x = XEXP (mem_rtx, 0);
 
-      if (GET_CODE (x) == PLUS
+      if ((mode == QImode || mode == HImode)
+	  && GET_CODE (x) == PLUS
 	  && REG_P (XEXP (x, 0))
 	  && CONST_INT_P (XEXP (x, 1)))
 	return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
+
+      /* Allow reg+reg addressing here without validating the register
+	 numbers.  Usually one of the regs must be R0 or a pseudo reg.
+	 In some cases it can happen that arguments from hard regs are
+	 propagated directly into address expressions.  In this cases reload
+	 will have to fix it up later.  However, allow this only for native
+	 1, 2 or 4 byte addresses.  */
+      if (can_create_pseudo_p () && GET_CODE (x) == PLUS
+	  && GET_MODE_SIZE (mode) <= 4
+	  && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
+	return true;
+
+      /* 'general_operand' does not allow volatile mems during RTL expansion to
+	 avoid matching arithmetic that operates on mems, it seems.
+	 On SH this leads to redundant sign extensions for QImode or HImode
+	 stores.  Thus we mimic the behavior but allow volatile mems.  */
+        if (memory_address_addr_space_p (GET_MODE (mem_rtx), x,
+					 MEM_ADDR_SPACE (mem_rtx)))
+	  return true;
     }
 
   return general_operand (op, mode);
Index: gcc/testsuite/gcc.target/sh/pr52483-1.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr52483-1.c	(revision 203857)
+++ gcc/testsuite/gcc.target/sh/pr52483-1.c	(working copy)
@@ -1,9 +1,9 @@ 
-/* Check that loads from volatile mems don't result in redundant sign
-   extensions.  */
+/* Check that loads/stores from/to volatile mems don't result in redundant
+   sign/zero extensions.  */
 /* { dg-do compile { target "sh*-*-*" } } */
-/* { dg-options "-O1" } */
+/* { dg-options "-O2" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
-/* { dg-final { scan-assembler-not "exts" } } */
+/* { dg-final { scan-assembler-not "exts|extu" } } */
 
 int
 test_00 (volatile char* x)
@@ -11,20 +11,44 @@ 
   return *x;
 }
 
+void
+test_100 (volatile char* x, char y)
+{
+  *x = y;
+}
+
 int
 test_01 (volatile short* x)
 {
   return *x;
 }
 
+void
+test_101 (volatile unsigned char* x, unsigned char y)
+{
+  *x = y;
+}
+
 int
 test_02 (volatile unsigned char* x)
 {
   return *x == 0x80;
 }
 
+void
+test_102 (volatile short* x, short y)
+{
+  *x = y;
+}
+
 int
 test_03 (volatile unsigned short* x)
 {
   return *x == 0xFF80;
 }
+
+void
+test_103 (volatile unsigned short* x, unsigned short y)
+{
+  *x = y;
+}
Index: gcc/testsuite/gcc.target/sh/pr52483-2.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr52483-2.c	(revision 203857)
+++ gcc/testsuite/gcc.target/sh/pr52483-2.c	(working copy)
@@ -1,14 +1,15 @@ 
-/* Check that loads from volatile mems utilize displacement addressing
-   modes and do not result in redundant sign extensions. */
+/* Check that loads/stores from/to volatile mems utilize displacement
+   addressing modes and do not result in redundant sign/zero extensions. */
 /* { dg-do compile { target "sh*-*-*" } } */
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
-/* { dg-final { scan-assembler-times "@\\(5," 2 } } */
-/* { dg-final { scan-assembler-times "@\\(10," 2 } } */
-/* { dg-final { scan-assembler-times "@\\(20," 2 } } */
-/* { dg-final { scan-assembler-times "@\\(40," 2 } } */
-/* { dg-final { scan-assembler-times "@\\(44," 2 } } */
+/* { dg-final { scan-assembler-times "@\\(5," 4 } } */
+/* { dg-final { scan-assembler-times "@\\(10," 4 } } */
+/* { dg-final { scan-assembler-times "@\\(20," 4 } } */
+/* { dg-final { scan-assembler-times "@\\(40," 4 } } */
+/* { dg-final { scan-assembler-times "@\\(44," 4 } } */
 /* { dg-final { scan-assembler-not "exts" } } */
+/* { dg-final { scan-assembler-times "extu|movu" 2 } } */
 
 int
 test_00 (volatile char* x)
@@ -16,35 +17,73 @@ 
   return x[5];
 }
 
+void
+test_100 (volatile char* x, char y)
+{
+  x[5] = y;
+}
+
 int
 test_01 (volatile short* x)
 {
   return x[5];
 }
 
+void
+test_101 (volatile short* x, short y)
+{
+  x[5] = y;
+}
+
 int
 test_02 (volatile int* x)
 {
   return x[5];
 }
 
+void
+test_102 (volatile int* x, int y)
+{
+  x[5] = y;
+}
+
 long long
 test_03 (volatile long long* x)
 {
   return x[5];
 }
 
+void
+test_103 (volatile long long* x, long long y)
+{
+  x[5] = y;
+}
+
 unsigned int
 test_04 (volatile unsigned char* x)
 {
+  // expected 1x extu.b or movu.b
   return x[5];
 }
 
+void
+test_104 (volatile unsigned char* x, unsigned char y)
+{
+  x[5] = y;
+}
+
 unsigned int
 test_05 (volatile unsigned short* x)
 {
+  // expected 1x extu.w or movu.w
   return x[5];
 }
+
+void
+test_105 (volatile unsigned short* x, unsigned short y)
+{
+  x[5] = y;
+}
  
 unsigned int
 test_06 (volatile unsigned int* x)
@@ -52,8 +91,20 @@ 
   return x[5];
 }
 
+void
+test_106 (volatile unsigned int* x, unsigned int y)
+{
+  x[5] = y;
+}
+
 unsigned long long
 test_07 (volatile unsigned long long* x)
 {
   return x[5];
 }
+
+void
+test_107 (volatile unsigned long long* x, unsigned long long y)
+{
+  x[5] = y;
+}
Index: gcc/testsuite/gcc.target/sh/pr52483-3.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr52483-3.c	(revision 203857)
+++ gcc/testsuite/gcc.target/sh/pr52483-3.c	(working copy)
@@ -1,10 +1,10 @@ 
-/* Check that loads from volatile mems utilize indexed addressing
-   modes and do not result in redundant sign extensions. */
+/* Check that loads/stores from/to volatile mems utilize indexed addressing
+   modes and do not result in redundant sign/zero extensions. */
 /* { dg-do compile { target "sh*-*-*" } } */
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
-/* { dg-final { scan-assembler-times "@\\(r0," 3 } } */
-/* { dg-final { scan-assembler-not "exts" } } */
+/* { dg-final { scan-assembler-times "@\\(r0," 6 } } */
+/* { dg-final { scan-assembler-not "exts|extu" } } */
 
 int
 test_00 (volatile char* x, unsigned int y)
@@ -12,14 +12,32 @@ 
   return x[y];
 }
 
+void
+test_100 (volatile char* x, unsigned int y, char z)
+{
+  x[y] = z;
+}
+
 int
 test_01 (volatile short* x, unsigned int y)
 {
   return x[y];
 }
 
+void
+test_101 (volatile short* x, unsigned int y, short z)
+{
+  x[y] = z;
+}
+
 int
 test_02 (volatile int* x, unsigned int y)
 {
   return x[y];
 }
+
+int
+test_102 (volatile int* x, unsigned int y, int z)
+{
+  x[y] = z;
+}
Index: gcc/testsuite/gcc.target/sh/pr52483-4.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr52483-4.c	(revision 203857)
+++ gcc/testsuite/gcc.target/sh/pr52483-4.c	(working copy)
@@ -1,12 +1,18 @@ 
-/* Check that loads from volatile floating point mems utilize indexed
-   addressing modes. */
+/* Check that loads/stores from/to volatile floating point mems utilize
+   indexed addressing modes. */
 /* { dg-do compile { target "sh*-*-*" } } */
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } }  */
-/* { dg-final { scan-assembler-times "@\\(r0," 1 } } */
+/* { dg-final { scan-assembler-times "@\\(r0," 2 } } */
 
 float
 test_00 (volatile float* x, unsigned int y)
 {
   return x[y];
 }
+
+void
+test_100 (volatile float* x, unsigned int y, float z)
+{
+  x[y] = z;
+}