From 2c2789d582f8fcafd9ef46a22dcb5ca08c5eecd8 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Thu, 27 Jul 2017 16:29:31 +0000 Subject: [PATCH] [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 Sudakshina Das * config/aarch64/aarch64.md (define_split for and3nr_compare): Move non aarch64_logical_operand to a register. (define_split for and_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 Sudakshina Das * gcc.target/aarch64/tst_imm_split_1.c: New Test. Co-Authored-By: Sudakshina Das From-SVN: r250631 --- gcc/ChangeLog | 10 ++++++ gcc/config/aarch64/aarch64.md | 36 +++++++++++++++++++ gcc/config/aarch64/predicates.md | 4 +++ gcc/testsuite/ChangeLog | 5 +++ .../gcc.target/aarch64/tst_imm_split_1.c | 18 ++++++++++ 5 files changed, 73 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c 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 + Sudakshina Das + + * config/aarch64/aarch64.md + (define_split for and3nr_compare): Move + non aarch64_logical_operand to a register. + (define_split for and_3nr_compare0): Move non + register immediate operand to a register. + * config/aarch64/predicates.md (aarch64_mov_imm_operand): New. + 2017-07-27 Peter Bergner 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 "*and3nr_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_")) + (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 + Sudakshina Das + + * gcc.target/aarch64/tst_imm_split_1.c: New Test. + 2017-07-27 Marek Polacek 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" } } */ -- 2.30.2