int a = -1;
volatile unsigned b = 1U;
int c = 1;
- c = (a + 972195718) / (b ? 1 : 0);
- if (c == 972195717)
+ c = (a + 972195718) / (b ? 2 : 0);
+ if (c == 486097858)
;
else
__builtin_abort ();
int a = -1;
volatile unsigned b = 1U;
int c = 1;
- c = (a + 972195718) % (b ? 1 : 0);
- if (c == 972195717)
+ c = (a + 972195718) % (b ? 2 : 0);
+ if (c == 1)
;
else
__builtin_abort ();
volatile unsigned b = 1U;
int c = 1;
c = (a + 972195716) % (b ? 1 : 2);
- if (c == 972195715)
+ if (c == 0)
;
else
__builtin_abort ();
/* Dont optimize 972195717 / 0 in function foo. */
-/* { dg-final { scan-tree-dump-times "972195717 / _" 1 "evrp" } } */
+/* { dg-final { scan-tree-dump-times "972195717 / " 1 "evrp" } } */
/* Dont optimize 972195717 % 0 in function bar. */
-/* { dg-final { scan-tree-dump-times "972195717 % _" 1 "evrp" } } */
-/* Optimize in function bar2. */
-/* { dg-final { scan-tree-dump-times "972195715 % _" 0 "evrp" } } */
+/* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */
+/* May optimize in function bar2, but EVRP doesn't perform this yet. */
+/* { dg-final { scan-tree-dump-times "972195715 % " 0 "evrp" { xfail *-*-* } } } */
evrp_dom_walker ()
: dom_walker (CDI_DOMINATORS), stack (10)
{
- stmts_to_fixup.create (0);
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
~evrp_dom_walker ()
{
- stmts_to_fixup.release ();
BITMAP_FREE (need_eh_cleanup);
}
virtual edge before_dom_children (basic_block);
/* Cond_stack holds the old VR. */
auto_vec<std::pair <const_tree, value_range*> > stack;
bitmap need_eh_cleanup;
- vec<gimple *> stmts_to_fixup;
+ auto_vec<gimple *> stmts_to_fixup;
+ auto_vec<gimple *> stmts_to_remove;
};
else
set_value_range_to_varying (&vr_result);
update_value_range (lhs, &vr_result);
+
+ /* Mark PHIs whose lhs we fully propagate for removal. */
+ tree val = op_with_constant_singleton_value_range (lhs);
+ if (val && may_propagate_copy (lhs, val))
+ stmts_to_remove.safe_push (phi);
}
edge taken_edge = NULL;
update_value_range (output, &vr);
vr = *get_value_range (output);
-
/* Set the SSA with the value range. */
if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
{
&& range_includes_zero_p (vr.min,
vr.max) == 1)))
set_ptr_nonnull (output);
+
+ /* Mark stmts whose output we fully propagate for removal. */
+ tree val;
+ if ((val = op_with_constant_singleton_value_range (output))
+ && may_propagate_copy (output, val)
+ && !stmt_could_throw_p (stmt)
+ && !gimple_has_side_effects (stmt))
+ {
+ stmts_to_remove.safe_push (stmt);
+ continue;
+ }
}
else
set_defs_to_varying (stmt);
}
}
}
+
+ /* Visit BB successor PHI nodes and replace PHI args. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ for (gphi_iterator gpi = gsi_start_phis (e->dest);
+ !gsi_end_p (gpi); gsi_next (&gpi))
+ {
+ gphi *phi = gpi.phi ();
+ use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
+ tree arg = USE_FROM_PTR (use_p);
+ if (TREE_CODE (arg) != SSA_NAME
+ || virtual_operand_p (arg))
+ continue;
+ tree val = op_with_constant_singleton_value_range (arg);
+ if (val && may_propagate_copy (arg, val))
+ propagate_value (use_p, val);
+ }
+ }
+
bb->flags |= BB_VISITED;
return taken_edge;
evrp_dom_walker walker;
walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
+ dump_all_value_ranges (dump_file);
+ fprintf (dump_file, "\n");
+ }
+
+ /* Remove stmts in reverse order to make debug stmt creation possible. */
+ while (! walker.stmts_to_remove.is_empty ())
+ {
+ gimple *stmt = walker.stmts_to_remove.pop ();
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "Removing dead stmt ");
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ fprintf (dump_file, "\n");
+ }
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ remove_phi_node (&gsi, true);
+ else
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ }
+ }
+
if (!bitmap_empty_p (walker.need_eh_cleanup))
gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
fixup_noreturn_call (stmt);
}
- if (dump_file)
- {
- fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
- dump_all_value_ranges (dump_file);
- fprintf (dump_file, "\n");
- }
vrp_free_lattice ();
scev_finalize ();
loop_optimizer_finalize ();