[PATCH] match.pd: fold the inequality spelling of divisibility

<[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
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.