On Thu, 2 Apr 2020, Jakub Jelinek wrote: > On Thu, Apr 02, 2020 at 11:12:48AM +0200, Richard Biener wrote: > > > "The implementation may assume that any thread will eventually do one of > > > the > > > following: > > > — terminate, > > > — make a call to a library I/O function, > > > — perform an access through a volatile glvalue, or > > > — perform a synchronization operation or an atomic operation. > > > [Note: This is intended to allow compiler transformations such as removal > > > of > > > empty loops, even when termination cannot be proven. — end note]" > > With -ffinite-loops, do we actually not optimize if the loop has volatile > accesses > or atomics or library I/O calls?
We don't remove the loop then, yes. All of those are considered side-effects by GCC and thus they are considered needed and keep the loop live. From a technical point finite_loop_p will still return true for those which is not correct but harmless at the moment (I hope). I read the above as volatile int i; int __attribute__((const,noinline)) baz(int i) { return i; } int foo(int a) { do { i; if (a != baz(a)) return 1; } while (1); } being a valid endles loop which we indeed preserve. But we notice the opportunity to unswitch on the condition and elide _that_ loop: <bb 2> [local count: 118111600]: _1 = baz (a_4(D)); if (_1 != a_4(D)) goto <bb 4>; [11.00%] else goto <bb 3>; [89.00%] <bb 3> [local count: 955630224]: vol.0_5 ={v} i; goto <bb 3>; [100.00%] <bb 4> [local count: 118111600]: vol.0_3 ={v} i; return 1; thus turn it into if (a != baz(a)) { i; return 1; } do { i; } while (1); Richard.