aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.cc
diff options
context:
space:
mode:
authorRobin Dapp <rdapp.gcc@gmail.com>2024-01-15 16:23:30 +0100
committerRobin Dapp <rdapp@ventanamicro.com>2024-01-25 16:21:33 +0100
commit660e17f00658b68115282e6de38243e3c6cc1ee2 (patch)
tree6491681b5a30963c0734c1e181fd8424735c849c /gcc/fold-const.cc
parent90880e117aa70a5ecd9b7df4381410c2ea0dcfdb (diff)
downloadgcc-660e17f00658b68115282e6de38243e3c6cc1ee2.zip
gcc-660e17f00658b68115282e6de38243e3c6cc1ee2.tar.gz
gcc-660e17f00658b68115282e6de38243e3c6cc1ee2.tar.bz2
fold-const: Handle AND, IOR, XOR with stepped vectors [PR112971].
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.
Diffstat (limited to 'gcc/fold-const.cc')
-rw-r--r--gcc/fold-const.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 1fd9572..80e211e 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)),