[llvm-bugs] [Bug 45064] New: [WinEH] LLVM emits unreachable (incorrect?) RSP adjustments after noreturn calls, like CxxThrowException

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Feb 28 17:05:16 PST 2020


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

            Bug ID: 45064
           Summary: [WinEH] LLVM emits unreachable (incorrect?) RSP
                    adjustments after noreturn calls, like
                    CxxThrowException
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Backend: X86
          Assignee: unassignedbugs at nondot.org
          Reporter: rnk at google.com
                CC: craig.topper at gmail.com, hans at chromium.org,
                    llvm-bugs at lists.llvm.org, llvm-dev at redking.me.uk,
                    spatel+llvm at rotateright.com

I noticed this while investigating https://bugs.llvm.org/show_bug.cgi?id=45021

We've had this bug many times:
https://bugs.llvm.org/show_bug.cgi?id=43155
https://bugs.llvm.org/show_bug.cgi?id=27117

But we still have it. :)

Consider, with EH enabled:

struct MakeCleanup {
  ~MakeCleanup();
};
bool cond();
void foo() {
  MakeCleanup o;
  if (cond())
    throw;
  if (cond())
    throw;
}

We get this:
...
        callq   _CxxThrowException
        subq    $32, %rsp
.Ltmp7:
        jmp     .LBB0_8
.LBB0_5:                                # %if.then3
.Ltmp4:
        xorl    %ecx, %ecx
        xorl    %edx, %edx
        callq   _CxxThrowException
        subq    $32, %rsp
.Ltmp5:
.LBB0_8:                                # %unreachable

This is worrying to me, because it could interfere with the Win64 stack
unwinder.

On Win64, most stack frames are reserved, and I think the code we added in the
first place is causing more trouble than it's worth:
  if (CLI.DoesNotReturn && !getTargetMachine().Options.TrapUnreachable) {
    // No need to reset the stack after the call if the call doesn't return. To
    // make the MI verify, we'll pretend the callee does it for us.
    NumBytesForCalleeToPop = NumBytes;
  }
X86ISelLowering.cpp:4333 (file is too big to link on github)

When EH is involved, it becomes difficult for the code I added to PEI to
determine that this adjustment is after a noreturn function call:
https://github.com/llvm/llvm-project/blob/master/llvm/lib/Target/X86/X86FrameLowering.cpp#L3074

I think we might want to invent a cleaner way of indicating that the adjustment
is "dead" and can be skipped while still pacifying the verifier. I notice that
a third argument to ADJCALLSTACKDOWN* was added to pacify the verifier, so we
could do the same again for ADJCALLSTACKUP*.

-- 
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/20200229/b5f02176/attachment.html>


More information about the llvm-bugs mailing list