diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-26 10:33:36 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-26 10:33:36 +0000 |
commit | a63f89638edc7c3120e52faf6815bfe3e9b270e2 (patch) | |
tree | 61b7552b10852929b89f1cb93878fadffc1885c2 /gcc/fold-const.c | |
parent | 9402409a6bd0d7d1f7358793f768bda3ec8a9574 (diff) | |
parent | 087a99ba8749638f86c111f776ed326b3fbd97c0 (diff) | |
download | gcc-cxx-conversion.tar.gz |
Merged revisions 196607-196608,196611-196614,196625,196629-196634,196636,196639,196645-196647,196649-196650,196654-196659,196666,196669,196671-196675,196682-196683,196694-196695,196697-196698,196700-196701,196704-196706,196709,196721-196748,196750-196751,196753,196755-196758,196762,196764-196765,196767-196771,196773-196779,196781-196784,196788-196792,196795-196797,196799-196800,196804-196807,196810-196814,196821,196823-196825,196828-196829,196831-196832,196834,196841-196842,196847-196853,196855-196856,196858,196860-196861,196864-196866,196868,196870-196872,196874,196876,196878-196879,196882,196884-196890,196896-196897,196899-196902,196954,196956-196961,196964-196965,196970,196977-196978,196981-196983,196989,197002-197005,197007,197011-197012,197016-197019,197021,197023-197025,197029-197034,197036-197042 via svnmerge from cxx-conversion
svn+ssh://gcc.gnu.org/svn/gcc/trunk
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/cxx-conversion@197098 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 26cfc0e83e4..905661cf7e6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2572,13 +2572,14 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) flags &= ~OEP_CONSTANT_ADDRESS_OF; /* Require equal access sizes, and similar pointer types. We can have incomplete types for array references of - variable-sized arrays from the Fortran frontent - though. */ + variable-sized arrays from the Fortran frontend + though. Also verify the types are compatible. */ return ((TYPE_SIZE (TREE_TYPE (arg0)) == TYPE_SIZE (TREE_TYPE (arg1)) || (TYPE_SIZE (TREE_TYPE (arg0)) && TYPE_SIZE (TREE_TYPE (arg1)) && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), TYPE_SIZE (TREE_TYPE (arg1)), flags))) + && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)) && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg0, 1))) == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg1, 1)))) && OP_SAME (0) && OP_SAME (1)); @@ -4632,7 +4633,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, if (comp_code == NE_EXPR) return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); else if (comp_code == EQ_EXPR) - return build_int_cst (type, 0); + return build_zero_cst (type); } /* Try some transformations of A op B ? A : B. @@ -4666,6 +4667,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, /* Avoid these transformations if the COND_EXPR may be used as an lvalue in the C++ front-end. PR c++/19199. */ && (in_gimple_form + || VECTOR_TYPE_P (type) || (strcmp (lang_hooks.name, "GNU C++") != 0 && strcmp (lang_hooks.name, "GNU Objective-C++") != 0) || ! maybe_lvalue_p (arg1) @@ -13898,6 +13900,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, return NULL_TREE; case COND_EXPR: + case VEC_COND_EXPR: /* Pedantic ANSI C says that a conditional expression is never an lvalue, so all simple results must be passed through pedantic_non_lvalue. */ if (TREE_CODE (arg0) == INTEGER_CST) @@ -13915,6 +13918,14 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, return pedantic_non_lvalue_loc (loc, tem); return NULL_TREE; } + else if (TREE_CODE (arg0) == VECTOR_CST) + { + if (integer_all_onesp (arg0)) + return pedantic_omit_one_operand_loc (loc, type, arg1, arg2); + if (integer_zerop (arg0)) + return pedantic_omit_one_operand_loc (loc, type, arg2, arg1); + } + if (operand_equal_p (arg1, op2, 0)) return pedantic_omit_one_operand_loc (loc, type, arg1, arg0); @@ -13950,6 +13961,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, } } + /* ??? Fixup the code below for VEC_COND_EXPR. */ + if (code == VEC_COND_EXPR) + return NULL_TREE; + /* If the second operand is simpler than the third, swap them since that produces better jump optimization results. */ if (truth_value_p (TREE_CODE (arg0)) @@ -14137,16 +14152,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, return NULL_TREE; - case VEC_COND_EXPR: - if (TREE_CODE (arg0) == VECTOR_CST) - { - if (integer_all_onesp (arg0) && !TREE_SIDE_EFFECTS (op2)) - return pedantic_non_lvalue_loc (loc, op1); - if (integer_zerop (arg0) && !TREE_SIDE_EFFECTS (op1)) - return pedantic_non_lvalue_loc (loc, op2); - } - return NULL_TREE; - case CALL_EXPR: /* CALL_EXPRs used to be ternary exprs. Catch any mistaken uses of fold_ternary on them. */ @@ -15293,15 +15298,18 @@ tree_binary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0, break; case MULT_EXPR: - if (FLOAT_TYPE_P (type)) + if (FLOAT_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) { - /* x * x for floating point x is always non-negative. */ - if (operand_equal_p (op0, op1, 0)) - return true; - return (tree_expr_nonnegative_warnv_p (op0, - strict_overflow_p) - && tree_expr_nonnegative_warnv_p (op1, - strict_overflow_p)); + /* x * x is always non-negative for floating point x + or without overflow. */ + if (operand_equal_p (op0, op1, 0) + || (tree_expr_nonnegative_warnv_p (op0, strict_overflow_p) + && tree_expr_nonnegative_warnv_p (op1, strict_overflow_p))) + { + if (TYPE_OVERFLOW_UNDEFINED (type)) + *strict_overflow_p = true; + return true; + } } /* zero_extend(x) * zero_extend(y) is non-negative if x and y are |