diff options
author | Jeff Law <law@redhat.com> | 2016-11-18 14:52:32 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2016-11-18 14:52:32 -0700 |
commit | 57d7fe867cfc59db8481dfe0f8646f029889ef3f (patch) | |
tree | 9985d818e7b6cf2ddc5531b04e2a1537e4997fd1 | |
parent | 0bdc4c1ce9470d4b5b926d2d62ba3ed243775d9e (diff) | |
download | gcc-57d7fe867cfc59db8481dfe0f8646f029889ef3f.zip gcc-57d7fe867cfc59db8481dfe0f8646f029889ef3f.tar.gz gcc-57d7fe867cfc59db8481dfe0f8646f029889ef3f.tar.bz2 |
re PR target/25112 ([m68k] Suboptimal equality comparisons with small integers)
PR target/25112
* config/m68k/m68k.c (moveq feeding equality comparison): New
peepholes.
* config/m68k/predicates.md (addq_subq_operand): New predicate.
(equality_comparison_operator): Likewise.
PR target/25112
* gcc.target/m68k/pr25112: New test.
From-SVN: r242605
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.md | 40 | ||||
-rw-r--r-- | gcc/config/m68k/predicates.md | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/m68k/pr25112.c | 26 |
5 files changed, 91 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff3da21..534ef4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-11-18 Jeff Law <law@redhat.com> + + PR target/25112 + * config/m68k/m68k.c (moveq feeding equality comparison): New + peepholes. + * config/m68k/predicates.md (addq_subq_operand): New predicate. + (equality_comparison_operator): Likewise. + 2016-11-18 Richard Sandiford <richard.sandiford@arm.com> * rtlanal.c (load_extend_op): Move to... diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 3d7895d..7b7f373 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -7641,6 +7641,46 @@ (const_int 0))] "operands[5] = (operands[0] == operands[3]) ? operands[4] : operands[3];") +;; We want to turn +;; moveq const,dX +;; cmp.l dX,dY +;; je/jne +;; +;; into +;; addq/subq -const,dY +;; cmp.l dY, 0 +;; je/jne +;; +;; dX and dY must both be dead at the end of the sequence and the constant +;; must be valid for addq/subq. +;; +;; Essentially we're making it trivial for final to realize the comparison +;; is not needed +;; +;; Testing has shown a variant where the operands are reversed in the +;; comparison never hits, so I have not included that variant. +;; + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "addq_subq_operand" "")) + (set (cc0) (compare (match_operand:SI 2 "register_operand" "") + (match_dup 0))) + (set (pc) (if_then_else (match_operator 5 "equality_comparison_operator" + [(cc0) (const_int 0)]) + (match_operand 3 "pc_or_label_operand") + (match_operand 4 "pc_or_label_operand")))] + "peep2_reg_dead_p (2, operands[0]) + && peep2_reg_dead_p (2, operands[2]) + && (operands[3] == pc_rtx || operands[4] == pc_rtx) + && DATA_REG_P (operands[2])" + [(set (match_dup 2) (plus:SI (match_dup 2) (match_dup 6))) + (set (cc0) (compare (match_dup 2) (const_int 0))) + (set (pc) (if_then_else (match_op_dup 5 [(cc0) (const_int 0)]) + (match_dup 3) + (match_dup 4)))] + "operands[6] = GEN_INT (-INTVAL (operands[1]));") + (define_peephole2 [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "pow2_m1_operand" "")) diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md index 186436c..bfb548a 100644 --- a/gcc/config/m68k/predicates.md +++ b/gcc/config/m68k/predicates.md @@ -245,6 +245,18 @@ || reload_completed)); }) +;; Used to detect constants that are valid for addq/subq instructions +(define_predicate "addq_subq_operand" + (match_code "const_int") +{ + return ((INTVAL (op) <= 8 && INTVAL (op) > 0) + || (INTVAL (op) >= -8 && INTVAL (op) < 0)); +}) + +;; Used to detect equality and non-equality operators +(define_predicate "equality_comparison_operator" + (match_code "eq,ne")) + ;; Used to detect when an operand is either a register ;; or a constant that is all ones in its lower bits. ;; Used by insv pattern to help detect when we're initializing diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6b70fa..729c2e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-18 Jeff Law <law@redhat.com> + + PR target/25112 + * gcc.target/m68k/pr25112: New test. + 2016-11-18 David Edelsohn <dje.gcc@gmail.com> * gcc.dg/tree-ssa/pr71179.c: Prune ABI message. diff --git a/gcc/testsuite/gcc.target/m68k/pr25112.c b/gcc/testsuite/gcc.target/m68k/pr25112.c new file mode 100644 index 0000000..0633cc1 --- /dev/null +++ b/gcc/testsuite/gcc.target/m68k/pr25112.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-times "addq" 16 } } */ +/* { dg-final { scan-assembler-times "subq" 16 } } */ +/* { dg-final { scan-assembler-times "moveq" 4 } } */ +extern int bar (void); + +#define FOO(x) \ + void foo##x (void) { int a = bar (); if (a == x) bar (); } \ + void bar##x (void) { int a = bar (); if (a == -x) bar (); } \ + void foon##x (void) { int a = bar (); if (a != x) bar (); } \ + void barn##x (void) { int a = bar (); if (a != -x) bar (); } \ + + +FOO (1) +FOO (2) +FOO (3) +FOO (4) +FOO (5) +FOO (6) +FOO (7) +FOO (8) +FOO (9) + + |