[llvm-bugs] [Bug 25398] New: WinEH funclet entries/exits "kill" volatile registers

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Nov 3 18:17:33 PST 2015


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

            Bug ID: 25398
           Summary: WinEH funclet entries/exits "kill" volatile registers
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: Register Allocator
          Assignee: unassignedbugs at nondot.org
          Reporter: JCTremoulet at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Created attachment 15215
  --> https://llvm.org/bugs/attachment.cgi?id=15215&action=edit
File that miscompiles (64-bit, with -code-model=large)

The rules around WinEH funclets need to be correctly modeled in the register
allocator:
 - On entry to a funclet, all registers may be trashed
 - On exit from a funclet, volatile registers may be trashed, and nonvolatile
registers will be restored *to the value they had just prior to the exception*

32-bit WinEH has a workaround that just models calls which may transition to
funclets as killing all registers, which is conservatively correct.
64-bit WinEH does not (yet?) have such a workaround, which could lead to
miscompiles, as in the attached bad_regalloc.ll (which needs -code-model=large
to expose the bug, and tries to hold the call target in rsi across a funclet
entry where it may be trashed).

While the workaround is conservatively correct, it imposes a rather severe
penalty on the non-exceptional path around exceptional constructs, so the real
work here is to find a correct, less conservative solution.

A good first step would be modeling the kills as happening on the exceptional
path out of the invoke but not the normal path out of it.  This requires
modeling them as occurring on the unsplittable edge or, equivalently, modeling
them with some operator at the start of the funclet entry block *which is glued
to the top of the block* -- the RA needs to know that it cannot insert spills
after the edge and before the kill, which IIUC is a novel constraint for LLVM's
RA.

A good second step would be to recognize when the only appearance of some
nonvolatile register in a function is its apparent kill at one of these funclet
boundaries, and suppress the save/restore that would otherwise be inserted to
preserve its value for the current function's caller, since the runtime will
already restore its value on exit from the funclet.

A third step would be to take advantage of the runtime's restoring of these
values on funclet exit, enregistering candidates across entire catch handlers
when those candidates are not modified within the handler.

-- 
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/20151104/09c77404/attachment.html>


More information about the llvm-bugs mailing list