]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/54988
authorolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Oct 2012 09:07:08 +0000 (09:07 +0000)
committerolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Oct 2012 09:07:08 +0000 (09:07 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192982 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/iterators.md
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr53988.c [new file with mode: 0644]

index 35acd1eb678a1e4a2f9d1461f914e9b28774c451..a6fcec3a2e52c09a71ffd0275f795163450985c2 100644 (file)
@@ -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.
index e118c3ef1cd5718136021d2e58674c1c228b9995..c68c37eed2d5f2143c39d188c72a0fd19afee594 100644 (file)
@@ -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")])
index d875a63961a3db8a34a5860864e2f1a382303e95..d9843228ff5a9c8548d4efad75ebb42ab7c221c2 100644 (file)
 ;; 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)
index 627d80ddb376104f49bcee704a8f050ffbd970d2..7acc07a7533e1d68b7181ad3ca395ee0b3794292 100644 (file)
@@ -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 (file)
index 0000000..4bade1e
--- /dev/null
@@ -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;
+}