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