[llvm-dev] returns_twice / noreturn

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 3 18:06:52 PDT 2017


On 11/03/2017 07:57 PM, Yichao Yu wrote:
> On Fri, Nov 3, 2017 at 8:54 PM, Alexandre Isoard via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
>> On Fri, Nov 3, 2017 at 5:39 PM, Hal Finkel <hfinkel at anl.gov> wrote:
>>> On 11/03/2017 07:20 PM, Alexandre Isoard via llvm-dev wrote:
>>>
>>> Hello,
>>>
>>> I am not sure about the semantic (if any) of returns_twice and noreturn
>>> attributes.
>>>
>>> int fork() __attribute__((returns_twice));
>>> void join(int) __attribute__((noreturn));
>>>
>>> int f(int n) {
>>>    int t = fork();
>>>    n++;
>>>    if (t != 0)
>>>      join(t);
>>>    return n;
>>> }
>>>
>>> Where the n++ has been moved after the if, is that legal?
>>>
>>>
>>> Why wouldn't it be?
>>
>> Because fork() could return 0, then n get incremented (first time), we go
>> into join(t) which do not return... but jump back into fork() which returns
>> again, but 1 this time, then n get incremented (second time), and we return
>> n+2.
> This is a valid transformation and that's why to get the effect you
> want in C/C++, the variable must be marked volatile.

That's correct. The relevant semantics here come from C's 
setjmp/longjmp, and there's an exception in that language to deal with 
this situation:

7.13.2.1p3: "All accessible objects have values, and all other 
components of the abstract machine have state, as of the time the 
longjmp function was called, except that the values of objects of 
automatic storage duration that are local to the function containing the 
invocation of the corresponding setjmp macro that do not have 
volatile-qualified type and have been changed between the setjmp 
invocation and longjmp call are indeterminate."

We should probably import some version of this into the LangRef to 
more-accurately describe returns_twice/noreturn (because that's what we 
actually implement in this regard).

  -Hal

>
>> While if we move the n++ outside of that "region", we change that semantic?
>> Basically, returns_twice and noreturn have SSA-reaching side-effects.
>>
>>>
>>> They have semantics. returns_twice, however, really means, "it may return
>>> more than once". noreturn is interpreted as the name implies. Thus the
>>> unreachable after the call.
>>
>> That means we can encode a loop this way? :-)
>>
>>>
>>>   -Hal
>>>
>>> --
>>> Hal Finkel
>>> Lead, Compiler Technology and Programming Languages
>>> Leadership Computing Facility
>>> Argonne National Laboratory
>>
>>
>>
>> --
>> Alexandre Isoard
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-dev mailing list