diff mbox

[PR,target/25128] Improve comparisons against 65536 on m68k

Message ID c141a314-f9ba-bb84-7abc-070b160a6177@redhat.com
State New
Headers show

Commit Message

Jeff Law Nov. 21, 2016, 6:20 p.m. UTC
One more gift to the retro-computing folks.

GCC for the m68k generates poor code for some relational comparisons 
against 65536.  Swapping the upper/lower halves of the register and 
doing a word sized tst is faster on the 68000/68010 and smaller on all 
variants.  This doesn't work for all comparisons against 65536.

Anyway, it's easy to implement, so here we go.  Tested with m68k.md as 
well as by building newlib using a version which unconditionally made 
the transformation when it was valid (the committed version only fires 
with -Os or when tuning for a m68000/m68010.

You might question if any of that testing is worthwhile -- it actually 
found a case where I thought I'd changed the in-progress peephole, but 
had instead changed something totally unrelated causing the compiler to 
hang!

Installing on the trunk.  I'm probably done with m68k hacking for 2016, 
barring problems with the yearly bootstrap.

Jeff
commit bdc7c1bb83d9baa342c0101049f7586330e406da
Author: Jeff Law <law@redhat.com>
Date:   Mon Nov 21 11:18:34 2016 -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.
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b30319e..d546162 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 2085619..c6130f1 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -7786,7 +7786,6 @@ 
   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" "")))
@@ -7804,3 +7803,23 @@ 
 			   (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)))]
+  "")
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index bfb548a..be32ef6 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -279,3 +279,6 @@ 
 ;; 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"))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 828c941..7dbfcaa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f99f817
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr25128.c
@@ -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 ();
+}
+
+
+
+
+