This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR47559
On Tue, 1 Feb 2011, Zdenek Dvorak wrote:
> Hi,
>
> > We perform store-motion on loops without exits - which for the
> > testcase makes us fail to properly handle must-not-throw info.
> > The patch below simply disables store-motion for loops without
> > exits (technically the transformation is profitable though),
> > a workaround for the ICE.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok?
> >
> > Any better idea where to check for the throwing statement?
>
> I am not sure what must-not-throw is. However, can_sm_ref_p would be the place
> where one should exclude the memory references that should not be moved or for
> that we cannot update the information correctly,
I see. The check is already there:
/* If it can trap, it must be always executed in LOOP.
Readonly memory locations may trap when storing to them, but
tree_could_trap_p is a predicate for rvalues, so check that
explicitly. */
base = get_base_address (ref->mem);
if ((tree_could_trap_p (ref->mem)
|| (DECL_P (base) && TREE_READONLY (base)))
&& !ref_always_accessed_p (loop, ref, true))
return false;
but ref_always_accessed_p returns true - so we move possibly trapping
stores. For LIM we give up on stmt_could_throw_p () stmts, so
maybe we should, for tree_could_throw_p () ones, too, independent
on whether the ref is always performed.
I'll testing the following.
Richard.
2011-02-01 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47559
* tree-ssa-loop-im.c (can_sm_ref_p): Do not perform
store-motion on references that can throw.
* g++.dg/torture/pr47559.C: New testcase.
Index: gcc/tree-ssa-loop-im.c
===================================================================
*** gcc/tree-ssa-loop-im.c (revision 169434)
--- gcc/tree-ssa-loop-im.c (working copy)
*************** can_sm_ref_p (struct loop *loop, mem_ref
*** 2318,2323 ****
--- 2318,2327 ----
|| !for_each_index (&ref->mem, may_move_till, loop))
return false;
+ /* If it can throw fail, we do not properly update EH info. */
+ if (tree_could_throw_p (ref->mem))
+ return false;
+
/* If it can trap, it must be always executed in LOOP.
Readonly memory locations may trap when storing to them, but
tree_could_trap_p is a predicate for rvalues, so check that
Index: gcc/testsuite/g++.dg/torture/pr47559.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr47559.C (revision 0)
--- gcc/testsuite/g++.dg/torture/pr47559.C (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ // { dg-do compile }
+ // { dg-options "-std=c++0x -fnon-call-exceptions" }
+
+ void foo (int *k) noexcept
+ {
+ for (;;)
+ *k = 0;
+ }