Skip to content
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

#inline(never) is not respected #73739

Closed
jrmuizel opened this issue Jun 25, 2020 · 11 comments
Closed

#inline(never) is not respected #73739

jrmuizel opened this issue Jun 25, 2020 · 11 comments
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. S-blocked Status: Blocked on something else such as an RFC or other implementation work.

Comments

@jrmuizel
Copy link
Contributor

I tried this code:

#[inline(never)]
fn demo(s: &str) -> &str {
    s
}

pub fn main() -> &'static str {
    demo("input string")
}

it compiles to:

example::main:
        lea     rax, [rip + .L__unnamed_1]
        mov     edx, 12
        ret

.L__unnamed_1:
        .ascii  "input string"

which has demo inlined into main

This worked properly in Rust 1.11 but broke in Rust 1.12 and remains broken.

@jrmuizel jrmuizel added the C-bug Category: This is a bug. label Jun 25, 2020
@bugadani
Copy link
Contributor

godbolt.org

@bugadani
Copy link
Contributor

Also, attribute is respected for public functions: godbolt.org

@nbdd0121
Copy link
Contributor

I suspect this is a LLVM bug.

@jrmuizel
Copy link
Contributor Author

Indeed. I've filed https://bugs.llvm.org/show_bug.cgi?id=46463.

@jyn514
Copy link
Member

jyn514 commented Jun 26, 2020

@rustbot modify labels: S-blocked A-codegen A-LLVM

Not sure about the codegen one.

@rustbot rustbot added A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Jun 26, 2020
@hanna-kruppe
Copy link
Contributor

I don't think this is an LLVM bug. The inline(never) attribute controls inlining but it does not make the function opaque to other inter-procedural analyses and optimizations, which can appear to have similar effects to inlining, especially in trivial examples like this. In particular, the generated code in this example can be explained by a combination of (1) noticing that demo() returns its argument unmodified and (2) noticing demo() has no effects other than this return value.

@nagisa
Copy link
Member

nagisa commented Jun 26, 2020

Furthermore any form of the inline attribute it is just a "hint" and is not required to be honored by the compiler.

EDIT: though I concur with @hanna-kruppe's evaluation and believe that to be the explanation as to why, regardless of what the linked LLVM issue says.

@nikic
Copy link
Contributor

nikic commented Jul 12, 2020

@hanna-kruppe is correct, this is not a bug on the LLVM side. There was some discussion that this semantic could be covered by a new noipa attribute, which is supported by GCC. (Though I haven't really heard why one would be interested in this.)

@workingjubilee
Copy link
Member

As mentioned, this is Technically Not A Bug, and no clear motivation for guaranteeing this has been given. #[inline(never)] in practice often works... in non-trivial cases. Or just when the function is marked pub, really. If it didn't work in that case, I think there would be more work to be done, but in practice it does work in that case, so! Closing. Feel free to reopen if there was some niche case you were thinking of not adequately served by adding pub as well.

@workingjubilee workingjubilee closed this as not planned Won't fix, can't repro, duplicate, stale Jul 21, 2022
@lovely-error
Copy link

I have a case where the behavior of this attribute would be of crucial importance had it been what it claims it is. In short, I want to ease the pressure of monomorphisation an do a single implementation M which should not be exposed and then make some impls call that implementation. As you may imagine, if compiler would inline every single call to M that would defeat the purpose of the this technique.

@workingjubilee
Copy link
Member

@lovely-error You may open a new issue explaining your use-case if you like.

But if it's just for optimization purposes, the problem is not that #[inline(never)] does not reduce inlining. It does. It's that you can't hide something in an #[inline(never)] fn monomorphic that could change the global state in a way that another instantiation couldn't see. That could provide illogical results if it is instantiated twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. S-blocked Status: Blocked on something else such as an RFC or other implementation work.
Projects
None yet
Development

No branches or pull requests

10 participants