aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcollison <collison@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-11 06:26:04 +0000
committercollison <collison@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-11 06:26:04 +0000
commit9dfbc8343ed2df949769bf4029e64ae16b97ae0f (patch)
tree91ba49988f85f94ff32515d9689e9c387c4f404a
parent7575399afe69865d01f7b8f5e2a07da0d003d623 (diff)
2015-03-10 Michael Collison <michael.collison@linaro.org>
Backport from trunk r218503. 2014-12-08 Sandra Loosemore <sandra@codesourcery.com> * simplify-rtx.c (simplify_relational_operation_1): Handle simplification identities for BICS patterns. 2015-03-10 Michael Collison <michael.collison@linaro.org> Backport from trunk r218503. 2014-12-08 Sandra Loosemore <sandra@codesourcery.com> * gcc.target/aarch64/bics_4.c: New. 2015-03-10 Michael Collison <michael.collison@linaro.org> Backport from trunk r218486. 2014-12-08 Alex Velenko <Alex.Velenko@arm.com> * gcc.target/aarch64/bics_3.c : New testcase. git-svn-id: svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@221344 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.linaro10
-rw-r--r--gcc/config/aarch64/aarch64.md26
-rw-r--r--gcc/simplify-rtx.c26
-rw-r--r--gcc/testsuite/ChangeLog.linaro14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/bics_3.c69
-rw-r--r--gcc/testsuite/gcc.target/aarch64/bics_4.c87
6 files changed, 231 insertions, 1 deletions
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 <michael.collison@linaro.org>
+2015-03-10 Michael Collison <michael.collison@linaro.org>
+
+ Backport from trunk r218503.
+ 2014-12-08 Sandra Loosemore <sandra@codesourcery.com>
+
+ * simplify-rtx.c (simplify_relational_operation_1): Handle
+ simplification identities for BICS patterns.
+
+2015-03-10 Michael Collison <michael.collison@linaro.org>
Backport from trunk r220751.
2015-02-17 James Greenhalgh <james.greenhalgh@arm.com>
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_cmpl<mode>3_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\\t<w>zr, %<w>1, %<w>0"
+ [(set_attr "type" "logics_reg")]
+)
+
(define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>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_<SHIFT:optab><mode>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_<mode>" "n")))
+ (match_operand:GPI 2 "register_operand" "r"))
+ (const_int 0)))]
+ ""
+ "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
+ [(set_attr "type" "logics_shift_imm")]
+)
+
(define_insn "clz<mode>2"
[(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,5 +1,19 @@
2015-03-10 Michael Collison <michael.collison@linaro.org>
+ Backport from trunk r218503.
+ 2014-12-08 Sandra Loosemore <sandra@codesourcery.com>
+
+ * gcc.target/aarch64/bics_4.c: New.
+
+2015-03-10 Michael Collison <michael.collison@linaro.org>
+
+ Backport from trunk r218486.
+ 2014-12-08 Alex Velenko <Alex.Velenko@arm.com>
+
+ * gcc.target/aarch64/bics_3.c : New testcase.
+
+2015-03-10 Michael Collison <michael.collison@linaro.org>
+
Backport from trunk r217938.
2014-11-21 Jiong Wang <jiong.wang@arm.com>
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 } } */