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

Box<T, &A> and LTO: Explicit gep type does not match pointee type of pointer operand #95036

Closed
exrook opened this issue Mar 17, 2022 · 7 comments · Fixed by #95328
Closed

Box<T, &A> and LTO: Explicit gep type does not match pointee type of pointer operand #95036

exrook opened this issue Mar 17, 2022 · 7 comments · Fixed by #95328
Assignees
Labels
A-allocators Area: Custom and system allocators A-lto Area: Link Time Optimization C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@exrook
Copy link
Contributor

exrook commented Mar 17, 2022

Code

Only when building with lto = thin or lto = fat do I trigger this issue. Found while working on #77438.
Compile test that triggers the issue: exrook@b2652ba

lto_box_allocator/lib.rs

#![feature(allocator_api)]
#![feature(bench_black_box)]
use std::alloc::Global;
use std::hint::black_box;

pub fn f() {
    let mut node = Box::new_in(Node {
        v: &(),
        b: false,
    }, &Global);
    node.b = true;
    black_box(node); // without this bug only triggers when built without optimizations
}

struct Node {
    v: &'static (),
    b: bool,
}

box_consumer/main.rs

extern crate lto_box_allocator;

fn main() {
    lto_box_allocator::f();
}

Meta

rustc --version --verbose:

rustc 1.61.0-nightly (458262b13 2022-03-09)
binary: rustc
commit-hash: 458262b1315e0de7be940fe95e111bb045e4a2a4
commit-date: 2022-03-09
host: x86_64-unknown-linux-gnu
release: 1.61.0-nightly
LLVM version: 14.0.0

Error output

lto=thin

error: failed to prepare thin LTO module: Explicit gep type does not match pointee type of pointer operand (Producer: 'LLVM14.0.0-rust-dev' Reader: 'LLVM 14.0.0-rust-dev')

error: aborting due to previous error

lto=fat

warning: Explicit gep type does not match pointee type of pointer operand (Producer: 'LLVM14.0.0-rust-dev' Reader: 'LLVM 14.0.0-rust-dev')

error: failed to load bitcode of module "lto-box-allocator.lto_box_allocator.c2c2224e-cgu.0.rcgu.o":

error: aborting due to previous error; 1 warning emitted
@exrook exrook added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 17, 2022
@exrook
Copy link
Contributor Author

exrook commented Mar 17, 2022

@rustbot modify labels: +A-allocators +A-lto

@rustbot rustbot added A-allocators Area: Custom and system allocators A-lto Area: Link Time Optimization labels Mar 17, 2022
@beepster4096
Copy link
Contributor

@rustbot claim

1 similar comment
@beepster4096
Copy link
Contributor

@rustbot claim

@exrook
Copy link
Contributor Author

exrook commented Mar 24, 2022

Hey @drmeepster thanks for looking into this bug (and for fixing my last reports as well :)).
I've figured out some more information since first posting this.

I'm able to reproduce the bug in a single crate when compiling with codegen-units > 1 and further minimized the triggering code:

pub fn test() {
    let mut node = Box::new_in([5u8], &Global);
    node[0] = 7u8;
    black_box(node);
}

The bug seems to be specifically triggered when the allocator is non zero-sized, it doesn't matter whether it's a reference or not.
Additionally if the boxed type is a struct or tuple, only accessing past the first non-zero field triggers the bug.

Attempting to disassemble the bitcode dumped with RUSTFLAGS="-C save-temps" with llvm-dis gives the same Explicit gep type.. error, unless I pass the --opaque-pointers flag which causes the disassembly to succeed.

The offending store instruction is encoded as follows:

  %17 = getelementptr inbounds [1 x i8], ptr %11, i64 0, i64 0, !dbg !919
  store i8 7, ptr %17, align 1, !dbg !919

Unfortunately the --opaque-pointers flag strips all pointer types from the input, turning them to ptr in the output, so I do not know what the original type was that is causing the issue.

Using the following which doesn't trigger the issue:

pub fn test() {
    let mut node = Box::new_in([5u8], Global);
    node[0] = 7u8;
    black_box(node);
}

llvm-dis without --opaque-pointers gives:

  %13 = getelementptr inbounds [1 x i8], [1 x i8]* %10, i64 0, i64 0, !dbg !632
  store i8 7, i8* %13, align 1, !dbg !632

@beepster4096
Copy link
Contributor

Thanks for the info and minimized code! That's gonna make this easier.

@beepster4096
Copy link
Contributor

I still don't know how this actually happens, I just know that the change in #95328 fixes it. I suspect it's some code assuming that a wide box is always a wide pointer, but I don't know where...

@exrook
Copy link
Contributor Author

exrook commented Mar 26, 2022

I think you're right about that assumption, using a wide pointer in the box has no issues:

pub fn test_l3(mut node: Box<[u8], &Global>) {
    node[0] = 7;
    black_box(node);
}

@bors bors closed this as completed in ce319ac Mar 28, 2022
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Jun 15, 2022
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jun 15, 2022
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-allocators Area: Custom and system allocators A-lto Area: Link Time Optimization C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants