re PR target/52483 (SH Target: Loads from volatile memory leave redundant sign/zero extensions)
PR target/52483 * config/sh/predicates.md (general_extend_operand): Invoke general_movsrc_operand for memory operands. (general_movsrc_operand): Allow reg+reg addressing, do not use general_operand for memory operands. PR target/52483 * gcc.target/sh/pr52483-1.c: New. * gcc.target/sh/pr52483-2.c: New. * gcc.target/sh/pr52483-3.c: New. * gcc.target/sh/pr52483-4.c: New. * gcc.target/sh/pr52483-5.c: New. From-SVN: r200350
This commit is contained in:
parent
97db2bf7fb
commit
0bcf9a093e
8 changed files with 204 additions and 9 deletions
|
@ -1,3 +1,11 @@
|
|||
2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/52483
|
||||
* config/sh/predicates.md (general_extend_operand): Invoke
|
||||
general_movsrc_operand for memory operands.
|
||||
(general_movsrc_operand): Allow reg+reg addressing, do not use
|
||||
general_operand for memory operands.
|
||||
|
||||
2013-06-23 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* config/i386/i386.c (ix86_pragma_target_parse): Restore target
|
||||
|
|
|
@ -398,9 +398,13 @@
|
|||
(define_predicate "general_extend_operand"
|
||||
(match_code "subreg,reg,mem,truncate")
|
||||
{
|
||||
return (GET_CODE (op) == TRUNCATE
|
||||
? arith_operand
|
||||
: nonimmediate_operand) (op, mode);
|
||||
if (GET_CODE (op) == TRUNCATE)
|
||||
return arith_operand (op, mode);
|
||||
|
||||
if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))
|
||||
return general_movsrc_operand (op, mode);
|
||||
|
||||
return nonimmediate_operand (op, mode);
|
||||
})
|
||||
|
||||
;; Returns 1 if OP is a simple register address.
|
||||
|
@ -468,17 +472,36 @@
|
|||
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
|
||||
loads. 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;
|
||||
}
|
||||
|
||||
if (TARGET_SHMEDIA
|
||||
|
@ -489,6 +512,7 @@
|
|||
&& GET_CODE (op) == SUBREG && GET_MODE (op) == mode
|
||||
&& SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
|
||||
/* FIXME */ abort (); /* return 1; */
|
||||
|
||||
return general_operand (op, mode);
|
||||
})
|
||||
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/52483
|
||||
* gcc.target/sh/pr52483-1.c: New.
|
||||
* gcc.target/sh/pr52483-2.c: New.
|
||||
* gcc.target/sh/pr52483-3.c: New.
|
||||
* gcc.target/sh/pr52483-4.c: New.
|
||||
* gcc.target/sh/pr52483-5.c: New.
|
||||
|
||||
2013-06-23 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* testsuite/gcc.target/i386/intrinsics_1.c: New test.
|
||||
|
|
30
gcc/testsuite/gcc.target/sh/pr52483-1.c
Normal file
30
gcc/testsuite/gcc.target/sh/pr52483-1.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* Check that loads from volatile mems don't result in redundant sign
|
||||
extensions. */
|
||||
/* { dg-do compile { target "sh*-*-*" } } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||
/* { dg-final { scan-assembler-not "exts" } } */
|
||||
|
||||
int
|
||||
test_00 (volatile char* x)
|
||||
{
|
||||
return *x;
|
||||
}
|
||||
|
||||
int
|
||||
test_01 (volatile short* x)
|
||||
{
|
||||
return *x;
|
||||
}
|
||||
|
||||
int
|
||||
test_02 (volatile unsigned char* x)
|
||||
{
|
||||
return *x == 0x80;
|
||||
}
|
||||
|
||||
int
|
||||
test_03 (volatile unsigned short* x)
|
||||
{
|
||||
return *x == 0xFF80;
|
||||
}
|
59
gcc/testsuite/gcc.target/sh/pr52483-2.c
Normal file
59
gcc/testsuite/gcc.target/sh/pr52483-2.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Check that loads from volatile mems utilize displacement addressing
|
||||
modes and do not result in redundant sign 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-not "exts" } } */
|
||||
|
||||
int
|
||||
test_00 (volatile char* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
int
|
||||
test_01 (volatile short* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
int
|
||||
test_02 (volatile int* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
long long
|
||||
test_03 (volatile long long* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
test_04 (volatile unsigned char* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
test_05 (volatile unsigned short* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
test_06 (volatile unsigned int* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
||||
|
||||
unsigned long long
|
||||
test_07 (volatile unsigned long long* x)
|
||||
{
|
||||
return x[5];
|
||||
}
|
25
gcc/testsuite/gcc.target/sh/pr52483-3.c
Normal file
25
gcc/testsuite/gcc.target/sh/pr52483-3.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* Check that loads from volatile mems utilize indexed addressing
|
||||
modes and do not result in redundant sign 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" } } */
|
||||
|
||||
int
|
||||
test_00 (volatile char* x, unsigned int y)
|
||||
{
|
||||
return x[y];
|
||||
}
|
||||
|
||||
int
|
||||
test_01 (volatile short* x, unsigned int y)
|
||||
{
|
||||
return x[y];
|
||||
}
|
||||
|
||||
int
|
||||
test_02 (volatile int* x, unsigned int y)
|
||||
{
|
||||
return x[y];
|
||||
}
|
12
gcc/testsuite/gcc.target/sh/pr52483-4.c
Normal file
12
gcc/testsuite/gcc.target/sh/pr52483-4.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* Check that loads from 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 } } */
|
||||
|
||||
float
|
||||
test_00 (volatile float* x, unsigned int y)
|
||||
{
|
||||
return x[y];
|
||||
}
|
28
gcc/testsuite/gcc.target/sh/pr52483-5.c
Normal file
28
gcc/testsuite/gcc.target/sh/pr52483-5.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* Check that loads from volatile mems utilize post-increment addressing
|
||||
modes and do not result in redundant sign extensions. */
|
||||
/* { dg-do compile { target "sh*-*-*" } } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
|
||||
/* { dg-final { scan-assembler-times "@r\[0-9\]\+\\+," 3 } } */
|
||||
/* { dg-final { scan-assembler-not "exts" } } */
|
||||
|
||||
volatile char*
|
||||
test_00 (volatile char* x)
|
||||
{
|
||||
int xx = *x++;
|
||||
return x;
|
||||
}
|
||||
|
||||
volatile short*
|
||||
test_01 (volatile short* x)
|
||||
{
|
||||
int xx = *x++;
|
||||
return x;
|
||||
}
|
||||
|
||||
volatile int*
|
||||
test_02 (volatile int* x)
|
||||
{
|
||||
int xx = *x++;
|
||||
return x;
|
||||
}
|
Loading…
Add table
Reference in a new issue