Skip to content

alloc-variant-zeroed causing issues with LTO #145995

Closed

Description

@clubby789

I believe this causing https://crbug.com/441524277. In summary, the rust calloc function _RNvCsfo6nMSlQo1l_7___rustc19___rust_alloc_zeroed definition does not have the alloc-family attribute, but user modules of it have the alloc-family attribute on the calloc declaration. however, if ThinLTO decides to import the function, we lose the alloc-family attribute and the verifier complains 'alloc-variant-zeroed' must name a function belonging to the same 'alloc-family'.

Originally posted by @aeubanks in #144086 (comment)

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 29, 2025
  2. added
    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
    on Aug 29, 2025
  3. added
    A-LTOArea: Link-time optimization (LTO)
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    C-bugCategory: This is a bug.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 29, 2025
  4. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Sep 1, 2025
  5. aeubanks commented on Sep 3, 2025

    @aeubanks
    Contributor

    followup to #144086 (comment)

    $ cat src/main.rs
    
    mod foobar {
        use std::alloc::{GlobalAlloc, Layout};
    
        struct Allocator;
    
        unsafe impl GlobalAlloc for Allocator {
            unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
                panic!()
            }
    
            unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
                panic!()
            }
    
            unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
                panic!()
            }
    
            unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
                panic!()
            }
        }
    
        #[global_allocator]
        static GLOBAL: Allocator = Allocator;
    }
    
    
    fn main() {
        println!("Hello, world!");
    }
    
    $ RUSTFLAGS='--emit=llvm-ir' cargo build --release
    

    no sign of the alloc-family attribute in the .ll file, which does contain definitions for the alloc functions

  6. apiraino commented on Sep 4, 2025

    @apiraino
    Contributor

    Assigning priority (discussion on Zulip).

    @rustbot label -I-prioritize +P-high

  7. added
    P-highHigh priority
    and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Sep 4, 2025
  8. aeubanks commented on Sep 17, 2025

    @aeubanks
    Contributor

    any update on this? we have #144086 reverted in our ToT rustc build but that's not sustainable

  9. wesleywiser commented on Sep 18, 2025

    @wesleywiser
    Member

    Visited during compiler team triage meeting, we recommend considering a revert & re-apply of the injecting PR after this issue has been resolved.

  10. nikic commented on Sep 18, 2025

    @nikic
    Contributor

    Forwarding from Zulip: If no global_allocator is specified the function definitions are generated at:

    pub(crate) unsafe fn codegen(
    tcx: TyCtxt<'_>,
    cx: SimpleCx<'_>,
    module_name: &str,
    kind: AllocatorKind,
    alloc_error_handler_kind: AllocatorKind,
    ) {
    let usize = match tcx.sess.target.pointer_width {
    16 => cx.type_i16(),
    32 => cx.type_i32(),
    64 => cx.type_i64(),
    tws => bug!("Unsupported target word size for int: {}", tws),
    };
    let i8 = cx.type_i8();
    let i8p = cx.type_ptr();
    if kind == AllocatorKind::Default {
    for method in ALLOCATOR_METHODS {
    let mut args = Vec::with_capacity(method.inputs.len());
    for input in method.inputs.iter() {
    match input.ty {
    AllocatorTy::Layout => {
    args.push(usize); // size
    args.push(usize); // align
    }
    AllocatorTy::Ptr => args.push(i8p),
    AllocatorTy::Usize => args.push(usize),
    AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
    }
    }
    let output = match method.output {
    AllocatorTy::ResultPtr => Some(i8p),
    AllocatorTy::Unit => None,
    AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
    panic!("invalid allocator output")
    }
    };
    let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
    let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
    create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false);
    }
    }
    If global_allocator is specified it happens in the macro expansion, which is this file I believe: https://github.com/rust-lang/rust/blob/master/compiler/rustc_builtin_macros/src/global_allocator.rs So I guess we need to expand
    fn attrs(&self) -> AttrVec {
    thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
    }
    to include the usual allocator attributes.

    Alternatively we could also drop the verifier checks on the LLVM side -- they are not required for correctness. Though it sounds like this did highlight a legitimate problem in this case.

  11. 10 remaining items

  12. added a commit that references this issue on Sep 25, 2025
  13. nikic commented on Sep 25, 2025

    @nikic
    Contributor

    @aeubanks Could you please confirm whether #146766 does indeed fix the original issue you saw?

  14. added 2 commits that reference this issue on Sep 27, 2025
  15. added 2 commits that reference this issue on Sep 29, 2025
  16. added a commit that references this issue on Sep 30, 2025
  17. added this to the 1.91.0 milestone on Oct 1, 2025
  18. wesleywiser commented on Oct 9, 2025

    @wesleywiser
    Member

    #147030 was merged to beta to revert the injecting PR and #147150 was merged to master to fix the actual issue thus I believe this can be closed.

    @aeubanks if you are still observing this issue on beta or nightly, please let us know so we can reopen. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-LTOArea: Link-time optimization (LTO)C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions