-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
differing stack sizes via differing paths to variadic calls that push different number of args to the stack #612
Comments
@arndb came up with this test case: int a, b;
void __reiserfs_panic(int, ...) __attribute__((noreturn));
void balance_internal() {
if (a)
__reiserfs_panic(0, "", __func__, "", 2, __func__, a);
if (b)
__reiserfs_panic(0, "", __func__, "", 5, __func__, a, 0);
} And mentioned that "The point is that the stack is different |
It looks like "branch-folder" is tail merging blocks that end in calls even when the calls push additional arguments on the stack. It probably shouldn't do that, or do so more carefully. When it computes the longest "chain" between two branches that flow together, it thinks the "call" instructions are identical, which is dubious since if the function accepts or can accept 6 or more arguments then it's only safe to merge if the callers push the same number of arguments. I don't see any existing interfaces to query the number of function parameters that were pushed on the stack, but it would seem that calls to the same variadic function with differing numbers of args pushed to the stack are not identical and should not be candidates for tail merging. (ie. @topperc do you know? Given a call Conservatively, I can check whether the |
@rnk can you help? |
My first reaction is that this is a bug in LLVM. If the same MBB is entered with different stack levels, there's no way to emit proper unwind instructions for it, and that's an issue for everyone, not just LLVM. As a workaround, try disabling shrink wrapping (I forget the flag, sorry). |
I looked at this again, and I guess shrink wrapping isn't involved here. This function doesn't have any prologue to speak of. You can use a different workaround of disabling x86 call frame optimization, |
I filed https://llvm.org/pr49130 for this. I don't think you need to include objtool to see what the issue is, I think the .cfi_* directives that LLVM produces itself aren't quite right. The most straightforward fix is probably to make some changes to the CFI inserter pass. |
From the discussion with @jpoimboe in https://lore.kernel.org/r/20190716231718.flutou25wemgsfju@treble/:
It seems that LLVM is producing differing stack sizes when two paths eventually call a noreturn function. This wouldn't result in observed runtime behavior, but could mess up unwinding.
I should:
The text was updated successfully, but these errors were encountered: