re PR target/25128 ([m68k] Suboptimal comparisons against 65536)
authorJeff Law <law@redhat.com>
Mon, 21 Nov 2016 18:19:12 +0000 (11:19 -0700)
committerJeff Law <law@gcc.gnu.org>
Mon, 21 Nov 2016 18:19:12 +0000 (11:19 -0700)
PR target/25128
* config/m68k/predicates.md (swap_peephole_relational_operator): New
predicate.
* config/m68k/m68k.md (relational tests against 65535/65536): New
peephole2.

PR target/25128
* gcc.target/m68k/pr25128.c: New test.

From-SVN: r242676

gcc/ChangeLog
gcc/config/m68k/m68k.md
gcc/config/m68k/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/m68k/pr25128.c [new file with mode: 0644]

index b30319eb664e7598e5744b40f2a4400b85c0db41..d546162cc64061abfa8a0ae3fdf5a36bf8182d67 100644 (file)
@@ -1,3 +1,11 @@
+2016-11-20  Jeff Law  <law@redhat.com>
+
+       PR target/25128
+       * config/m68k/predicates.md (swap_peephole_relational_operator): New
+       predicate.
+       * config/m68k/m68k.md (relational tests against 65535/65536): New
+       peephole2.
+
 2016-11-21  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * tree-ssa-loop-prefetch.c: Delete FIXME after the includes.
index 208561996e774fa365cea5f1d019236efd63d17a..c6130f123862c50059ce6cc631f6b1ef8c35eaae 100644 (file)
   operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
   operands[7] = operands[2];
 }")
-
 (define_peephole2
   [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
                       (match_operand:SI 1 "pow2_m1_operand" "")))
                           (match_dup 2) (match_dup 3)))]
   "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
 
+;; When optimizing for size or for the original 68000 or 68010, we can
+;; improve some relational tests against 65536 (which get canonicalized
+;; internally against 65535).
+;; The rotate in the output pattern will turn into a swap.
+(define_peephole2
+  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
+                      (const_int 65535)))
+   (set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator"
+                            [(cc0) (const_int 0)])
+                          (match_operand 2 "pc_or_label_operand")
+                          (match_operand 3 "pc_or_label_operand")))]
+  "peep2_reg_dead_p (1, operands[0])
+   && (operands[2] == pc_rtx || operands[3] == pc_rtx)
+   && (optimize_size || TUNE_68000_10)
+   && DATA_REG_P (operands[0])"
+  [(set (match_dup 0) (rotate:SI (match_dup 0) (const_int 16)))
+   (set (cc0) (compare (subreg:HI (match_dup 0) 2) (const_int 0)))
+   (set (pc) (if_then_else (match_op_dup 1 [(cc0) (const_int 0)])
+                          (match_dup 2) (match_dup 3)))]
+  "")
index bfb548ab86ff39b64d219ff7e02fd89cf59d8018..be32ef60db38b4397f478d91a3183feea9f2545d 100644 (file)
 ;; Used to detect (pc) or (label_ref) in some jumping patterns to cut down
 (define_predicate "pc_or_label_operand"
   (match_code "pc,label_ref"))
+
+(define_predicate "swap_peephole_relational_operator"
+  (match_code "gtu,leu,gt,le"))
index 828c941265ea9c40ebcbf3f25d24b04c58545064..7dbfcaa8c30dd9248abf0bfcc2f5da07acff52bd 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-20  Jeff Law  <law@redhat.com>
+
+       PR target/25128
+       * gcc.target/m68k/pr25128.c: New test.
+
 2016-11-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * gcc.dg/tree-ssa/tailcall-7.c: New test.
diff --git a/gcc/testsuite/gcc.target/m68k/pr25128.c b/gcc/testsuite/gcc.target/m68k/pr25128.c
new file mode 100644 (file)
index 0000000..f99f817
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+/* { dg-final { scan-assembler-times "swap" 4 } } */
+/* { dg-final { scan-assembler-times "tst.w" 4 } } */
+/* { dg-final { scan-assembler-not "cmp.l" } } */
+
+
+unsigned int bar (void);
+void
+foo1 (void)
+{
+  unsigned int a = bar ();
+  if (0x10000 <= a)
+    bar ();
+}
+
+
+void
+foo2 (void)
+{
+  unsigned int a = bar ();
+  if (0x10000 > a)
+    bar ();
+}
+
+
+void
+foo3 (void)
+{
+  int a = bar ();
+  if (0x10000 <= a)
+    bar ();
+}
+
+
+void
+foo4 (void)
+{
+  int a = bar ();
+  if (0x10000 > a)
+    bar ();
+}
+
+
+
+
+