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 <l...@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 --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 <l...@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.tkac...@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 <l...@redhat.com>
+
+ PR target/25128
+ * gcc.target/m68k/pr25128.c: New test.
+
2016-11-21 Richard Sandiford <richard.sandif...@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 ();
+}
+
+
+
+
+