Hi! As mentioned in the PR, save_expr seems to be very optimistic when some expression is invariant, which can result in various wrong-code issues. The problem is with the TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t) case in tree_invariant_p_1. TREE_READONLY (t) in that case says that the object shouldn't be modified during its lifetime and !TREE_SIDE_EFFECTS (t) that it can be evaluated safely multiple times, but that doesn't mean we can avoid wrapping the expression into SAVE_EXPR say for a TREE_READONLY COMPONENT_REF with INDIRECT_REF as first operand - either the lifetime of the TREE_READONLY object could end earlier than when we need to reevaluate the object (that happens in the pr52339-1.c case where save_expr is called on p->a and then free (p) is done or pr52339.C where delete a->b when calling ~B () dtor deallocates a), or e.g. the pointer could change as in pr52339-2.c (so evaluating p->a again after ++p yields a possibly different value than originally and again we need a SAVE_EXPR). Attached are two patches which fix this, unfortunately both regress FAIL: gnat.dg/loop_optimization21.adb scan-tree-dump-times optimized "Index_Check" 1 FAIL: gnat.dg/vect1.adb scan-tree-dump-times vect "vectorized 1 loops" 15 FAIL: gnat.dg/vect2.adb scan-tree-dump-times vect "vectorized 1 loops" 15 FAIL: gnat.dg/vect3.adb scan-tree-dump-times vect "vectorized 1 loops" 15 FAIL: gnat.dg/vect4.adb scan-tree-dump-times vect "vectorized 1 loops" 15 FAIL: gnat.dg/vect5.adb scan-tree-dump-times vect "vectorized 1 loops" 15 FAIL: gnat.dg/vect6.adb scan-tree-dump-times vect "vectorized 1 loops" 15 on x86_64-linux (the first scan triggers 2 times rather than once, the next 3 13 times rather than 15 and the last 3 14 times rather than 15 times). The first patch has been otherwise successfully bootstrapped/regtested on x86_64-linux and i686-linux (with that above regressions), the second one is probably better but has been so far tested just on the new testcases and verified to also cause the above Ada regressions. Ok for trunk (which version), what to do about the regressions, shall we just adjust the expected counts or something else? E.g. in the vect6.adb case it is the procedure Add (X : Varray; Y : Long_Float; R : out Varray) is begin for I in X'Range loop R(I) := X(I) + Y; end loop; end; function that is no longer vectorized. Both patches lead to lots of former r.P_BOUNDS->LB0 r.P_BOUNDS->UB0 x.P_BOUNDS->LB0 x.P_BOUNDS->UB0 expressions to be wrapped into SAVE_EXPRs. Jakub