aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple-fold.cc')
-rw-r--r--gcc/gimple-fold.cc83
1 files changed, 67 insertions, 16 deletions
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 7721795..e63fd6f 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -6246,14 +6246,33 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
false, NULL_TREE)))
gimple_cond_set_condition (cond_stmt, code, ops[0], ops[1]);
else if (code == SSA_NAME)
- gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
- build_zero_cst (TREE_TYPE (ops[0])));
+ {
+ /* If setting the gimple cond to the same thing,
+ return false as nothing changed. */
+ if (gimple_cond_code (cond_stmt) == NE_EXPR
+ && operand_equal_p (gimple_cond_lhs (cond_stmt), ops[0])
+ && integer_zerop (gimple_cond_rhs (cond_stmt)))
+ return false;
+ gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
+ build_zero_cst (TREE_TYPE (ops[0])));
+ }
else if (code == INTEGER_CST)
{
+ /* Make into the canonical form `1 != 0` and `0 != 0`.
+ If already in the canonical form return false
+ saying nothing has been done. */
if (integer_zerop (ops[0]))
- gimple_cond_make_false (cond_stmt);
+ {
+ if (gimple_cond_false_canonical_p (cond_stmt))
+ return false;
+ gimple_cond_make_false (cond_stmt);
+ }
else
- gimple_cond_make_true (cond_stmt);
+ {
+ if (gimple_cond_true_canonical_p (cond_stmt))
+ return false;
+ gimple_cond_make_true (cond_stmt);
+ }
}
else if (!inplace)
{
@@ -10592,10 +10611,12 @@ arith_code_with_undefined_signed_overflow (tree_code code)
/* Return true if STMT has an operation that operates on a signed
integer types involves undefined behavior on overflow and the
- operation can be expressed with unsigned arithmetic. */
+ operation can be expressed with unsigned arithmetic.
+ Also returns true if STMT is a VCE that needs to be rewritten
+ if moved to be executed unconditionally. */
bool
-gimple_with_undefined_signed_overflow (gimple *stmt)
+gimple_needing_rewrite_undefined (gimple *stmt)
{
if (!is_gimple_assign (stmt))
return false;
@@ -10606,6 +10627,16 @@ gimple_with_undefined_signed_overflow (gimple *stmt)
if (!INTEGRAL_TYPE_P (lhs_type)
&& !POINTER_TYPE_P (lhs_type))
return false;
+ tree rhs = gimple_assign_rhs1 (stmt);
+ /* VCE from integral types to a integral types but with
+ a smaller precision need to be changed into casts
+ to be well defined. */
+ if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
+ && is_gimple_val (TREE_OPERAND (rhs, 0))
+ && TYPE_PRECISION (lhs_type)
+ < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
+ return true;
if (!TYPE_OVERFLOW_UNDEFINED (lhs_type))
return false;
if (!arith_code_with_undefined_signed_overflow
@@ -10625,19 +10656,39 @@ gimple_with_undefined_signed_overflow (gimple *stmt)
contain a modified form of STMT itself. */
static gimple_seq
-rewrite_to_defined_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
- bool in_place)
+rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi, gimple *stmt,
+ bool in_place)
{
+ gcc_assert (gimple_needing_rewrite_undefined (stmt));
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "rewriting stmt with undefined signed "
- "overflow ");
+ fprintf (dump_file, "rewriting stmt for being uncondtional defined");
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
-
+ gimple_seq stmts = NULL;
+ /* VCE from integral types to another integral types but with
+ smaller precisions need to be changed into casts
+ to be well defined. */
+ if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ tree new_rhs = TREE_OPERAND (rhs, 0);
+ gcc_assert (TYPE_PRECISION (TREE_TYPE (rhs))
+ < TYPE_PRECISION (TREE_TYPE (new_rhs)));
+ gcc_assert (is_gimple_val (new_rhs));
+ gimple_assign_set_rhs_code (stmt, NOP_EXPR);
+ gimple_assign_set_rhs1 (stmt, new_rhs);
+ if (in_place)
+ update_stmt (stmt);
+ else
+ {
+ gimple_set_modified (stmt, true);
+ gimple_seq_add_stmt (&stmts, stmt);
+ }
+ return stmts;
+ }
tree lhs = gimple_assign_lhs (stmt);
tree type = unsigned_type_for (TREE_TYPE (lhs));
- gimple_seq stmts = NULL;
if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
else
@@ -10672,15 +10723,15 @@ rewrite_to_defined_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
}
void
-rewrite_to_defined_overflow (gimple_stmt_iterator *gsi)
+rewrite_to_defined_unconditional (gimple_stmt_iterator *gsi)
{
- rewrite_to_defined_overflow (gsi, gsi_stmt (*gsi), true);
+ rewrite_to_defined_unconditional (gsi, gsi_stmt (*gsi), true);
}
gimple_seq
-rewrite_to_defined_overflow (gimple *stmt)
+rewrite_to_defined_unconditional (gimple *stmt)
{
- return rewrite_to_defined_overflow (nullptr, stmt, false);
+ return rewrite_to_defined_unconditional (nullptr, stmt, false);
}
/* The valueization hook we use for the gimple_build API simplification.