mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
a6f623d4fa
commit
35d1b0838c
|
|
@ -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>
|
2013-10-26 Vladimir Makarov <vmakarov@redhat.com>
|
||||||
|
|
||||||
Revert:
|
Revert:
|
||||||
|
|
|
||||||
|
|
@ -550,17 +550,36 @@
|
||||||
&& ! (reload_in_progress || reload_completed))
|
&& ! (reload_in_progress || reload_completed))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((mode == QImode || mode == HImode)
|
if (mode == GET_MODE (op)
|
||||||
&& mode == GET_MODE (op)
|
&& (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (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))
|
&& REG_P (XEXP (x, 0))
|
||||||
&& CONST_INT_P (XEXP (x, 1)))
|
&& CONST_INT_P (XEXP (x, 1)))
|
||||||
return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
|
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);
|
return general_operand (op, mode);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2013-10-26 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
* g++.dg/torture/pr49309.C: Removed.
|
* g++.dg/torture/pr49309.C: Removed.
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/* Check that loads from volatile mems don't result in redundant sign
|
/* Check that loads/stores from/to volatile mems don't result in redundant
|
||||||
extensions. */
|
sign/zero extensions. */
|
||||||
/* { dg-do compile { target "sh*-*-*" } } */
|
/* { dg-do compile { target "sh*-*-*" } } */
|
||||||
/* { dg-options "-O1" } */
|
/* { dg-options "-O2" } */
|
||||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||||
/* { dg-final { scan-assembler-not "exts" } } */
|
/* { dg-final { scan-assembler-not "exts|extu" } } */
|
||||||
|
|
||||||
int
|
int
|
||||||
test_00 (volatile char* x)
|
test_00 (volatile char* x)
|
||||||
|
|
@ -11,20 +11,44 @@ test_00 (volatile char* x)
|
||||||
return *x;
|
return *x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_100 (volatile char* x, char y)
|
||||||
|
{
|
||||||
|
*x = y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_01 (volatile short* x)
|
test_01 (volatile short* x)
|
||||||
{
|
{
|
||||||
return *x;
|
return *x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_101 (volatile unsigned char* x, unsigned char y)
|
||||||
|
{
|
||||||
|
*x = y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_02 (volatile unsigned char* x)
|
test_02 (volatile unsigned char* x)
|
||||||
{
|
{
|
||||||
return *x == 0x80;
|
return *x == 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_102 (volatile short* x, short y)
|
||||||
|
{
|
||||||
|
*x = y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_03 (volatile unsigned short* x)
|
test_03 (volatile unsigned short* x)
|
||||||
{
|
{
|
||||||
return *x == 0xFF80;
|
return *x == 0xFF80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_103 (volatile unsigned short* x, unsigned short y)
|
||||||
|
{
|
||||||
|
*x = y;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
/* Check that loads from volatile mems utilize displacement addressing
|
/* Check that loads/stores from/to volatile mems utilize displacement
|
||||||
modes and do not result in redundant sign extensions. */
|
addressing modes and do not result in redundant sign/zero extensions. */
|
||||||
/* { dg-do compile { target "sh*-*-*" } } */
|
/* { dg-do compile { target "sh*-*-*" } } */
|
||||||
/* { dg-options "-O1" } */
|
/* { dg-options "-O1" } */
|
||||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(5," 2 } } */
|
/* { dg-final { scan-assembler-times "@\\(5," 4 } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(10," 2 } } */
|
/* { dg-final { scan-assembler-times "@\\(10," 4 } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(20," 2 } } */
|
/* { dg-final { scan-assembler-times "@\\(20," 4 } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(40," 2 } } */
|
/* { dg-final { scan-assembler-times "@\\(40," 4 } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(44," 2 } } */
|
/* { dg-final { scan-assembler-times "@\\(44," 4 } } */
|
||||||
/* { dg-final { scan-assembler-not "exts" } } */
|
/* { dg-final { scan-assembler-not "exts" } } */
|
||||||
|
/* { dg-final { scan-assembler-times "extu|movu" 2 } } */
|
||||||
|
|
||||||
int
|
int
|
||||||
test_00 (volatile char* x)
|
test_00 (volatile char* x)
|
||||||
|
|
@ -16,35 +17,73 @@ test_00 (volatile char* x)
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_100 (volatile char* x, char y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_01 (volatile short* x)
|
test_01 (volatile short* x)
|
||||||
{
|
{
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_101 (volatile short* x, short y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_02 (volatile int* x)
|
test_02 (volatile int* x)
|
||||||
{
|
{
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_102 (volatile int* x, int y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
long long
|
long long
|
||||||
test_03 (volatile long long* x)
|
test_03 (volatile long long* x)
|
||||||
{
|
{
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_103 (volatile long long* x, long long y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
test_04 (volatile unsigned char* x)
|
test_04 (volatile unsigned char* x)
|
||||||
{
|
{
|
||||||
|
// expected 1x extu.b or movu.b
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_104 (volatile unsigned char* x, unsigned char y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
test_05 (volatile unsigned short* x)
|
test_05 (volatile unsigned short* x)
|
||||||
{
|
{
|
||||||
|
// expected 1x extu.w or movu.w
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_105 (volatile unsigned short* x, unsigned short y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
test_06 (volatile unsigned int* x)
|
test_06 (volatile unsigned int* x)
|
||||||
|
|
@ -52,8 +91,20 @@ test_06 (volatile unsigned int* x)
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_106 (volatile unsigned int* x, unsigned int y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long long
|
unsigned long long
|
||||||
test_07 (volatile unsigned long long* x)
|
test_07 (volatile unsigned long long* x)
|
||||||
{
|
{
|
||||||
return x[5];
|
return x[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_107 (volatile unsigned long long* x, unsigned long long y)
|
||||||
|
{
|
||||||
|
x[5] = y;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
/* Check that loads from volatile mems utilize indexed addressing
|
/* Check that loads/stores from/to volatile mems utilize indexed addressing
|
||||||
modes and do not result in redundant sign extensions. */
|
modes and do not result in redundant sign/zero extensions. */
|
||||||
/* { dg-do compile { target "sh*-*-*" } } */
|
/* { dg-do compile { target "sh*-*-*" } } */
|
||||||
/* { dg-options "-O1" } */
|
/* { dg-options "-O1" } */
|
||||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||||
/* { dg-final { scan-assembler-times "@\\(r0," 3 } } */
|
/* { dg-final { scan-assembler-times "@\\(r0," 6 } } */
|
||||||
/* { dg-final { scan-assembler-not "exts" } } */
|
/* { dg-final { scan-assembler-not "exts|extu" } } */
|
||||||
|
|
||||||
int
|
int
|
||||||
test_00 (volatile char* x, unsigned int y)
|
test_00 (volatile char* x, unsigned int y)
|
||||||
|
|
@ -12,14 +12,32 @@ test_00 (volatile char* x, unsigned int y)
|
||||||
return x[y];
|
return x[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_100 (volatile char* x, unsigned int y, char z)
|
||||||
|
{
|
||||||
|
x[y] = z;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_01 (volatile short* x, unsigned int y)
|
test_01 (volatile short* x, unsigned int y)
|
||||||
{
|
{
|
||||||
return x[y];
|
return x[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_101 (volatile short* x, unsigned int y, short z)
|
||||||
|
{
|
||||||
|
x[y] = z;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
test_02 (volatile int* x, unsigned int y)
|
test_02 (volatile int* x, unsigned int y)
|
||||||
{
|
{
|
||||||
return x[y];
|
return x[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test_102 (volatile int* x, unsigned int y, int z)
|
||||||
|
{
|
||||||
|
x[y] = z;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,18 @@
|
||||||
/* Check that loads from volatile floating point mems utilize indexed
|
/* Check that loads/stores from/to volatile floating point mems utilize
|
||||||
addressing modes. */
|
indexed addressing modes. */
|
||||||
/* { dg-do compile { target "sh*-*-*" } } */
|
/* { dg-do compile { target "sh*-*-*" } } */
|
||||||
/* { dg-options "-O1" } */
|
/* { dg-options "-O1" } */
|
||||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */
|
/* { 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
|
float
|
||||||
test_00 (volatile float* x, unsigned int y)
|
test_00 (volatile float* x, unsigned int y)
|
||||||
{
|
{
|
||||||
return x[y];
|
return x[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_100 (volatile float* x, unsigned int y, float z)
|
||||||
|
{
|
||||||
|
x[y] = z;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue