aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-08-21 11:22:14 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2007-08-21 11:22:14 +0200
commitc01ee93565332d96080cdfecaa32827d0c7fa623 (patch)
treee69367431695e71d8953aafa59574d63eb548731 /gcc/fold-const.c
parentf7d1e0c6cb12146eaddeac1386e1a5b9394f5955 (diff)
downloadgcc-c01ee93565332d96080cdfecaa32827d0c7fa623.zip
gcc-c01ee93565332d96080cdfecaa32827d0c7fa623.tar.gz
gcc-c01ee93565332d96080cdfecaa32827d0c7fa623.tar.bz2
re PR middle-end/32912 (ICE with vector code)
PR middle-end/32912 * fold-const.c (fold_unary): Optimize BIT_NOT_EXPR of VECTOR_CST. (fold_binary): Handle vectors in X | ~X and X ^ ~X optimizations. * gcc.dg/pr32912-1.c: New test. * gcc.dg/pr32912-2.c: New test. * gcc.dg/pr32912-3.c: New test. From-SVN: r127661
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 33467eb..7718759 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8397,6 +8397,29 @@ fold_unary (enum tree_code code, tree type, tree op0)
TREE_OPERAND (arg0, 1)))))
return fold_build2 (BIT_XOR_EXPR, type,
fold_convert (type, TREE_OPERAND (arg0, 0)), tem);
+ /* Perform BIT_NOT_EXPR on each element individually. */
+ else if (TREE_CODE (arg0) == VECTOR_CST)
+ {
+ tree elements = TREE_VECTOR_CST_ELTS (arg0), elem, list = NULL_TREE;
+ int count = TYPE_VECTOR_SUBPARTS (type), i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (elements)
+ {
+ elem = TREE_VALUE (elements);
+ elem = fold_unary (BIT_NOT_EXPR, TREE_TYPE (type), elem);
+ if (elem == NULL_TREE)
+ break;
+ elements = TREE_CHAIN (elements);
+ }
+ else
+ elem = build_int_cst (TREE_TYPE (type), -1);
+ list = tree_cons (NULL_TREE, elem, list);
+ }
+ if (i == count)
+ return build_vector (type, nreverse (list));
+ }
return NULL_TREE;
@@ -10485,7 +10508,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg0) == BIT_NOT_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
{
- t1 = build_int_cst_type (type, -1);
+ t1 = fold_convert (type, integer_zero_node);
+ t1 = fold_unary (BIT_NOT_EXPR, type, t1);
return omit_one_operand (type, t1, arg1);
}
@@ -10493,7 +10517,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg1) == BIT_NOT_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
{
- t1 = build_int_cst_type (type, -1);
+ t1 = fold_convert (type, integer_zero_node);
+ t1 = fold_unary (BIT_NOT_EXPR, type, t1);
return omit_one_operand (type, t1, arg0);
}
@@ -10599,7 +10624,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg0) == BIT_NOT_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
{
- t1 = build_int_cst_type (type, -1);
+ t1 = fold_convert (type, integer_zero_node);
+ t1 = fold_unary (BIT_NOT_EXPR, type, t1);
return omit_one_operand (type, t1, arg1);
}
@@ -10607,7 +10633,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg1) == BIT_NOT_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
{
- t1 = build_int_cst_type (type, -1);
+ t1 = fold_convert (type, integer_zero_node);
+ t1 = fold_unary (BIT_NOT_EXPR, type, t1);
return omit_one_operand (type, t1, arg0);
}