aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2016-01-20 00:54:26 -0700
committerJeff Law <law@gcc.gnu.org>2016-01-20 00:54:26 -0700
commitbcff0913882cc6e70f90be3d8448ec0186d21abc (patch)
tree5d9f7b573fc95196488974f89850d1834ebafc87 /gcc
parenta3f69631af2a64405722a526650b96fbcf9a9373 (diff)
downloadgcc-bcff0913882cc6e70f90be3d8448ec0186d21abc.zip
gcc-bcff0913882cc6e70f90be3d8448ec0186d21abc.tar.gz
gcc-bcff0913882cc6e70f90be3d8448ec0186d21abc.tar.bz2
[PATCH] [target/25114] Improve comparisons against some small integers for m68k
* config/m68k/predicates.md (pow2_m1_operand): New predicate extracted from ... (reg_or_pow2_m1_operand): Call pow2_m1_operand. (pc_or_label_operand): New predicate. * config/m68k/m68k.md: Add new peephole2 patterns for GTU/LEU tests for small integers that are 2^n - 1. * gcc.target/m68k/pr25114.c: New test. From-SVN: r232601
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/m68k/m68k.md85
-rw-r--r--gcc/config/m68k/predicates.md16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr25114.c26
5 files changed, 137 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ac6232c..764b209 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2016-01-20 Jeff Law <law@redhat.com>
+
+ * config/m68k/predicates.md (pow2_m1_operand): New predicate
+ extracted from ...
+ (reg_or_pow2_m1_operand): Call pow2_m1_operand.
+ (pc_or_label_operand): New predicate.
+ * config/m68k/m68k.md: Add new peephole2 patterns for GTU/LEU
+ tests for small integers that are 2^n - 1.
+
2016-01-20 Jonathan Wakely <jwakely@redhat.com>
* doc/invoke.texi (Options Summary): Add '.' after @xref.
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index a56cc9f..5731780 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -7634,3 +7634,88 @@
(set (mem:QI (match_dup 5))
(const_int 0))]
"operands[5] = (operands[0] == operands[3]) ? operands[4] : operands[3];")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "pow2_m1_operand" ""))
+ (set (cc0) (compare (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" "")))
+ (set (pc) (if_then_else (gtu (cc0) (const_int 0))
+ (match_operand 4 "pc_or_label_operand")
+ (match_operand 5 "pc_or_label_operand")))]
+ "INTVAL (operands[1]) <= 255
+ && operands[0] == operands[3]
+ && peep2_reg_dead_p (2, operands[0])
+ && peep2_reg_dead_p (2, operands[2])
+ && (operands[4] == pc_rtx || operands[5] == pc_rtx)
+ && (optimize_size || TUNE_68040_60)
+ && DATA_REG_P (operands[2])"
+ [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6)))
+ (set (cc0) (compare (match_dup 7) (const_int 0)))
+ (set (pc) (if_then_else (ne (cc0) (const_int 0))
+ (match_dup 4) (match_dup 5)))]
+ "
+{
+ 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" "")))
+ (set (pc) (if_then_else (gtu (cc0) (const_int 0))
+ (match_operand 2 "pc_or_label_operand")
+ (match_operand 3 "pc_or_label_operand")))]
+ "INTVAL (operands[1]) <= 255
+ && peep2_reg_dead_p (1, operands[0])
+ && (operands[2] == pc_rtx || operands[3] == pc_rtx)
+ && (optimize_size || TUNE_68040_60)
+ && DATA_REG_P (operands[0])"
+ [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4)))
+ (set (cc0) (compare (match_dup 0) (const_int 0)))
+ (set (pc) (if_then_else (ne (cc0) (const_int 0))
+ (match_dup 2) (match_dup 3)))]
+ "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "pow2_m1_operand" ""))
+ (set (cc0) (compare (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" "")))
+ (set (pc) (if_then_else (leu (cc0) (const_int 0))
+ (match_operand 4 "pc_or_label_operand")
+ (match_operand 5 "pc_or_label_operand")))]
+ "INTVAL (operands[1]) <= 255
+ && operands[0] == operands[3]
+ && peep2_reg_dead_p (2, operands[0])
+ && peep2_reg_dead_p (2, operands[2])
+ && (operands[4] == pc_rtx || operands[5] == pc_rtx)
+ && (optimize_size || TUNE_68040_60)
+ && DATA_REG_P (operands[2])"
+ [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6)))
+ (set (cc0) (compare (match_dup 7) (const_int 0)))
+ (set (pc) (if_then_else (eq (cc0) (const_int 0))
+ (match_dup 4) (match_dup 5)))]
+ "
+{
+ 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" "")))
+ (set (pc) (if_then_else (leu (cc0) (const_int 0))
+ (match_operand 2 "pc_or_label_operand")
+ (match_operand 3 "pc_or_label_operand")))]
+ "INTVAL (operands[1]) <= 255
+ && peep2_reg_dead_p (1, operands[0])
+ && (operands[2] == pc_rtx || operands[3] == pc_rtx)
+ && (optimize_size || TUNE_68040_60)
+ && DATA_REG_P (operands[0])"
+ [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4)))
+ (set (cc0) (compare (match_dup 0) (const_int 0)))
+ (set (pc) (if_then_else (eq (cc0) (const_int 0))
+ (match_dup 2) (match_dup 3)))]
+ "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
+
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index 18411d6..186436c 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -253,7 +253,17 @@
(define_predicate "reg_or_pow2_m1_operand"
(match_code "reg,const_int")
{
- return (REG_P (op)
- || (GET_CODE (op) == CONST_INT
- && exact_log2 (INTVAL (op) + 1) >= 0));
+ return (REG_P (op) || pow2_m1_operand (op, VOIDmode));
})
+
+;; Used to detect a constant that is all ones in its lower bits.
+(define_predicate "pow2_m1_operand"
+ (match_code "const_int")
+{
+ return (GET_CODE (op) == CONST_INT && exact_log2 (INTVAL (op) + 1) >= 0);
+})
+
+;; Used to detect valid targets for conditional branches
+;; 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"))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 63baf4e..dfad960 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-01-20 Jeff Law <law@redhat.com>
+
+ * gcc.target/m68k/pr25114.c: New test.
+
2016-01-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gcc.target/arm/memset-inline-10.c: Added
diff --git a/gcc/testsuite/gcc.target/m68k/pr25114.c b/gcc/testsuite/gcc.target/m68k/pr25114.c
new file mode 100644
index 0000000..bb722d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr25114.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -m68040" } */
+/* There should be 16 logical right shift instructions. One for each function*/
+/* { dg-final { scan-assembler-times "lsr" 16 } } */
+
+unsigned int bar (void);
+
+#define F(C) void foo##C (void) { unsigned int a = bar (); if (a <= C) bar (); }
+#define G(C) void foo2##C (void) { unsigned int a = bar (); if (a > C) bar (); }
+
+F(0x1)
+F(0x3)
+F(0x7)
+F(0xf)
+F(0x1f)
+F(0x3f)
+F(0x7f)
+F(0xff)
+G(0x1)
+G(0x3)
+G(0x7)
+G(0xf)
+G(0x1f)
+G(0x3f)
+G(0x7f)
+G(0xff)