[llvm-bugs] [Bug 36513] New: The pruneeh pass seems to incorrectly add the nounwind attribute

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Feb 25 18:08:16 PST 2018


https://bugs.llvm.org/show_bug.cgi?id=36513

            Bug ID: 36513
           Summary: The pruneeh pass seems to incorrectly add the nounwind
                    attribute
           Product: new-bugs
           Version: 5.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: benoit.vey at etu.upmc.fr
                CC: llvm-bugs at lists.llvm.org

Created attachment 19953
  --> https://bugs.llvm.org/attachment.cgi?id=19953&action=edit
IR and assembly files demonstrating the bug

The attachment is an archive containing an IR file and an x86 assembly file
demonstrating the bug.

In the IR file, there are two almost identical functions. `with_nounwind` is
marked `nounwind`, `without_nounwind` isn't. If you run

  opt -pruneeh -S nounwind.ll

you'll observe that `without_nounwind` has been marked `nounwind`, making it
identical to `with_nounwind`.

The x86 assembly file is the result of the following command (the input is the
original file, not the output of the above command):

  llc -o nounwind.s nounwind.ll

In the resulting assembly code for `with_nounwind`, it seems that the landing
pad isn't generated correctly. In particular, take a look at the following
parts of the code:

>From `without_nounwind`

  .LBB0_1:                     # %throw
  .Ltmp0:
        callq   throw_exception
  .Ltmp1:
  # BB#2:                      # %unreachable
  .LBB0_3:                     # %landing
  .Ltmp2:
          popq    %rax
          retq
  ...
      .long   .Ltmp1-.Ltmp0           #   Call between .Ltmp0 and .Ltmp1
      .long   .Ltmp2-.Lfunc_begin0    #     jumps to .Ltmp2

And from `with_nounwind`

  .LBB1_1:                     # %throw
        pushq   %rax
  .Ltmp3:
        callq   throw_exception
  .Ltmp4:
        addq    $8, %rsp
  # BB#2:                      # %unreachable
  .LBB1_3:                     # %landing
  .Ltmp5:
        retq
  ...
      .long   .Ltmp4-.Ltmp3           #   Call between .Ltmp3 and .Ltmp4
      .long   .Ltmp5-.Lfunc_begin1    #     jumps to .Ltmp5

As you can see, in `without_nounwind`, the landing pad is correctly setup so
that the stack space used for spilling is cleaned up in both the throwing and
the non-throwing cases. In `with_nounwind`, the landing pad is setup right
before the return instruction and the throwing case doesn't cleanup the stack.
At runtime, this results in a segmentation fault. I can provide the code for
`throw_exception` and `my_personality` in case anyone wants to try running the
code.

I'm not sure whether it is pruneeh that is incorrectly adding the `nounwind`
attribute or it is the machine code generation that doesn't handle `nounwind`
functions correctly so I included details for both parts.

This bug was originally found through a bug report to the Pony compiler. See
the following link for the full details:
https://github.com/ponylang/ponyc/issues/1186

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180226/3b7ddb0b/attachment.html>


More information about the llvm-bugs mailing list