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. 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* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171103/068a89eb/attachment.html>
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.> > 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 >
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