re PR target/67126 ([SH] gcc.target/sh/pr51244-12.c failures)
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 21 Sep 2015 00:17:22 +0000 (00:17 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 21 Sep 2015 00:17:22 +0000 (00:17 +0000)
gcc/
PR target/67126
* config/sh/sh.md (*reg_lsb_t): Emit bld insn on SH2A.
(*mov_t_msb_neg): Rewrite negc pattern.

gcc/testsuite/
PR target/67126
* gcc.target/sh/pr51244-12.c: Adjust testcase.
* gcc.target/sh/pr54236-2.c: Likewise.

From-SVN: r227957

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr51244-12.c
gcc/testsuite/gcc.target/sh/pr54236-2.c

index 9a76fc4e9ea2f403398f5357eb4f217356bbf2db..14d6927de6b384e2ba7e656c29bda3e8949f1f8b 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/67126
+       * config/sh/sh.md (*reg_lsb_t): Emit bld insn on SH2A.
+       (*mov_t_msb_neg): Rewrite negc pattern.
+
 2015-09-20  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_internal_mov_immediate): Cleanup
index 659c4c78b303d7bdead5d660cf364b7cfb912df3..e0fc90368eef9d7f020dc0ef569ebb212cabe4c9 100644 (file)
@@ -4204,7 +4204,7 @@ label:
 ;; Let combine see that we can get the MSB and LSB into the T bit
 ;; via shll and shlr.  This allows it to plug it into insns that can have
 ;; the T bit as an input (e.g. addc).
-;; FIXME: On SH2A use bld #0,Rn instead of shlr to avoid mutating the input.
+;; On SH2A use bld #0,Rn instead of shlr to avoid mutating the input.
 (define_insn_and_split "*reg_lsb_t"
   [(set (reg:SI T_REG)
        (and:SI (match_operand:SI 0 "arith_reg_operand")
@@ -4214,7 +4214,8 @@ label:
   "&& 1"
   [(const_int 0)]
 {
-  emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[0]));
+  emit_insn (TARGET_SH2A ? gen_bldsi_reg (operands[0], const0_rtx)
+                        : gen_shlr (gen_reg_rtx (SImode), operands[0]));
 })
 
 (define_insn_and_split "*reg_msb_t"
@@ -11979,41 +11980,31 @@ label:
   [(set (match_dup 0) (reg:SI T_REG))
    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
 
-;; Use negc to store the T bit in a MSB of a reg in the following way:
-;;     T = 0: 0x80000000 -> reg
-;;     T = 1: 0x7FFFFFFF -> reg
-;; This works because 0 - 0x80000000 = 0x80000000.
+;; 0x7fffffff + T
+;; 0x7fffffff + (1-T) = 0 - 0x80000000 - T
+;;
+;; Notice that 0 - 0x80000000 = 0x80000000.
+
+;; Single bit tests are usually done with zero_extract.  On non-SH2A this
+;; will use a tst-negc sequence.  On SH2A it will use a bld-addc sequence.
+;; The zeroth bit requires a special pattern, otherwise we get a shlr-addc.
+;; This is a special case of the generic treg_set_expr pattern and thus has
+;; to come first or it will never match.
 (define_insn_and_split "*mov_t_msb_neg"
   [(set (match_operand:SI 0 "arith_reg_dest")
-       (minus:SI (const_int -2147483648)  ;; 0x80000000
-                 (match_operand 1 "treg_set_expr")))
+       (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
+                        (const_int 1))
+                (const_int 2147483647)))
    (clobber (reg:SI T_REG))]
-  "TARGET_SH1 && can_create_pseudo_p ()"
+  "TARGET_SH1"
   "#"
-  "&& 1"
-  [(const_int 0)]
-{
-  if (negt_reg_operand (operands[1], VOIDmode))
-    {
-      emit_insn (gen_addc (operands[0],
-                          force_reg (SImode, const0_rtx),
-                          force_reg (SImode, GEN_INT (2147483647))));
-      DONE;
-    }
-
-  sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
-  if (ti.remove_trailing_nott ())
-    emit_insn (gen_addc (operands[0],
-                        force_reg (SImode, const0_rtx),
-                        force_reg (SImode, GEN_INT (2147483647))));
-  else
-    emit_insn (gen_negc (operands[0],
-                        force_reg (SImode, GEN_INT (-2147483648LL))));
-  DONE;
-})
+  "&& can_create_pseudo_p ()"
+  [(parallel [(set (match_dup 0)
+                  (plus:SI (zero_extract:SI (match_dup 1)
+                                            (const_int 1) (const_int 0))
+                           (const_int 2147483647)))
+             (clobber (reg:SI T_REG))])])
 
-;; 0x7fffffff + T
-;; 0x7fffffff + (1-T) = 0 - 0x80000000 - T
 (define_insn_and_split "*mov_t_msb_neg"
   [(set (match_operand:SI 0 "arith_reg_dest")
        (plus:SI (match_operand 1 "treg_set_expr")
index 5fd91c111ceb38f1764c6f38e5caa3b0750c981e..752bac6be3b5d736a5d4f9fc5dbd1e800f6687f5 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-21  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/67126
+       * gcc.target/sh/pr51244-12.c: Adjust testcase.
+       * gcc.target/sh/pr54236-2.c: Likewise.
+
 2015-09-20  Oleg Endo  <olegendo@gcc.gnu.org>
 
        * gcc.target/sh/pr43417.c: Move target independent test to ...
index ae856f8c0ff1e006a33089de174a2185e8c0e5df..027c5ab975ff2e57f1c5909050faa7f0c5be1742 100644 (file)
@@ -4,8 +4,14 @@
 /* { dg-do compile }  */
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
-/* { dg-final { scan-assembler-times "negc" 15 } } */
-/* { dg-final { scan-assembler-times "addc" 3 } } */
+
+/* { dg-final { scan-assembler-times "negc" 15 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "addc" 3 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "negc" 13 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "addc" 5 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld" 2 { target { sh2a } } } } */
+
 /* { dg-final { scan-assembler-not "movrt|#-1|add\t|sub\t|movt" } } */
 
 int
index c72afb929571507b896f0e1f93871490bd95b830..b6c249395665b3d5e78103d502e7b4ee3c1b5ece 100644 (file)
@@ -5,7 +5,6 @@
 /* { dg-options "-O1" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
 /* { dg-final { scan-assembler-times "addc" 36 } } */
-/* { dg-final { scan-assembler-times "shlr" 22 } } */
 /* { dg-final { scan-assembler-times "shll" 14 } } */
 /* { dg-final { scan-assembler-times "add\tr" 12 } } */
 /* { dg-final { scan-assembler-not "movt" } } */
 
 /* { dg-final { scan-assembler-times "bclr\t#0" 1 { target { sh2a } } } } */
 
+/* { dg-final { scan-assembler-times "shlr" 22 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-not "shlr" { target { sh2a } } } } */
+
 int
 test_000 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + (b & 1);
 }
 
 int
 test_001 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + b + (c & 1);
 }
 
 int
 test_002 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + b + c + (d & 1);
 }
 
 int
 test_003 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return (b & 1) + a;
 }
 
 int
 test_004 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + (c & 1) + b;
 }
 
 int
 test_005 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + b + (d & 1) + c;
 }
 
 int
 test_006 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return (c & 1) + a + b;
 }
 
 int
 test_007 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + (d & 1) + b + c;
 }
 
 int
 test_008 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return (d & 1) + a + b + c;
 }
 
 int
 test_009 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + b + (b & 1);
 }
 
 int
 test_010 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + (b & 1) + b;
 }
 
 int
 test_011 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return (b & 1) + a + b;
 }
 
 int
 test_012 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + b + d + (b & 1);
 }
 
 int
 test_013 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + d + (b & 1) + b;
 }
 
 int
 test_014 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return a + (b & 1) + d + b;
 }
 
 int
 test_015 (int a, int c, int b, int d)
 {
-  // 1x shlr, 1x add, 1x addc
+  // 1x shlr/bld, 1x add, 1x addc
   return (b & 1) + a + d + b;
 }
 
@@ -140,42 +142,42 @@ test_016 (int a, int b, int c, int d)
 int
 test_017 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + a + (a & 1);
 }
 
 int
 test_018 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return a + (a & 1) + a;
 }
 
 int
 test_019 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return (a & 1) + a + a;
 }
 
 int
 test_020 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return b + b + (a & 1);
 }
 
 int
 test_021 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return b + (a & 1) + b;
 }
 
 int
 test_022 (int a, int b, int c, int d)
 {
-  // 1x shlr, 1x addc
+  // 1x shlr/bld, 1x addc
   return (a & 1) + b + b;
 }