From 0bcf9a093e66c073638106a1113472f4ba4cf03b Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Sun, 23 Jun 2013 08:39:55 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++ gcc/config/sh/predicates.md | 42 ++++++++++++++---- gcc/testsuite/ChangeLog | 9 ++++ gcc/testsuite/gcc.target/sh/pr52483-1.c | 30 +++++++++++++ gcc/testsuite/gcc.target/sh/pr52483-2.c | 59 +++++++++++++++++++++++++ gcc/testsuite/gcc.target/sh/pr52483-3.c | 25 +++++++++++ gcc/testsuite/gcc.target/sh/pr52483-4.c | 12 +++++ gcc/testsuite/gcc.target/sh/pr52483-5.c | 28 ++++++++++++ 8 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/sh/pr52483-1.c create mode 100644 gcc/testsuite/gcc.target/sh/pr52483-2.c create mode 100644 gcc/testsuite/gcc.target/sh/pr52483-3.c create mode 100644 gcc/testsuite/gcc.target/sh/pr52483-4.c create mode 100644 gcc/testsuite/gcc.target/sh/pr52483-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b84d379e55c..3291a1adebf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-06-23 Oleg Endo + + 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 * config/i386/i386.c (ix86_pragma_target_parse): Restore target diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 25949c62d23..998ba7300ad 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -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); }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3473c697e8e..06e6847c266 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2013-06-23 Oleg Endo + + 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 * testsuite/gcc.target/i386/intrinsics_1.c: New test. diff --git a/gcc/testsuite/gcc.target/sh/pr52483-1.c b/gcc/testsuite/gcc.target/sh/pr52483-1.c new file mode 100644 index 00000000000..6538a0570b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr52483-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/sh/pr52483-2.c b/gcc/testsuite/gcc.target/sh/pr52483-2.c new file mode 100644 index 00000000000..5681039db4d --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr52483-2.c @@ -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]; +} diff --git a/gcc/testsuite/gcc.target/sh/pr52483-3.c b/gcc/testsuite/gcc.target/sh/pr52483-3.c new file mode 100644 index 00000000000..4d04193eb45 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr52483-3.c @@ -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]; +} diff --git a/gcc/testsuite/gcc.target/sh/pr52483-4.c b/gcc/testsuite/gcc.target/sh/pr52483-4.c new file mode 100644 index 00000000000..8bf8626f148 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr52483-4.c @@ -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]; +} diff --git a/gcc/testsuite/gcc.target/sh/pr52483-5.c b/gcc/testsuite/gcc.target/sh/pr52483-5.c new file mode 100644 index 00000000000..fd106456020 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr52483-5.c @@ -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; +}