[llvm-dev] MachineSink optimization in code containing a setjmp
    TB Schardl via llvm-dev 
    llvm-dev at lists.llvm.org
       
    Tue Oct 13 13:29:17 PDT 2015
    
    
  
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151013/0bf192a6/attachment.html>
    
    
More information about the llvm-dev
mailing list