===================================================================
@@ -1971,22 +1971,22 @@ simplify_bitwise_binary (gimple_stmt_ite
gimple_assign_set_rhs2 (stmt, b);
gimple_assign_set_rhs_code (stmt, def1_code);
update_stmt (stmt);
return true;
}
}
/* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */
if (code == BIT_AND_EXPR
&& def1_code == BIT_IOR_EXPR
- && TREE_CODE (arg2) == INTEGER_CST
- && TREE_CODE (def1_arg2) == INTEGER_CST)
+ && CONSTANT_CLASS_P (arg2)
+ && CONSTANT_CLASS_P (def1_arg2))
{
tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2),
arg2, def1_arg2);
tree tem;
gimple newop;
if (integer_zerop (cst))
{
gimple_assign_set_rhs1 (stmt, def1_arg1);
update_stmt (stmt);
return true;
@@ -2002,34 +2002,33 @@ simplify_bitwise_binary (gimple_stmt_ite
gimple_assign_set_rhs_code (stmt, BIT_IOR_EXPR);
update_stmt (stmt);
return true;
}
/* Combine successive equal operations with constants. */
if ((code == BIT_AND_EXPR
|| code == BIT_IOR_EXPR
|| code == BIT_XOR_EXPR)
&& def1_code == code
- && TREE_CODE (arg2) == INTEGER_CST
- && TREE_CODE (def1_arg2) == INTEGER_CST)
+ && CONSTANT_CLASS_P (arg2)
+ && CONSTANT_CLASS_P (def1_arg2))
{
tree cst = fold_build2 (code, TREE_TYPE (arg2),
arg2, def1_arg2);
gimple_assign_set_rhs1 (stmt, def1_arg1);
gimple_assign_set_rhs2 (stmt, cst);
update_stmt (stmt);
return true;
}
/* Canonicalize X ^ ~0 to ~X. */
if (code == BIT_XOR_EXPR
- && TREE_CODE (arg2) == INTEGER_CST
&& integer_all_onesp (arg2))
{
gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
update_stmt (stmt);
return true;
}
/* Try simple folding for X op !X, and X op X. */
res = simplify_bitwise_binary_1 (code, TREE_TYPE (arg1), arg1, arg2);
@@ -2472,73 +2471,74 @@ associate_plusminus (gimple_stmt_iterato
&& code != def_code)
{
/* (A +- B) -+ B -> A. */
code = TREE_CODE (def_rhs1);
rhs1 = def_rhs1;
rhs2 = NULL_TREE;
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true);
}
- else if (TREE_CODE (rhs2) == INTEGER_CST
- && TREE_CODE (def_rhs1) == INTEGER_CST)
+ else if (CONSTANT_CLASS_P (rhs2)
+ && CONSTANT_CLASS_P (def_rhs1))
{
/* (CST +- A) +- CST -> CST +- A. */
tree cst = fold_binary (code, TREE_TYPE (rhs1),
def_rhs1, rhs2);
if (cst && !TREE_OVERFLOW (cst))
{
code = def_code;
gimple_assign_set_rhs_code (stmt, code);
rhs1 = cst;
gimple_assign_set_rhs1 (stmt, rhs1);
rhs2 = def_rhs2;
gimple_assign_set_rhs2 (stmt, rhs2);
gimple_set_modified (stmt, true);
}
}
- else if (TREE_CODE (rhs2) == INTEGER_CST
- && TREE_CODE (def_rhs2) == INTEGER_CST
+ else if (CONSTANT_CLASS_P (rhs2)
+ && CONSTANT_CLASS_P (def_rhs2)
&& def_code == PLUS_EXPR)
{
/* (A + CST) +- CST -> A + CST. */
tree cst = fold_binary (code, TREE_TYPE (rhs1),
def_rhs2, rhs2);
if (cst && !TREE_OVERFLOW (cst))
{
code = PLUS_EXPR;
gimple_assign_set_rhs_code (stmt, code);
rhs1 = def_rhs1;
gimple_assign_set_rhs1 (stmt, rhs1);
rhs2 = cst;
gimple_assign_set_rhs2 (stmt, rhs2);
gimple_set_modified (stmt, true);
}
}
}
- else if (def_code == BIT_NOT_EXPR
- && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+ else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR)
{
tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
- if (code == PLUS_EXPR
- && operand_equal_p (def_rhs1, rhs2, 0))
+ if (operand_equal_p (def_rhs1, rhs2, 0))
{
/* ~A + A -> -1. */
- code = INTEGER_CST;
- rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
+ rhs1 = build_all_ones_cst (TREE_TYPE (rhs2));
rhs2 = NULL_TREE;
+ code = TREE_CODE (rhs1);
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true);
}
- else if (code == PLUS_EXPR
- && integer_onep (rhs1))
+ else if ((TREE_CODE (TREE_TYPE (rhs1)) != COMPLEX_TYPE
+ && integer_onep (rhs1))
+ || (TREE_CODE (rhs1) == COMPLEX_CST
+ && integer_onep (TREE_REALPART (rhs1))
+ && integer_onep (TREE_IMAGPART (rhs1))))
{
/* ~A + 1 -> -A. */
code = NEGATE_EXPR;
rhs1 = def_rhs1;
rhs2 = NULL_TREE;
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true);
}
}
@@ -2573,66 +2573,65 @@ associate_plusminus (gimple_stmt_iterato
{
/* A +- (B +- A) -> +- B. */
code = ((code == PLUS_EXPR)
? TREE_CODE (def_rhs1) : NEGATE_EXPR);
rhs1 = def_rhs1;
rhs2 = NULL_TREE;
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true);
}
- else if (TREE_CODE (rhs1) == INTEGER_CST
- && TREE_CODE (def_rhs1) == INTEGER_CST)
+ else if (CONSTANT_CLASS_P (rhs1)
+ && CONSTANT_CLASS_P (def_rhs1))
{
/* CST +- (CST +- A) -> CST +- A. */
tree cst = fold_binary (code, TREE_TYPE (rhs2),
rhs1, def_rhs1);
if (cst && !TREE_OVERFLOW (cst))
{
code = (code == def_code ? PLUS_EXPR : MINUS_EXPR);
gimple_assign_set_rhs_code (stmt, code);
rhs1 = cst;
gimple_assign_set_rhs1 (stmt, rhs1);
rhs2 = def_rhs2;
gimple_assign_set_rhs2 (stmt, rhs2);
gimple_set_modified (stmt, true);
}
}
- else if (TREE_CODE (rhs1) == INTEGER_CST
- && TREE_CODE (def_rhs2) == INTEGER_CST)
+ else if (CONSTANT_CLASS_P (rhs1)
+ && CONSTANT_CLASS_P (def_rhs2))
{
/* CST +- (A +- CST) -> CST +- A. */
tree cst = fold_binary (def_code == code
? PLUS_EXPR : MINUS_EXPR,
TREE_TYPE (rhs2),
rhs1, def_rhs2);
if (cst && !TREE_OVERFLOW (cst))
{
rhs1 = cst;
gimple_assign_set_rhs1 (stmt, rhs1);
rhs2 = def_rhs1;
gimple_assign_set_rhs2 (stmt, rhs2);
gimple_set_modified (stmt, true);
}
}
}
- else if (def_code == BIT_NOT_EXPR
- && INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
+ else if (def_code == BIT_NOT_EXPR)
{
tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
if (code == PLUS_EXPR
&& operand_equal_p (def_rhs1, rhs1, 0))
{
/* A + ~A -> -1. */
- code = INTEGER_CST;
- rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
+ rhs1 = build_all_ones_cst (TREE_TYPE (rhs1));
rhs2 = NULL_TREE;
+ code = TREE_CODE (rhs1);
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true);
}
}
}
}
out:
if (gimple_modified_p (stmt))
===================================================================
@@ -1636,20 +1636,35 @@ build_one_cst (tree type)
case COMPLEX_TYPE:
return build_complex (type,
build_one_cst (TREE_TYPE (type)),
build_zero_cst (TREE_TYPE (type)));
default:
gcc_unreachable ();
}
}
+/* Return an integer of type TYPE containing all 1's in as much precision as
+ it contains, or a complex or vector whose subparts are such integers. */
+
+tree
+build_all_ones_cst (tree type)
+{
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ tree scalar = build_all_ones_cst (TREE_TYPE (type));
+ return build_complex (type, scalar, scalar);
+ }
+ else
+ return build_minus_one_cst (type);
+}
+
/* Return a constant of arithmetic type TYPE which is the
opposite of the multiplicative identity of the set TYPE. */
tree
build_minus_one_cst (tree type)
{
switch (TREE_CODE (type))
{
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case POINTER_TYPE: case REFERENCE_TYPE:
===================================================================
@@ -4761,20 +4761,21 @@ extern tree build_vector_stat (tree, tre
extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *);
extern tree build_vector_from_val (tree, tree);
extern tree build_constructor (tree, vec<constructor_elt, va_gc> *);
extern tree build_constructor_single (tree, tree, tree);
extern tree build_constructor_from_list (tree, tree);
extern tree build_constructor_va (tree, int, ...);
extern tree build_real_from_int_cst (tree, const_tree);
extern tree build_complex (tree, tree, tree);
extern tree build_one_cst (tree);
extern tree build_minus_one_cst (tree);
+extern tree build_all_ones_cst (tree);
extern tree build_zero_cst (tree);
extern tree build_string (int, const char *);
extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
#define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
extern tree build_tree_list_vec_stat (const vec<tree, va_gc> *MEM_STAT_DECL);
#define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO)
extern tree build_decl_stat (location_t, enum tree_code,
tree, tree MEM_STAT_DECL);
extern tree build_fn_decl (const char *, tree);
#define build_decl(l,c,t,q) build_decl_stat (l,c,t,q MEM_STAT_INFO)