diff options
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a2b7ac18312..a8e5f43faf4 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, @@ -2473,9 +2502,13 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) } if (TREE_CODE (arg0) != TREE_CODE (arg1) - /* This is needed for conversions and for COMPONENT_REF. - Might as well play it safe and always test this. */ - || TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK + /* NOP_EXPR and CONVERT_EXPR are considered equal. */ + && !(CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1))) + return 0; + + /* This is needed for conversions and for COMPONENT_REF. + Might as well play it safe and always test this. */ + if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1))) return 0; @@ -3755,6 +3788,10 @@ simple_operand_p (const_tree exp) #pragma weak, etc). */ && ! TREE_PUBLIC (exp) && ! DECL_EXTERNAL (exp) + /* Weakrefs are not safe to be read, since they can be NULL. + They are !TREE_PUBLIC && !DECL_EXTERNAL but still + have DECL_WEAK flag set. */ + && (! VAR_OR_FUNCTION_DECL_P (exp) || ! DECL_WEAK (exp)) /* Loading a static variable is unduly expensive, but global registers aren't expensive. */ && (! TREE_STATIC (exp) || DECL_REGISTER (exp)))); @@ -6160,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. @@ -10153,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 @@ -10171,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); } } @@ -10185,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); } } @@ -10666,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, @@ -10676,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)) @@ -10685,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, |