Fixes an obscure Win64 unwinding failure which I've stumbled upon. Please see comments for details.
MSVC does the same, btw.
Details
- Reviewers
rnk - Commits
- rGe70401045009: Fix failure to invoke exception handler on Win64
Diff Detail
Event Timeline
| lib/Target/X86/X86FrameLowering.cpp | ||
|---|---|---|
| 838 | This seems like a do { } while (...) loop. | |
| 844 | Does this not return one-past-the-end? That aside, I don't think this will work in general, because basic block placement runs *after* prologue-epilogue insertion. For now I think we should always insert a nop if the epilogue is at the beginning of a basic block, just to be safe. The actual solution is probably to insert some kind of target-specific pseudo that we lower out after block placement to either a nop or nothing. | |
| test/CodeGen/X86/win64_call_epi.ll | ||
| 2 | Does this fail without -O0? Just curious. | |
| 4 | Can you come up with a test case that fails when block placement runs? Something like this maybe: define void @bar(i1 zeroext %cond ) {
br i1 %cond, label %a, label %b ; <- Add metadata to indicate that %a is *highly* likely over %b.
a:
call void @foo()
br label %done
b:
call void @baz()
store i32 0, i32* @something
br label %done
done:
ret void
} | |
| lib/Target/X86/X86FrameLowering.cpp | ||
|---|---|---|
| 844 |
Hmm, yes it probably does.
I can make it do what you suggest, though I think that 'ret' starts out in a MBB of its' own quite often.
I was considering creating 'SEH_Epilogue' pseudo, then checking for preceding CALLs when lowering it in X86AsmPrinter. Unfortunately, some pseudos, like EH_LABEL, are not lowered till the last moment, so it'd still have to have logic to skip those. | |
| test/CodeGen/X86/win64_call_epi.ll | ||
| 2 | No, it still works. Just something I copied from another test... | |
| 4 | Yeah, this breaks it. :( | |
| lib/Target/X86/X86FrameLowering.cpp | ||
|---|---|---|
| 844 | The SEH_Epilogue pseudo sounds good, even with exciting logic to skip non-instruction pseudos. | |
lgtm
I guess I'll apply this with the suggested tweaks, to save a round trip. Thanks for the patch!
| lib/Target/X86/X86MCInstLower.cpp | ||
|---|---|---|
| 982–983 | Usually when you declare locals in a case label like this you need to wrap it in braces. There are no subsequent cases today, but you should go ahead and wrap it now. | |
| 986 | I think some pseudos emit real code, so I would soften this to say that by assuming they aren't real, we will conservatively emit a nop in more cases than is absolutely necessary. | |
This seems like a do { } while (...) loop.