diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2013-06-13 21:39:19 +0200 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2013-06-13 19:39:19 +0000 |
commit | 948a1fd93681cc364caf89dbd6bb7f746d0fa576 (patch) | |
tree | 2816dc4e656351349a314a7258c30b28db26aa18 /gcc/fold-const.c | |
parent | 0597fb9cc60035f8edc15e5fccbde701cf277931 (diff) | |
download | gcc-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.c | 52 |
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, |