From: Kyrylo Tkachov <[email protected]>
GCC folds:
x / y * y == x
to:
x % y == 0
Apply the same simplification to inequality.
int divisible_by_3 (unsigned int x)
{
return x / 3 * 3 != x;
}
aarch64 -O2:
before:
divisible_by_3:
mov w1, 43691
movk w1, 0xaaaa, lsl 16
umull x1, w0, w1
lsr x1, x1, 33
add w1, w1, w1, lsl 1
cmp w1, w0
cset w0, ne
ret
after:
divisible_by_3:
mov w1, 43691
movk w1, 0xaaaa, lsl 16
mul w0, w0, w1
mov w1, 1431655765
cmp w0, w1
cset w0, hi
ret
Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill
gcc/ChangeLog:
* match.pd (x / y * y == x): Extend to inequality.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/divmul-mod-1.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
---
gcc/match.pd | 9 ++---
gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c | 38 ++++++++++++++++++++
2 files changed, 43 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 877e449d7d8..33eec29f53a 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6036,16 +6036,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(plus:c (mult:c (div @0 @1) @1) (mod @0 @1))
@0))
-/* x / y * y == x -> x % y == 0. */
-(simplify
- (eq:c (mult:c (trunc_div:s @0 @1) @1) @0)
+/* x / y * y == x -> x % y == 0, and likewise for !=. */
+(for cmp (eq ne)
+ (simplify
+ (cmp:c (mult:c (trunc_div:s @0 @1) @1) @0)
(if (TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE
&& (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
|| !target_supports_op_p (TREE_TYPE (@0), TRUNC_DIV_EXPR,
optab_vector)
|| target_supports_op_p (TREE_TYPE (@0), TRUNC_MOD_EXPR,
optab_vector)))
- (eq (trunc_mod @0 @1) { build_zero_cst (TREE_TYPE (@0)); })))
+ (cmp (trunc_mod @0 @1) { build_zero_cst (TREE_TYPE (@0)); }))))
/* ((X /[ex] C1) +- C2) * (C1 * C3) --> (X * C3) +- (C1 * C2 * C3). */
(for op (plus minus)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c b/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
new file mode 100644
index 00000000000..f65a28d2335
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+typedef unsigned int v4ui __attribute__ ((vector_size (16)));
+
+int
+eq (unsigned int a, unsigned int b)
+{
+ return a / b * b == a;
+}
+
+int
+ne (unsigned int a, unsigned int b)
+{
+ return a / b * b != a;
+}
+
+int
+nes (int a, int b)
+{
+ return a / b * b != a;
+}
+
+v4si
+veq (v4ui a, v4ui b)
+{
+ return a / b * b == a;
+}
+
+v4si
+vne (v4ui a, v4ui b)
+{
+ return a / b * b != a;
+}
+
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+/* { dg-final { scan-tree-dump " % " "optimized" } } */
--
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.