I gave it another shot now by introducing a separate function as
Richard suggested.  It's probably not at the location he intended.

The way I read the discussion there hasn't been any consensus
on how (or rather where) to properly tackle the problem.  Any
other ideas still?

Regards
 Robin


Found in PR112971 this patch adds folding support for bitwise operations
of const duplicate zero/one vectors with stepped vectors.
On riscv we have the situation that a folding would perpetually continue
without simplifying because e.g. {0, 0, 0, ...} & {7, 6, 5, ...} would
not be folded to {0, 0, 0, ...}.

gcc/ChangeLog:

        PR middle-end/112971

        * fold-const.cc (simplify_const_binop): New function for binop
        simplification of two constant vectors when element-wise
        handling is not necessary.
        (const_binop): Call new function.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/pr112971.c: New test.
---
 gcc/fold-const.cc                             | 31 +++++++++++++++++++
 .../gcc.target/riscv/rvv/autovec/pr112971.c   | 18 +++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112971.c

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 385e4a69ab3..2ef425aec0f 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -1343,6 +1343,29 @@ distributes_over_addition_p (tree_code op, int opno)
     }
 }
 
+/* OP is the INDEXth operand to CODE (counting from zero) and OTHER_OP
+   is the other operand.  Try to use the value of OP to simplify the
+   operation in one step, without having to process individual elements.  */
+static tree
+simplify_const_binop (tree_code code, tree op, tree other_op,
+                     int index ATTRIBUTE_UNUSED)
+{
+  /* AND, IOR as well as XOR with a zerop can be simplified directly.  */
+  if (TREE_CODE (op) == VECTOR_CST && TREE_CODE (other_op) == VECTOR_CST)
+    {
+      if (integer_zerop (other_op))
+       {
+         if (code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
+           return op;
+         else if (code == BIT_AND_EXPR)
+           return other_op;
+       }
+    }
+
+  return NULL_TREE;
+}
+
+
 /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
    constant.  We assume ARG1 and ARG2 have the same data type, or at least
    are the same kind of constant and the same machine mode.  Return zero if
@@ -1646,6 +1669,14 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
        return build_complex (type, real, imag);
     }
 
+  tree simplified;
+  if ((simplified = simplify_const_binop (code, arg1, arg2, 0)))
+    return simplified;
+
+  if (commutative_tree_code (code)
+      && (simplified = simplify_const_binop (code, arg2, arg1, 1)))
+    return simplified;
+
   if (TREE_CODE (arg1) == VECTOR_CST
       && TREE_CODE (arg2) == VECTOR_CST
       && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)),
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112971.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112971.c
new file mode 100644
index 00000000000..816ebd3c493
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112971.c
@@ -0,0 +1,18 @@
+/* { dg-do compile }  */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -fno-vect-cost-model" 
}  */
+
+int a;
+short b[9];
+char c, d;
+void e() {
+  d = 0;
+  for (;; d++) {
+    if (b[d])
+      break;
+    a = 8;
+    for (; a >= 0; a--) {
+      char *f = &c;
+      *f &= d == (a & d);
+    }
+  }
+}
-- 
2.43.0


Reply via email to