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. */
+ /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
+ constant folding if x/y is a constant. */
if ((code == EQ || code == NE)
- && op0code == AND
- && rtx_equal_p (XEXP (op0, 0), op1)
+ && (op0code == AND || op0code == IOR)
&& !side_effects_p (op1)
&& op1 != CONST0_RTX (cmp_mode))
{
- 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));
+ /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
+ (eq/ne (and (not y) x) 0). */
+ if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
+ || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), 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 (cmp_mode));
- }
+ return simplify_gen_relational (code, mode, cmp_mode, lhs,
+ CONST0_RTX (cmp_mode));
+ }
- /* 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)
- && op1 != CONST0_RTX (cmp_mode))
- {
- 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));
+ /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
+ (eq/ne (and (not x) y) 0). */
+ if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
+ || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), 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 (cmp_mode));
+ return simplify_gen_relational (code, mode, cmp_mode, lhs,
+ CONST0_RTX (cmp_mode));
+ }
}
/* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
--- /dev/null
+/* { 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 != 0)
+ abort ();
+
+ x = bics_si_test1 (0xf11f, 0xf00d, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf00d, 0xf11f, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf11f, 0xf00d, 0);
+ if (x != 0)
+ abort ();
+
+ y = bics_di_test1 (0x10001000f00dll, 0x12341000f00dll, 0ll);
+ if (y != 0)
+ abort ();
+
+ y = bics_di_test1 (0x12341000f00dll, 0x10001000f00dll, 0ll);
+ if (y != 0x12341000f00dll)
+ abort ();
+
+ y = bics_di_test2 (0x10001000f00dll, 0x12341000f00dll, 0ll);
+ if (y != 0x12341000f00dll)
+ abort ();
+
+ y = bics_di_test2 (0x12341000f00dll, 0x10001000f00dll, 0ll);
+ if (y != 0)
+ 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 } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+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;
+}
+
+int
+main ()
+{
+ int x;
+ x = bics_si_test1 (0xf00d, 0xf11f, 0);
+ if (x != 0)
+ abort ();
+
+ x = bics_si_test1 (0xf11f, 0xf00d, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf00d, 0xf11f, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf11f, 0xf00d, 0);
+ if (x != 0)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */