diff options
Diffstat (limited to 'gcc-4.4.0/gcc/fold-const.c')
-rw-r--r-- | gcc-4.4.0/gcc/fold-const.c | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/gcc-4.4.0/gcc/fold-const.c b/gcc-4.4.0/gcc/fold-const.c index e38850fd5..623bd61e9 100644 --- a/gcc-4.4.0/gcc/fold-const.c +++ b/gcc-4.4.0/gcc/fold-const.c @@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "md5.h" #include "gimple.h" +#include "tree-flow.h" +#include "tree-flow-inline.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -5265,59 +5267,66 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2) return fold_build3 (COND_EXPR, type, arg0, arg1, arg2); case LT_EXPR: - /* If C1 is C2 + 1, this is min(A, C2). */ + /* If C1 is C2 + 1, this is min(A, C2), but use ARG00's type for + MIN_EXPR, to preserve the signedness of the comparison. */ if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), OEP_ONLY_CONST) && operand_equal_p (arg01, const_binop (PLUS_EXPR, arg2, build_int_cst (type, 1), 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MIN_EXPR, - type, - fold_convert (type, arg1), - arg2)); + { + tem = fold_build2 (MIN_EXPR, TREE_TYPE (arg00), arg00, + fold_convert (TREE_TYPE (arg00), arg2)); + return pedantic_non_lvalue (fold_convert (type, tem)); + } break; case LE_EXPR: - /* If C1 is C2 - 1, this is min(A, C2). */ + /* If C1 is C2 - 1, this is min(A, C2), with the same care + as above. */ if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), OEP_ONLY_CONST) && operand_equal_p (arg01, const_binop (MINUS_EXPR, arg2, build_int_cst (type, 1), 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MIN_EXPR, - type, - fold_convert (type, arg1), - arg2)); + { + tem = fold_build2 (MIN_EXPR, TREE_TYPE (arg00), arg00, + fold_convert (TREE_TYPE (arg00), arg2)); + return pedantic_non_lvalue (fold_convert (type, tem)); + } break; case GT_EXPR: - /* If C1 is C2 - 1, this is max(A, C2). */ + /* If C1 is C2 - 1, this is max(A, C2), but use ARG00's type for + MAX_EXPR, to preserve the signedness of the comparison. */ if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), OEP_ONLY_CONST) && operand_equal_p (arg01, const_binop (MINUS_EXPR, arg2, build_int_cst (type, 1), 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MAX_EXPR, - type, - fold_convert (type, arg1), - arg2)); + { + tem = fold_build2 (MAX_EXPR, TREE_TYPE (arg00), arg00, + fold_convert (TREE_TYPE (arg00), arg2)); + return pedantic_non_lvalue (fold_convert (type, tem)); + } break; case GE_EXPR: - /* If C1 is C2 + 1, this is max(A, C2). */ + /* If C1 is C2 + 1, this is max(A, C2), with the same care as above. */ if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), OEP_ONLY_CONST) && operand_equal_p (arg01, const_binop (PLUS_EXPR, arg2, build_int_cst (type, 1), 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MAX_EXPR, - type, - fold_convert (type, arg1), - arg2)); + { + tem = fold_build2 (MAX_EXPR, TREE_TYPE (arg00), arg00, + fold_convert (TREE_TYPE (arg00), arg2)); + return pedantic_non_lvalue (fold_convert (type, tem)); + } break; case NE_EXPR: break; @@ -9241,6 +9250,27 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) return fold_build2 (cmp_code, type, variable1, const2); } + /* Fold comparison using aliasing guarantee: + &local_var != parameter_default + &local_var == parameter_default + + A local variable can never be pointed to by + the default SSA name of an incoming parameter. */ + + if (TREE_CODE (arg0) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (arg0, 0)) == VAR_DECL + && !is_global_var (TREE_OPERAND (arg0, 0)) + && TREE_CODE (arg1) == SSA_NAME + && TREE_CODE (SSA_NAME_VAR (arg1)) == PARM_DECL + && SSA_NAME_IS_DEFAULT_DEF (arg1)) + { + if (code == NE_EXPR) + return constant_boolean_node (1, type); + else if (code == EQ_EXPR) + return constant_boolean_node (0, type); + } + + tem = maybe_canonicalize_comparison (code, type, op0, op1); if (tem) return tem; @@ -11360,6 +11390,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) if (prec < HOST_BITS_PER_WIDE_INT || newmask == ~(unsigned HOST_WIDE_INT) 0) { + tree newmaskt; + if (shift_type != TREE_TYPE (arg0)) { tem = fold_build2 (TREE_CODE (arg0), shift_type, @@ -11370,9 +11402,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } else tem = op0; - return fold_build2 (BIT_AND_EXPR, type, tem, - build_int_cst_type (TREE_TYPE (op1), - newmask)); + newmaskt = build_int_cst_type (TREE_TYPE (op1), newmask); + if (!tree_int_cst_equal (newmaskt, arg1)) + return fold_build2 (BIT_AND_EXPR, type, tem, newmaskt); } } } @@ -11861,7 +11893,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) if (code == LROTATE_EXPR || code == RROTATE_EXPR) low = low % TYPE_PRECISION (type); else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR) - return build_int_cst (type, 0); + return omit_one_operand (type, build_int_cst (type, 0), + TREE_OPERAND (arg0, 0)); else low = TYPE_PRECISION (type) - 1; } |