aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2012-10-30 09:07:08 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2012-10-30 09:07:08 +0000
commit197ddd06a0f70f89b2ffc376592d4e9318a9596a (patch)
treeeaa935a8ef9ba701ffd47ed7e9e919c6ac16819e /gcc
parent3a8ebb9268a572b1cba79373ac0fdafeef607fa4 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/sh/iterators.md3
-rw-r--r--gcc/config/sh/sh.md30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/pr53988.c74
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;
+}