Hi,

This is nothing to do with undefined behaviour, but a matter of
scheduling of effects that are visible in different circumstances.  In
particular, i and j are declared in a way that tells the compiler that
the compiler, in its current thread of execution has full control of
them.  The compiler knows that while it is executing the code in test,
nothing else can affect the value of i or j, nor can they be affected by
the values of i and j.  The compiler knows that code from elsewhere may
read or write them, but only before test() is called, during functions
called from test(), or after test() returns.  It knows for sure that
there are no other threads of execution that interact via i and j.

So how do you inhibit these kinds of optimisations?  Stop lying to your
compiler.

If you want them to be visible in other threads, tell your compiler that
they are visible in other threads.  You already know how to do that -
using volatile accesses, atomic accesses, other <stdatomic.h> features,
or operating system features.  You can also use somewhat "hack"
techniques such as Linux's "ACCESS_ONCE" macro or inline assembly
dependency controls, but it would be better to define and declare the
data correctly.

Messing around with optimisation settings is just a way of hiding your
coding and design errors until they get more subtle and harder to spot
in the future.

mvh.,

David


On 22/07/18 17:00, Umesh Kalappa wrote:
> Hi Richard,
> 
> making i unsigned still  the  optimization is effective ,no luck.
> and yes test() is the threaded  routine and since i and j are global
> ,we need the side effects take place like assignment etc ,that are
> observed by other threads .
> 
> By making volatile or thread safe or atomic operations ,the
> optimization inhibited ,but still we  didn't  get  why its valid
> optimization for UB and tried with -fno-strict-overflow too ,no luck
> here .
> 
> Jakub and anyone can we inhibit these kind optimizations,that consider
> the UB and optimize .
> 
> Thank you
> ~Umesh
> 
> On Fri, Jul 20, 2018 at 11:47 PM, Richard Biener
> <richard.guent...@gmail.com> wrote:
>> On July 20, 2018 7:59:10 PM GMT+02:00, Martin Sebor <mse...@gmail.com> wrote:
>>> On 07/20/2018 06:19 AM, Umesh Kalappa wrote:
>>>> Hi All ,
>>>>
>>>> We are looking at the C sample i.e
>>>>
>>>> extern int i,j;
>>>>
>>>> int test()
>>>> {
>>>> while(1)
>>>> {       i++;
>>>>         j=20;
>>>> }
>>>> return 0;
>>>> }
>>>>
>>>> command used :(gcc 8.1.0)
>>>> gcc -S test.c -O2
>>>>
>>>> the generated asm for x86
>>>>
>>>> .L2:
>>>>         jmp     .L2
>>>>
>>>> we understand that,the infinite loop is not  deterministic ,compiler
>>>> is free to treat as that as UB and do aggressive optimization ,but we
>>>> need keep the side effects like j=20 untouched by optimization .
>>>>
>>>> Please note that using the volatile qualifier for i and j  or empty
>>>> asm("") in the while loop,will stop the optimizer ,but we don't want
>>>> do  that.
>>>>
>>>> Anyone from the community ,please share their insights why above
>>>> transformation is right ?
>>>
>>> The loop isn't necessarily undefined (and compilers don't look
>>> for undefined behavior as opportunities to optimize code), but
>>
>> The variable i overflows.
>>
>>> because it doesn't terminate it's not possible for a conforming
>>> C program to detect the side-effects in its body.  The only way
>>> to detect it is to examine the object code as you did.
>>
>> I'm not sure we perform this kind of dead code elimination but yes, we 
>> could. Make i unsigned and check whether that changes behavior.
>>
>>> Compilers are allowed (and expected) to transform source code
>>> into efficient object code as long as the transformations don't
>>> change the observable effects of the program.  That's just what
>>> happens in this case.
>>>
>>> Martin
>>
> 

Reply via email to