<div dir="ltr">We're using the llvm.eh.sjlj.setjmp() intrinsic.  From the IR, the declaration of the intrinsic is only marked nounwind, but all calls to the intrinsic are marked returns_twice.<div><br></div><div>TB</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 13, 2015 at 5:04 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">JUst to be clear: is the setjmp function marked returns_twice?<br>
<div><div class="h5"><br>
<br>
On Tue, Oct 13, 2015 at 1:29 PM, TB Schardl via llvm-dev<br>
<<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
> Hello LLVM-dev,<br>
><br>
> I think I've found an issue with the MachineSink optimization on a program<br>
> that uses setjmp.  It looks like MachineSink will happily move a machine<br>
> instruction into a following machine basic block (not necessarily a<br>
> successor), even when that later block can be reached through a setjmp.<br>
> Here is some example debug output from llc that I'm seeing:<br>
><br>
> Sinking along critical edge.<br>
> Sink instr %vreg8<def,tied1> = ADD64rr %vreg14<tied0>, %vreg31,<br>
> %EFLAGS<imp-def,dead>; GR64:%vreg8,%vreg14,%vreg31<br>
>         into block BB#11:<br>
>     Predecessors according to CFG: BB#8 BB#10 BB#32<br>
>  ...<br>
>         EH_SjLj_Setup <BB#36>, <regmask><br>
>     Successors according to CFG: BB#34 BB#36<br>
> Sinking along critical edge.<br>
> Sink instr %vreg8<def,tied1> = ADD64rr %vreg14<tied0>, %vreg31,<br>
> %EFLAGS<imp-def,dead>; GR64:%vreg8,%vreg14,%vreg31<br>
>         into block BB#35:<br>
>     Predecessors according to CFG: BB#34 BB#36<br>
> ..<br>
>     Successors according to CFG: BB#12(12) BB#13(20)<br>
><br>
> In this case, it looks like MachineSink moves the ADD64rr instruction from<br>
> BB#4 into BB#26, which post-dominates both BB#25 and BB#27.  This movement<br>
> becomes a problem, I think, when the arguments of the moved instruction are<br>
> spilled onto the stack.  Here is the final assembly of the affected basic<br>
> blocks:<br>
><br>
> .LBB0_19<br>
> ...<br>
>         movq    %rbp, -104(%rbp)<br>
>         movq    %rsp, -88(%rbp)<br>
>         movq    $.LBB0_42, 8(%r15)<br>
>         #EH_SjLj_Setup  .LBB0_42<br>
> # BB#20:<br>
>         movq    -176(%rbp), %rdi        # 8-byte Reload<br>
>         xorl    %ecx, %ecx<br>
>         jmp     .LBB0_21<br>
> .LBB0_42:<br>
>         movl    $1, %ecx<br>
>         movq    -176(%rbp), %rdi        # 8-byte Reload<br>
> .LBB0_21:<br>
>         movq    -168(%rbp), %rax        # 8-byte Reload<br>
>         addq    -144(%rbp), %rax        # 8-byte Folded Reload<br>
>         movq    %rax, -168(%rbp)        # 8-byte Spill<br>
><br>
> In my code, because of the setjmp, basic block .LBB0_21 ends up executing<br>
> twice, causing the addition to execute twice and produce an incorrect<br>
> result.<br>
><br>
> It seems like moving non-idempotent operations past a setjmp in this way<br>
> should be incorrect, because a corresponding longjmp can cause that<br>
> operation to execute twice.  Am I missing something in this reasoning?<br>
><br>
> Thank you in advance for your help.  I apologize for not having a small test<br>
> program handy.  The program in which I found this issue is somewhat large<br>
> and complex.<br>
><br>
> Cheers,<br>
> TB<br>
><br>
</div></div>> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
><br>
</blockquote></div><br></div>