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; } Produces the following LLVM IR: ; Function Attrs: nounwind uwtable define i32 @f(i32 %n) local_unnamed_addr #0 { entry: %call = call i32 (...) @fork() #3 %cmp = icmp eq i32 %call, 0 br i1 %cmp, label %if.end, label %if.then if.then: ; preds = %entry call void @join(i32 %call) #4 unreachable if.end: ; preds = %entry %inc = add nsw i32 %n, 1 ret i32 %inc } ; Function Attrs: returns_twice declare i32 @fork(...) local_unnamed_addr #1 ; Function Attrs: noreturn declare void @join(i32) local_unnamed_addr #2 Where the n++ has been moved after the if, is that legal? Also, technically, f could also returns_twice or noreturn (depending on the return values of fork). So my question is: do they have semantic or they are only "clues" for heuristic purposes? -- *Alexandre Isoard* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171103/e51d029f/attachment.html>
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; > } > > Produces the following LLVM IR: > > ; Function Attrs: nounwind uwtable > define i32 @f(i32 %n) local_unnamed_addr #0 { > entry: > %call = call i32 (...) @fork() #3 > %cmp = icmp eq i32 %call, 0 > br i1 %cmp, label %if.end, label %if.then > > if.then: ; preds = %entry > call void @join(i32 %call) #4 > unreachable > > if.end: ; preds = %entry > %inc = add nsw i32 %n, 1 > ret i32 %inc > } > > ; Function Attrs: returns_twice > declare i32 @fork(...) local_unnamed_addr #1 > > ; Function Attrs: noreturn > declare void @join(i32) local_unnamed_addr #2 > > Where the n++ has been moved after the if, is that legal?Why wouldn't it be?> > Also, technically, f could also returns_twice or noreturn (depending > on the return values of fork). > > So my question is: do they have semantic or they are only "clues" for > heuristic purposes?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. -Hal> > -- > *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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171103/8627aaa1/attachment-0001.html>
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>