diff options
author | Robin Dapp <rdapp.gcc@gmail.com> | 2024-01-15 16:23:30 +0100 |
---|---|---|
committer | Robin Dapp <rdapp@ventanamicro.com> | 2024-01-25 16:21:33 +0100 |
commit | 660e17f00658b68115282e6de38243e3c6cc1ee2 (patch) | |
tree | 6491681b5a30963c0734c1e181fd8424735c849c /gcc/fold-const.cc | |
parent | 90880e117aa70a5ecd9b7df4381410c2ea0dcfdb (diff) | |
download | gcc-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.cc | 31 |
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)), |