re PR target/52483 (SH Target: Loads from volatile memory leave redundant sign/zero extensions)

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

	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.

From-SVN: r204097
This commit is contained in:
Oleg Endo 2013-10-26 22:07:37 +00:00
parent a6f623d4fa
commit 35d1b0838c
7 changed files with 156 additions and 24 deletions

View file

@ -1,3 +1,9 @@
2013-10-26 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52483
* config/sh/predicates.md (general_movdst_operand): Allow reg+reg
addressing, do not use general_operand for memory operands.
2013-10-26 Vladimir Makarov <vmakarov@redhat.com>
Revert:

View file

@ -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);

View file

@ -1,3 +1,11 @@
2013-10-26 Oleg Endo <olegendo@gcc.gnu.org>
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.
2013-10-26 Jeff Law <law@redhat.com>
* g++.dg/torture/pr49309.C: Removed.

View file

@ -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 @@ test_00 (volatile char* x)
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;
}

View file

@ -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 @@ test_00 (volatile char* x)
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 @@ test_06 (volatile unsigned int* x)
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;
}

View file

@ -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 @@ test_00 (volatile char* x, unsigned int y)
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;
}

View file

@ -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;
}