Skip to content

Box::new(uninitialized) creates a big alloca #58201

Closed

Description

@RalfJung

The following code

pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024*1024]>> { unsafe {
    // CHECK-LABEL: @box_uninitialized2
    // CHECK-NOT: store
    // CHECK-NOT: alloca
    // CHECK-NOT: memcpy
    // CHECK-NOT: memset
    Box::new(std::mem::uninitialized())
} }

generates some really awful LLVM IR:

start:
  %_1.sroa.0 = alloca [1048576 x i64], align 8
  %_1.sroa.0.0.sroa_cast3 = bitcast [1048576 x i64]* %_1.sroa.0 to i8*
  call void @llvm.lifetime.start.p0i8(i64 8388608, i8* nonnull %_1.sroa.0.0.sroa_cast3)
  %0 = tail call i8* @__rust_alloc(i64 8388608, i64 8) #3, !noalias !1
  %1 = icmp eq i8* %0, null
  br i1 %1, label %bb7.i.i, label %"_ZN35_$LT$alloc..boxed..Box$LT$T$GT$$GT$3new17h9460275a68e769e0E.exit"

bb7.i.i:                                          ; preds = %start
; call alloc::alloc::handle_alloc_error
  tail call void @_ZN5alloc5alloc18handle_alloc_error17h3b023122fefb532cE(i64 8388608, i64 8) #3, !noalias !1
  unreachable

"_ZN35_$LT$alloc..boxed..Box$LT$T$GT$$GT$3new17h9460275a68e769e0E.exit": ; preds = %start
  %2 = bitcast i8* %0 to %"core::mem::MaybeUninit<[usize; 1048576]>"*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 %0, i8* nonnull align 8 %_1.sroa.0.0.sroa_cast3, i64 8388608, i1 false)
  call void @llvm.lifetime.end.p0i8(i64 8388608, i8* nonnull %_1.sroa.0.0.sroa_cast3)
  ret %"core::mem::MaybeUninit<[usize; 1048576]>"* %2

The same happens with std::mem::MaybeUninit::uninitialized().

Cc @arielb1, who made me write these tests, and @rust-lang/wg-codegen

Activity

  1. added
    I-slowIssue: Problems and improvements with respect to performance of generated code.
    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
    on Feb 6, 2019
  2. arielb1 commented on Feb 6, 2019

    @arielb1
    Contributor

    Feels like an LLVM limitation to me. It should be replacing the memcpy with a memset(%0, 8388608, undef) (or a memset of poison when that becomes available).

  3. nikic commented on Feb 7, 2019

    @nikic
    Contributor

    For reference: https://rust.godbolt.org/z/6ea0aL

    LLVM is capable of optimizing a memcpy of undef alloca away, this just runs into the usual limitation that all of memcpyopt doesn't work across BBs.

  4. arielb1 commented on Feb 7, 2019

    @arielb1
    Contributor

    LLVM is capable of optimizing a memcpy of undef alloca away, this just runs into the usual limitation that all of memcpyopt doesn't work across BBs.

    This is such a long-standing issue. Seems like it might be wise to have someone working on fixing this.

  5. nikic commented on Feb 7, 2019

    @nikic
    Contributor

    @arielb1 Someone has already worked on this, see https://reviews.llvm.org/D38374. It's a bit hard to track, but unfortunately this got reverted again (multiple times). I suspect that this is only going to get really resolved once memcpyopt moves to memssa -- which someone has also worked on in the past (https://reviews.llvm.org/D26739), but which never really went anywhere.

  6. self-assigned this
    on Oct 17, 2020
  7. nikic commented on Mar 12, 2021

    @nikic
    Contributor

    The alloca and memcpy are no longer present on nightly, as a result of #82806.

  8. Noratrieb commented on Dec 30, 2022

    @Noratrieb
    Member

    The FIXME in the test is still there, needs a test.

  9. added a commit that references this issue on Jan 4, 2023
    3361247
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-boxArea: Our favorite opsem complicationI-slowIssue: Problems and improvements with respect to performance of generated code.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions