Message ID | or8u6kfp8l.fsf@livre.home |
---|---|
State | New |
Headers | show |
On Fri, Oct 30, 2015 at 2:41 PM, Alexandre Oliva <aoliva@redhat.com> wrote: > The ifcombine pass may move a conditional access to an uninitialized > value before the condition that ensures it is always well-defined, > thus introducing undefined behavior. Stop it from doing so. > > Regstrapped on x86_64-linux-gnu and i686-linux-gnu. Ok to install? Ok. Thanks, Richard. > > Incidentally, bb_no_side_effects_p (inner_cond_bb) is called in all four > tests in tree_ssa_ifcombine_bb_1, for each outer_cond_bb that > tree_ssa_ifcombine_bb might choose. Is there any reason to not factor > it out to the test that checks whether the inner_cond_bb is indeed an > if_then_else block, early in tree_ssa_ifcombine_bb, so as to > short-circuit the whole thing when the inner block is not viable? > > > for gcc/ChangeLog > > PR tree-optimization/68083 > * tree-ssa-ifcombine.c: Include tree-ssa.h. > (bb_no_side_effects_p): Test for undefined uses too. > * tree-ssa.c (gimple_uses_undefined_value_p): New. > * tree-ssa.h (gimple_uses_undefined_value_p): Declare. > > for gcc/testsuite/ChangeLog > > PR tree-optimization/68083 > * gcc.dg/torture/pr68083.c: New. From Zhendong Su. > --- > gcc/testsuite/gcc.dg/torture/pr68083.c | 35 ++++++++++++++++++++++++++++++++ > gcc/tree-ssa-ifcombine.c | 2 ++ > gcc/tree-ssa.c | 18 ++++++++++++++++ > gcc/tree-ssa.h | 1 + > 4 files changed, 56 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr68083.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr68083.c b/gcc/testsuite/gcc.dg/torture/pr68083.c > new file mode 100644 > index 0000000..ae24781 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr68083.c > @@ -0,0 +1,35 @@ > +/* { dg-do run } */ > + > +int a = 2, b = 1, c = 1; > + > +int > +fn1 () > +{ > + int d; > + for (; a; a--) > + { > + for (d = 0; d < 4; d++) > + { > + int k; > + if (c < 1) > + if (k) > + c = 0; > + if (b) > + continue; > + return 0; > + } > + b = !1; > + } > + return 0; > +} > + > +int > +main () > +{ > + fn1 (); > + > + if (a != 1) > + __builtin_abort (); > + > + return 0; > +} > diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c > index ca55b57..622dc6b 100644 > --- a/gcc/tree-ssa-ifcombine.c > +++ b/gcc/tree-ssa-ifcombine.c > @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-iterator.h" > #include "gimplify-me.h" > #include "tree-cfg.h" > +#include "tree-ssa.h" > > #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT > #define LOGICAL_OP_NON_SHORT_CIRCUIT \ > @@ -125,6 +126,7 @@ bb_no_side_effects_p (basic_block bb) > continue; > > if (gimple_has_side_effects (stmt) > + || gimple_uses_undefined_value_p (stmt) > || gimple_could_trap_p (stmt) > || gimple_vuse (stmt)) > return false; > diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c > index c7be442..8dc2d61 100644 > --- a/gcc/tree-ssa.c > +++ b/gcc/tree-ssa.c > @@ -1210,6 +1210,24 @@ ssa_undefined_value_p (tree t, bool partial) > } > > > +/* Return TRUE iff STMT, a gimple statement, references an undefined > + SSA name. */ > + > +bool > +gimple_uses_undefined_value_p (gimple *stmt) > +{ > + ssa_op_iter iter; > + tree op; > + > + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) > + if (ssa_undefined_value_p (op)) > + return true; > + > + return false; > +} > + > + > + > /* If necessary, rewrite the base of the reference tree *TP from > a MEM_REF to a plain or converted symbol. */ > > diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h > index 5a409e5..3b5bd70 100644 > --- a/gcc/tree-ssa.h > +++ b/gcc/tree-ssa.h > @@ -51,6 +51,7 @@ extern bool tree_ssa_useless_type_conversion (tree); > extern tree tree_ssa_strip_useless_type_conversions (tree); > > extern bool ssa_undefined_value_p (tree, bool = true); > +extern bool gimple_uses_undefined_value_p (gimple *); > extern void execute_update_addresses_taken (void); > > /* Given an edge_var_map V, return the PHI arg definition. */ > > > -- > Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ > You must be the change you wish to see in the world. -- Gandhi > Be Free! -- http://FSFLA.org/ FSF Latin America board member > Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
diff --git a/gcc/testsuite/gcc.dg/torture/pr68083.c b/gcc/testsuite/gcc.dg/torture/pr68083.c new file mode 100644 index 0000000..ae24781 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68083.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ + +int a = 2, b = 1, c = 1; + +int +fn1 () +{ + int d; + for (; a; a--) + { + for (d = 0; d < 4; d++) + { + int k; + if (c < 1) + if (k) + c = 0; + if (b) + continue; + return 0; + } + b = !1; + } + return 0; +} + +int +main () +{ + fn1 (); + + if (a != 1) + __builtin_abort (); + + return 0; +} diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index ca55b57..622dc6b 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "gimplify-me.h" #include "tree-cfg.h" +#include "tree-ssa.h" #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT #define LOGICAL_OP_NON_SHORT_CIRCUIT \ @@ -125,6 +126,7 @@ bb_no_side_effects_p (basic_block bb) continue; if (gimple_has_side_effects (stmt) + || gimple_uses_undefined_value_p (stmt) || gimple_could_trap_p (stmt) || gimple_vuse (stmt)) return false; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index c7be442..8dc2d61 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1210,6 +1210,24 @@ ssa_undefined_value_p (tree t, bool partial) } +/* Return TRUE iff STMT, a gimple statement, references an undefined + SSA name. */ + +bool +gimple_uses_undefined_value_p (gimple *stmt) +{ + ssa_op_iter iter; + tree op; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + if (ssa_undefined_value_p (op)) + return true; + + return false; +} + + + /* If necessary, rewrite the base of the reference tree *TP from a MEM_REF to a plain or converted symbol. */ diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h index 5a409e5..3b5bd70 100644 --- a/gcc/tree-ssa.h +++ b/gcc/tree-ssa.h @@ -51,6 +51,7 @@ extern bool tree_ssa_useless_type_conversion (tree); extern tree tree_ssa_strip_useless_type_conversions (tree); extern bool ssa_undefined_value_p (tree, bool = true); +extern bool gimple_uses_undefined_value_p (gimple *); extern void execute_update_addresses_taken (void); /* Given an edge_var_map V, return the PHI arg definition. */