On Wed, 30 Oct 2019, Jakub Jelinek wrote: > Hi! > > As mentioned in the PR, while get_computation_at calls unshare_aff_combination > and through that unshares the individual expressions, we then call > aff_combination_to_tree which uses the fold-const.c APIs, and those do not > guarantee the same non-shareable tree isn't used multiple times in the > result, e.g. (a ? b : c) + d can be folded into a ? b + d : c + d and when > say d is (cast) &whatever that will appear multiple times in the result. > For debug stmts we are putting these expressions directly into the IL and so > need to make sure there is no invalid tree sharing. As since my patch we > can try to compute the expressions even in cases where it won't be then used > in the end, the following patch does the unsharing only immediately before > putting it into the IL, and removes unsharing in get_debug_computation_at > because it will be unshared anyway later. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. > 2019-10-30 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/92262 > * tree-ssa-loop-ivopts.c (get_debug_computation_at): Don't unshare > ubase or cbase here. > (remove_unused_ivs): Unshare comp before using it. > > * g++.dg/opt/pr92262.C: New test. > > --- gcc/tree-ssa-loop-ivopts.c.jj 2019-10-23 14:35:42.994753407 +0200 > +++ gcc/tree-ssa-loop-ivopts.c 2019-10-29 09:45:47.418217336 +0100 > @@ -4152,8 +4152,6 @@ get_debug_computation_at (class loop *lo > var = fold_convert (ctype, var); > } > > - ubase = unshare_expr (ubase); > - cbase = unshare_expr (cbase); > if (stmt_after_increment (loop, cand, at)) > var = fold_build2 (MINUS_EXPR, TREE_TYPE (var), var, > unshare_expr (cstep)); > @@ -7648,6 +7646,7 @@ remove_unused_ivs (struct ivopts_data *d > if (!best_cand) > continue; > > + comp = unshare_expr (comp); > if (count > 1) > { > tree vexpr = make_node (DEBUG_EXPR_DECL); > --- gcc/testsuite/g++.dg/opt/pr92262.C.jj 2019-10-29 11:20:46.822901945 > +0100 > +++ gcc/testsuite/g++.dg/opt/pr92262.C 2019-10-29 11:20:13.956410318 > +0100 > @@ -0,0 +1,85 @@ > +// PR tree-optimization/92262 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2 -ftree-loop-distribution -g" } > + > +struct A; > +struct B { template <typename T> using b = T *; }; > +template <typename, typename T> using c = B::b<T>; > +void *operator new (__SIZE_TYPE__, void *p) { return p; } > +struct C { > + template <typename T, typename... U> void > + foo (T *x, U... y) { new (x) T(y...); } > +}; > +template <typename> class D : public C {}; > +template <typename> struct E; > +template <typename T> struct E<D<T>> { > + using e = D<T>; > + template <typename U> using f = D<U>; > + template <typename U, typename... V> > + static void > + bar (e x, U y, V... z) { x.foo (y, z...); } > +}; > +template <typename T> struct F : E<T> { > + template <typename U> struct G { typedef typename E<T>::template f<U> O; }; > +}; > +template <typename T, typename U, typename V> void > +baz (T x, U y, V z) > +{ > + F<V>::bar (z, y, *x); > +} > +struct H { > + typedef c<int, A> I; > + typedef c<int, I> J; > + I i; > + J j; > + void qux (J x) { j = x; } > +}; > +template <typename> > +struct K { > + K(D<A> x) : k (x) {} > + typedef H::J L; > + struct M { L m; H n, o; }; > + struct N : F<D<int>>::G<A>::O, M { N (F<D>::G<A>::O); }; > + void quux (); > + N k; > +}; > +template <typename T> > +void > +K<T>::quux () > +{ > + L K (k.m - 1); > + k.n.qux (K); > +} > +template <typename, typename = int> > +struct P : K<int> { > + template <typename T> > + P (T x, T, D<A> y = D<A> ()) : K (y) { corge (x); } > + template <typename T> void corge (T); > + typedef L L; > +}; > +template <typename T, typename U> > +template <typename V> > +void P<T, U>::corge (V y) > +{ > + quux (); > + for (L x = k.n.j; x < k.o.j; ++x) > + { > + ++y; > + D<int> pv; > + baz (y, *x, pv); > + } > + D<int> z; > + baz (y, k.o.i, z); > +} > +struct A { > + A (int x) : a (x) {} > + int a; > +}; > +int a[2]{}; > + > +int > +main () > +{ > + P<int> (a, a); > + return 0; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)