diff options
author | jgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-07-27 16:29:31 +0000 |
---|---|---|
committer | jgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-07-27 16:29:31 +0000 |
commit | 6b18f4b7ce64526e01337687da663a7f00eb8227 (patch) | |
tree | 2c0f09817f8455203b1c9380e0f904f72c8cfb9c | |
parent | 7d4d7ecb021f2832d3cea0dd63700ff870f90b4e (diff) | |
download | gcc-6b18f4b7ce64526e01337687da663a7f00eb8227.tar.gz |
[PATCH][AArch64] Fix missing optimization for CMP+AND
During combine GCC tries to merge CMP (with zero) and AND into a TST. However,
in cases where an ANDS operand is not compatible, this was being missed. Adding
a define_split where this operand was moved to a register seems to help out.
Committed on behalf of Sudi Das
---
gcc/
2017-07-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Sudakshina Das <sudi.das@arm.com>
* config/aarch64/aarch64.md
(define_split for and<mode>3nr_compare): Move
non aarch64_logical_operand to a register.
(define_split for and_<SHIFT:optab><mode>3nr_compare0): Move non
register immediate operand to a register.
* config/aarch64/predicates.md (aarch64_mov_imm_operand): New.
gcc/testsuite
2017-07-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Sudakshina Das <sudi.das@arm.com>
* gcc.target/aarch64/tst_imm_split_1.c: New Test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@250631 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 36 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c | 18 |
5 files changed, 73 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05107fd93fc..0b37bae243e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-07-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + Sudakshina Das <sudi.das@arm.com> + + * config/aarch64/aarch64.md + (define_split for and<mode>3nr_compare): Move + non aarch64_logical_operand to a register. + (define_split for and_<SHIFT:optab><mode>3nr_compare0): Move non + register immediate operand to a register. + * config/aarch64/predicates.md (aarch64_mov_imm_operand): New. + 2017-07-27 Peter Bergner <bergner@vnet.ibm.com> PR middle-end/81564 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f876a2b7208..d3e66db1f71 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3835,6 +3835,22 @@ [(set_attr "type" "logics_reg,logics_imm")] ) +(define_split + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (match_operand:GPI 0 "register_operand") + (match_operand:GPI 1 "aarch64_mov_imm_operand")) + (const_int 0))) + (clobber (match_operand:SI 2 "register_operand"))] + "" + [(set (match_dup 2) (match_dup 1)) + (set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (match_dup 0) + (match_dup 2)) + (const_int 0)))] +) + (define_insn "*and<mode>3nr_compare0_zextract" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ @@ -3870,6 +3886,26 @@ [(set_attr "type" "logics_shift_imm")] ) +(define_split + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (SHIFT:GPI + (match_operand:GPI 0 "register_operand") + (match_operand:QI 1 "aarch64_shift_imm_<mode>")) + (match_operand:GPI 2 "aarch64_mov_imm_operand")) + (const_int 0))) + (clobber (match_operand:SI 3 "register_operand"))] + "" + [(set (match_dup 3) (match_dup 2)) + (set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (SHIFT:GPI + (match_dup 0) + (match_dup 1)) + (match_dup 3)) + (const_int 0)))] +) + ;; ------------------------------------------------------------------- ;; Shifts ;; ------------------------------------------------------------------- diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index ad8a43c2b2c..11243c4ce00 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -114,6 +114,10 @@ (ior (match_operand 0 "register_operand") (match_operand 0 "aarch64_logical_immediate"))) +(define_predicate "aarch64_mov_imm_operand" + (and (match_code "const_int") + (match_test "aarch64_move_imm (INTVAL (op), mode)"))) + (define_predicate "aarch64_logical_and_immediate" (and (match_code "const_int") (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)"))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5f964a3d35a..87d3b6fce2f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-07-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + Sudakshina Das <sudi.das@arm.com> + + * gcc.target/aarch64/tst_imm_split_1.c: New Test. + 2017-07-27 Marek Polacek <polacek@redhat.com> PR c/81417 diff --git a/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c b/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c new file mode 100644 index 00000000000..33a2c0f45af --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +f (unsigned char *p) +{ + return p[0] == 50 || p[0] == 52; +} + +int +g (unsigned char *p) +{ + return (p[0] >> 4 & 0xfd) == 0; +} + +/* { dg-final { scan-assembler-not "and\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+.*" } } */ +/* { dg-final { scan-assembler "tst\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+" } } */ +/* { dg-final { scan-assembler "tst\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+, lsr 4" } } */ |