From 32c4227cfb4980611c8954d4553e9d0f9ca77ee1 Mon Sep 17 00:00:00 2001
From: Jennifer Schmitz <jschmitz@nvidia.com>
Date: Thu, 3 Oct 2024 04:46:51 -0700
Subject: [PATCH] [PR116831] match.pd: Check trunc_mod vector obtap before
 folding.

As in https://gcc.gnu.org/pipermail/gcc-patches/2024-September/663185.html,
this patch guards the simplification x / y * y == x -> x % y == 0 in
match.pd for vector types by a check for:
1) Support of the mod optab for vectors OR
2) Application before vector lowering for non-VL vectors.

The patch was bootstrapped and tested with no regression on
aarch64-linux-gnu and x86_64-linux-gnu.
OK for mainline?

Signed-off-by: Jennifer Schmitz <jschmitz@nvidia.com>

gcc/
	PR tree-optimization/116831
	* match.pd: Guard simplification to trunc_mod with check for
	mod optab support.

gcc/testsuite/
	PR tree-optimization/116831
	* gcc.dg/torture/pr116831.c: New test.
---
 gcc/match.pd                            |  7 ++++++-
 gcc/testsuite/gcc.dg/torture/pr116831.c | 10 ++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr116831.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ba83f0f29e6..89514e9767b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5380,7 +5380,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* x / y * y == x -> x % y == 0.  */
 (simplify
   (eq:c (mult:c (trunc_div:s @0 @1) @1) @0)
-  (if (TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE)
+  (if (TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE
+       || (VECTOR_INTEGER_TYPE_P (type)
+	   && ((optimize_vectors_before_lowering_p ()
+	        && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+	       || target_supports_op_p (type, TRUNC_MOD_EXPR,
+					optab_vector))))
     (eq (trunc_mod @0 @1) { build_zero_cst (TREE_TYPE (@0)); })))
 
 /* ((X /[ex] A) +- B) * A  -->  X +- A * B.  */
diff --git a/gcc/testsuite/gcc.dg/torture/pr116831.c b/gcc/testsuite/gcc.dg/torture/pr116831.c
new file mode 100644
index 00000000000..92b2a130e69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr116831.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-mcpu=neoverse-v2" { target aarch64*-*-* } } */
+
+long a;
+int b, c;
+void d (int e[][5], short f[][5][5][5]) 
+{
+  for (short g; g; g += 4)
+    a = c ?: e[6][0] % b ? 0 : f[0][0][0][g];
+}
+
-- 
2.44.0

