Commit 0bcf9a09 by Oleg Endo

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
parent 97db2bf7
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);
})
......
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.
......
/* 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;
}
/* 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];
}
/* 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];
}
/* 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];
}
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment