From 1b505641e26f98cb52fee9ce0a729187d68fb3c4 Mon Sep 17 00:00:00 2001 From: collison Date: Wed, 11 Mar 2015 06:26:04 +0000 Subject: 2015-03-10 Michael Collison Backport from trunk r218503. 2014-12-08 Sandra Loosemore * simplify-rtx.c (simplify_relational_operation_1): Handle simplification identities for BICS patterns. 2015-03-10 Michael Collison Backport from trunk r218503. 2014-12-08 Sandra Loosemore * gcc.target/aarch64/bics_4.c: New. 2015-03-10 Michael Collison Backport from trunk r218486. 2014-12-08 Alex Velenko * gcc.target/aarch64/bics_3.c : New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@221344 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.linaro | 10 +++- gcc/config/aarch64/aarch64.md | 26 +++++++++ gcc/simplify-rtx.c | 26 +++++++++ gcc/testsuite/ChangeLog.linaro | 14 +++++ gcc/testsuite/gcc.target/aarch64/bics_3.c | 69 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/bics_4.c | 87 +++++++++++++++++++++++++++++++ 6 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/bics_3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/bics_4.c diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro index fb4e128f9cf..bfc152571f5 100644 --- a/gcc/ChangeLog.linaro +++ b/gcc/ChangeLog.linaro @@ -1,4 +1,12 @@ -2015-03-06 Michael Collison +2015-03-10 Michael Collison + + Backport from trunk r218503. + 2014-12-08 Sandra Loosemore + + * simplify-rtx.c (simplify_relational_operation_1): Handle + simplification identities for BICS patterns. + +2015-03-10 Michael Collison Backport from trunk r220751. 2015-02-17 James Greenhalgh diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 9e3f6a35d51..92df8c61c5e 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2788,6 +2788,18 @@ [(set_attr "type" "logics_reg")] ) +(define_insn "*and_one_cmpl3_compare0_no_reuse" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (not:GPI + (match_operand:GPI 0 "register_operand" "r")) + (match_operand:GPI 1 "register_operand" "r")) + (const_int 0)))] + "" + "bics\\tzr, %1, %0" + [(set_attr "type" "logics_reg")] +) + (define_insn "*_one_cmpl_3" [(set (match_operand:GPI 0 "register_operand" "=r") (LOGICAL:GPI (not:GPI @@ -2837,6 +2849,20 @@ [(set_attr "type" "logics_shift_imm")] ) +(define_insn "*and_one_cmpl_3_compare0_no_reuse" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ + (and:GPI (not:GPI + (SHIFT:GPI + (match_operand:GPI 0 "register_operand" "r") + (match_operand:QI 1 "aarch64_shift_imm_" "n"))) + (match_operand:GPI 2 "register_operand" "r")) + (const_int 0)))] + "" + "bics\\tzr, %2, %0, %1" + [(set_attr "type" "logics_shift_imm")] +) + (define_insn "clz2" [(set (match_operand:GPI 0 "register_operand" "=r") (clz:GPI (match_operand:GPI 1 "register_operand" "r")))] diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index d5dade6903f..948a79600f3 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -4878,6 +4878,32 @@ simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode, simplify_gen_binary (XOR, cmp_mode, XEXP (op0, 1), op1)); + /* (eq/ne (and x y) x) simplifies to (eq/ne (and (not y) x) 0), which + can be implemented with a BICS instruction on some targets, or + constant-folded if y is a constant. */ + if ((code == EQ || code == NE) + && op0code == AND + && rtx_equal_p (XEXP (op0, 0), op1) + && !side_effects_p (op1)) + { + rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1), cmp_mode); + rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0)); + + return simplify_gen_relational (code, mode, cmp_mode, lhs, const0_rtx); + } + + /* Likewise for (eq/ne (and x y) y). */ + if ((code == EQ || code == NE) + && op0code == AND + && rtx_equal_p (XEXP (op0, 1), op1) + && !side_effects_p (op1)) + { + rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0), cmp_mode); + rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1)); + + return simplify_gen_relational (code, mode, cmp_mode, lhs, const0_rtx); + } + /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */ if ((code == EQ || code == NE) && GET_CODE (op0) == BSWAP diff --git a/gcc/testsuite/ChangeLog.linaro b/gcc/testsuite/ChangeLog.linaro index f7c2cb0d2af..69c16a2cf66 100644 --- a/gcc/testsuite/ChangeLog.linaro +++ b/gcc/testsuite/ChangeLog.linaro @@ -1,3 +1,17 @@ +2015-03-10 Michael Collison + + Backport from trunk r218503. + 2014-12-08 Sandra Loosemore + + * gcc.target/aarch64/bics_4.c: New. + +2015-03-10 Michael Collison + + Backport from trunk r218486. + 2014-12-08 Alex Velenko + + * gcc.target/aarch64/bics_3.c : New testcase. + 2015-03-10 Michael Collison Backport from trunk r217938. diff --git a/gcc/testsuite/gcc.target/aarch64/bics_3.c b/gcc/testsuite/gcc.target/aarch64/bics_3.c new file mode 100644 index 00000000000..ecb53e9d8ba --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bics_3.c @@ -0,0 +1,69 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +extern void abort (void); + +int __attribute__ ((noinline)) +bics_si_test (int a, int b) +{ + if (a & ~b) + return 1; + else + return 0; +} + +int __attribute__ ((noinline)) +bics_si_test2 (int a, int b) +{ + if (a & ~ (b << 2)) + return 1; + else + return 0; +} + +typedef long long s64; + +int __attribute__ ((noinline)) +bics_di_test (s64 a, s64 b) +{ + if (a & ~b) + return 1; + else + return 0; +} + +int __attribute__ ((noinline)) +bics_di_test2 (s64 a, s64 b) +{ + if (a & ~(b << 2)) + return 1; + else + return 0; +} + +int +main (void) +{ + int a = 5; + int b = 5; + int c = 20; + s64 d = 5; + s64 e = 5; + s64 f = 20; + if (bics_si_test (a, b)) + abort (); + if (bics_si_test2 (c, b)) + abort (); + if (bics_di_test (d, e)) + abort (); + if (bics_di_test2 (f, e)) + abort (); + return 0; +} + +/* { dg-final { scan-assembler-times "bics\twzr, w\[0-9\]+, w\[0-9\]+" 2 } } */ +/* { dg-final { scan-assembler-times "bics\twzr, w\[0-9\]+, w\[0-9\]+, lsl 2" 1 } } */ +/* { dg-final { scan-assembler-times "bics\txzr, x\[0-9\]+, x\[0-9\]+" 2 } } */ +/* { dg-final { scan-assembler-times "bics\txzr, x\[0-9\]+, x\[0-9\]+, lsl 2" 1 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/bics_4.c b/gcc/testsuite/gcc.target/aarch64/bics_4.c new file mode 100644 index 00000000000..ee82c4f7744 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bics_4.c @@ -0,0 +1,87 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ + +extern void abort (void); + +int +bics_si_test1 (int a, int b, int c) +{ + if ((a & b) == a) + return a; + else + return c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + if ((a & b) == b) + return b; + else + return c; +} + +typedef long long s64; + +s64 +bics_di_test1 (s64 a, s64 b, s64 c) +{ + if ((a & b) == a) + return a; + else + return c; +} + +s64 +bics_di_test2 (s64 a, s64 b, s64 c) +{ + if ((a & b) == b) + return b; + else + return c; +} + +int +main () +{ + int x; + s64 y; + + x = bics_si_test1 (0xf00d, 0xf11f, 0); + if (x != 0xf00d) + abort (); + + x = bics_si_test1 (0xf11f, 0xf00d, 0); + if (x != 0) + abort (); + + x = bics_si_test2 (0xf00d, 0xf11f, 0); + if (x != 0) + abort (); + + x = bics_si_test2 (0xf11f, 0xf00d, 0); + if (x != 0xf00d) + abort (); + + y = bics_di_test1 (0x10001000f00dll, 0x12341000f00dll, 0ll); + if (y != 0x10001000f00dll) + abort (); + + y = bics_di_test1 (0x12341000f00dll, 0x10001000f00dll, 0ll); + if (y != 0) + abort (); + + y = bics_di_test2 (0x10001000f00dll, 0x12341000f00dll, 0ll); + if (y != 0) + abort (); + + y = bics_di_test2 (0x12341000f00dll, 0x10001000f00dll, 0ll); + if (y != 0x10001000f00dll) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler-times "bics\twzr, w\[0-9\]+, w\[0-9\]+" 2 } } */ +/* { dg-final { scan-assembler-times "bics\txzr, x\[0-9\]+, x\[0-9\]+" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ -- cgit v1.2.3