aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.0/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.0/gcc/fold-const.c')
-rw-r--r--gcc-4.4.0/gcc/fold-const.c81
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;
}