aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2013-06-13 21:39:19 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2013-06-13 19:39:19 +0000
commit948a1fd93681cc364caf89dbd6bb7f746d0fa576 (patch)
tree2816dc4e656351349a314a7258c30b28db26aa18 /gcc/fold-const.c
parent0597fb9cc60035f8edc15e5fccbde701cf277931 (diff)
downloadgcc-948a1fd93681cc364caf89dbd6bb7f746d0fa576.zip
gcc-948a1fd93681cc364caf89dbd6bb7f746d0fa576.tar.gz
gcc-948a1fd93681cc364caf89dbd6bb7f746d0fa576.tar.bz2
fold-const.c (negate_expr_p): Handle VECTOR_CST.
2013-06-13 Marc Glisse <marc.glisse@inria.fr> gcc/ * fold-const.c (negate_expr_p): Handle VECTOR_CST. (fold_negate_expr): Likewise. (fold_real_zero_addition_p): Handle vectors. (fold_binary_loc) <PLUS_EXPR, MINUS_EXPR>: Likewise. gcc/testsuite/ * gcc.dg/fold-minus-1.c: New testcase. From-SVN: r200073
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 998948b..a8e5f43 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -421,6 +421,20 @@ negate_expr_p (tree t)
return negate_expr_p (TREE_REALPART (t))
&& negate_expr_p (TREE_IMAGPART (t));
+ case VECTOR_CST:
+ {
+ if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
+ return true;
+
+ int count = TYPE_VECTOR_SUBPARTS (type), i;
+
+ for (i = 0; i < count; i++)
+ if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
+ return false;
+
+ return true;
+ }
+
case COMPLEX_EXPR:
return negate_expr_p (TREE_OPERAND (t, 0))
&& negate_expr_p (TREE_OPERAND (t, 1));
@@ -560,6 +574,21 @@ fold_negate_expr (location_t loc, tree t)
}
break;
+ case VECTOR_CST:
+ {
+ int count = TYPE_VECTOR_SUBPARTS (type), i;
+ tree *elts = XALLOCAVEC (tree, count);
+
+ for (i = 0; i < count; i++)
+ {
+ elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i));
+ if (elts[i] == NULL_TREE)
+ return NULL_TREE;
+ }
+
+ return build_vector (type, elts);
+ }
+
case COMPLEX_EXPR:
if (negate_expr_p (t))
return fold_build2_loc (loc, COMPLEX_EXPR, type,
@@ -6168,9 +6197,12 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
return true;
+ /* In a vector or complex, we would need to check the sign of all zeros. */
+ if (TREE_CODE (addend) != REAL_CST)
+ return false;
+
/* Treat x + -0 as x - 0 and x - -0 as x + 0. */
- if (TREE_CODE (addend) == REAL_CST
- && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
+ if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
negate = !negate;
/* The mode has signed zeros, and we have to honor their sign.
@@ -10161,7 +10193,7 @@ fold_binary_loc (location_t loc,
fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)));
- if (INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
{
/* Convert ~A + 1 to -A. */
if (TREE_CODE (arg0) == BIT_NOT_EXPR
@@ -10179,7 +10211,7 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (tem);
if (operand_equal_p (tem, arg1, 0))
{
- t1 = build_minus_one_cst (type);
+ t1 = build_all_ones_cst (type);
return omit_one_operand_loc (loc, type, t1, arg1);
}
}
@@ -10193,7 +10225,7 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (tem);
if (operand_equal_p (arg0, tem, 0))
{
- t1 = build_minus_one_cst (type);
+ t1 = build_all_ones_cst (type);
return omit_one_operand_loc (loc, type, t1, arg0);
}
}
@@ -10674,8 +10706,6 @@ fold_binary_loc (location_t loc,
TREE_OPERAND (arg1, 0)));
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
- && (FLOAT_TYPE_P (type)
- || INTEGRAL_TYPE_P (type))
&& negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1))
return fold_build2_loc (loc, MINUS_EXPR, type,
@@ -10684,7 +10714,7 @@ fold_binary_loc (location_t loc,
fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)));
/* Convert -A - 1 to ~A. */
- if (INTEGRAL_TYPE_P (type)
+ if (TREE_CODE (type) != COMPLEX_TYPE
&& TREE_CODE (arg0) == NEGATE_EXPR
&& integer_onep (arg1)
&& !TYPE_OVERFLOW_TRAPS (type))
@@ -10693,13 +10723,13 @@ fold_binary_loc (location_t loc,
TREE_OPERAND (arg0, 0)));
/* Convert -1 - A to ~A. */
- if (INTEGRAL_TYPE_P (type)
+ if (TREE_CODE (type) != COMPLEX_TYPE
&& integer_all_onesp (arg0))
return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1);
- /* X - (X / CST) * CST is X % CST. */
- if (INTEGRAL_TYPE_P (type)
+ /* X - (X / Y) * Y is X % Y. */
+ if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
&& TREE_CODE (arg1) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
&& operand_equal_p (arg0,