diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2012-10-30 09:07:08 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2012-10-30 09:07:08 +0000 |
commit | 197ddd06a0f70f89b2ffc376592d4e9318a9596a (patch) | |
tree | eaa935a8ef9ba701ffd47ed7e9e919c6ac16819e /gcc | |
parent | 3a8ebb9268a572b1cba79373ac0fdafeef607fa4 (diff) | |
download | gcc-197ddd06a0f70f89b2ffc376592d4e9318a9596a.zip gcc-197ddd06a0f70f89b2ffc376592d4e9318a9596a.tar.gz gcc-197ddd06a0f70f89b2ffc376592d4e9318a9596a.tar.bz2 |
re PR c++/54988 (fpmath=sse target pragma causes inlining failure because of target specific option mismatch)
PR target/54988
* config/sh/sh.md (tstqi_t_zero): Rename to *tstqi_t_zero.
(*tst<mode>_t_zero): New insns.
* config/sh/iterators.md (lowpart_be, lowpart_le): New mode attributes.
PR target/54988
* gcc.target/sh/pr53988.c: New.
From-SVN: r192982
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sh/iterators.md | 3 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr53988.c | 74 |
5 files changed, 117 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 35acd1e..a6fcec3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-10-30 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/54988 + * config/sh/sh.md (tstqi_t_zero): Rename to *tstqi_t_zero. + (*tst<mode>_t_zero): New insns. + * config/sh/iterators.md (lowpart_be, lowpart_le): New mode attributes. + 2012-10-30 H.J. Lu <hongjiu.lu@intel.com> * gimple-pretty-print.c (dump_gimple_bb_header): Avoid alloca. diff --git a/gcc/config/sh/iterators.md b/gcc/config/sh/iterators.md index e118c3e..c68c37e 100644 --- a/gcc/config/sh/iterators.md +++ b/gcc/config/sh/iterators.md @@ -38,3 +38,6 @@ ;; Return codes. (define_code_iterator any_return [return simple_return]) +;; Lowpart subreg byte position code attributes for big and little endian. +(define_mode_attr lowpart_be [(QI "3") (HI "2")]) +(define_mode_attr lowpart_le [(QI "0") (HI "0")]) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index d875a63..d984322 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -633,13 +633,39 @@ ;; Test low QI subreg against zero. ;; This avoids unnecessary zero extension before the test. -(define_insn "tstqi_t_zero" +(define_insn "*tstqi_t_zero" [(set (reg:SI T_REG) (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))] "TARGET_SH1" "tst #255,%0" [(set_attr "type" "mt_group")]) +;; This pattern might be risky because it also tests the upper bits and not +;; only the subreg. However, it seems that combine will get to this only +;; when testing sign/zero extended values. In this case the extended upper +;; bits do not matter. +(define_insn "*tst<mode>_t_zero" + [(set (reg:SI T_REG) + (eq:SI + (subreg:QIHI + (and:SI (match_operand:SI 0 "arith_reg_operand" "%r") + (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>) + (const_int 0)))] + "TARGET_SH1 && TARGET_LITTLE_ENDIAN" + "tst %0,%1" + [(set_attr "type" "mt_group")]) + +(define_insn "*tst<mode>_t_zero" + [(set (reg:SI T_REG) + (eq:SI + (subreg:QIHI + (and:SI (match_operand:SI 0 "arith_reg_operand" "%r") + (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>) + (const_int 0)))] + "TARGET_SH1 && !TARGET_LITTLE_ENDIAN" + "tst %0,%1" + [(set_attr "type" "mt_group")]) + ;; Extract LSB, negate and store in T bit. (define_insn "tstsi_t_and_not" @@ -3514,7 +3540,7 @@ label: /* If it is possible to turn the and insn into a zero extension already, redundant zero extensions will be folded, which results in better code. - Ideally the splitter of *andsi_compact would be enough, if reundant + Ideally the splitter of *andsi_compact would be enough, if redundant zero extensions were detected after the combine pass, which does not happen at the moment. */ if (TARGET_SH1) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 627d80d..7acc07a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-10-30 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/54988 + * gcc.target/sh/pr53988.c: New. + 2012-10-30 Bin Cheng <bin.cheng@arm.com> PR target/54989 diff --git a/gcc/testsuite/gcc.target/sh/pr53988.c b/gcc/testsuite/gcc.target/sh/pr53988.c new file mode 100644 index 0000000..4bade1e --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr53988.c @@ -0,0 +1,74 @@ +/* Check that the tst Rm,Rn instruction is generated for QImode and HImode + values loaded from memory. If everything goes as expected we won't see + any sign/zero extensions or and ops. On SH2A we don't expect to see the + movu insn. */ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "tst\tr" 8 } } */ +/* { dg-final { scan-assembler-not "tst\t#255" } } */ +/* { dg-final { scan-assembler-not "exts|extu|and|movu" } } */ + +int +test00 (char* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test01 (unsigned char* a, unsigned char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test02 (short* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test03 (unsigned short* a, unsigned short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test04 (char* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test05 (short* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test06 (int* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test07 (int* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} |