]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] [target/25114] Improve comparisons against some small integers for m68k
authorJeff Law <law@redhat.com>
Wed, 20 Jan 2016 07:54:26 +0000 (00:54 -0700)
committerJeff Law <law@gcc.gnu.org>
Wed, 20 Jan 2016 07:54:26 +0000 (00:54 -0700)
* 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

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

index ac6232c8cd25b15b5ac7ef71134d008c63439ed7..764b2092063c648574934b2fc2a6d35edad0bb9e 100644 (file)
@@ -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.
index a56cc9f630f56af72a6e9c891d656c69ce82e305..5731780631f68d4a8f5fa0c905b0b466234e2b4b 100644 (file)
    (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)); }")
+
index 18411d64d760038801d18b4e683001f6f8a15e5d..186436c42b77a64c1774c6018db38428f4641c6b 100644 (file)
 (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"))
index 63baf4e5211e50700755353fb1a004a9849cff3f..dfad960b133dd052f7c37c8670ede7d0c258fc23 100644 (file)
@@ -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 (file)
index 0000000..bb722d9
--- /dev/null
@@ -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)