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:
Oleg Endo 2013-06-23 08:39:55 +00:00
parent 97db2bf7fb
commit 0bcf9a093e
8 changed files with 204 additions and 9 deletions

View file

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

View file

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

View file

@ -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.

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

View 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];
}

View 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];
}

View 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];
}

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