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 | ||
1 | Does this fail without -O0? Just curious. | |
3 | 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 | ||
1 | No, it still works. Just something I copied from another test... | |
3 | 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 ↗ | (On Diff #12127) | 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 ↗ | (On Diff #12127) | 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.