{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/28766","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/28766/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/28766/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/28766/events","html_url":"https://github.com/rust-lang/rust/issues/28766","id":109147474,"number":28766,"title":"Compiler segfaults when boxing a ZST from an external crate","user":{"login":"kylewlacy","id":1362179,"avatar_url":"https://avatars.githubusercontent.com/u/1362179?v=3","gravatar_id":"","url":"https://api.github.com/users/kylewlacy","html_url":"https://github.com/kylewlacy","followers_url":"https://api.github.com/users/kylewlacy/followers","following_url":"https://api.github.com/users/kylewlacy/following{/other_user}","gists_url":"https://api.github.com/users/kylewlacy/gists{/gist_id}","starred_url":"https://api.github.com/users/kylewlacy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kylewlacy/subscriptions","organizations_url":"https://api.github.com/users/kylewlacy/orgs","repos_url":"https://api.github.com/users/kylewlacy/repos","events_url":"https://api.github.com/users/kylewlacy/events{/privacy}","received_events_url":"https://api.github.com/users/kylewlacy/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/I-ICE","name":"I-ICE","color":"e10c02"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-09-30T18:06:16Z","updated_at":"2015-10-07T18:13:58Z","closed_at":null,"body":"# Demonstration\r\n\r\nI uploaded a repo with the simplest possible case I could come up with that demonstrates this issue [here](https://github.com/kylewlacy/rust-segfault). Here's how it works:\r\n\r\n```sh\r\n$ rustc --version --verbose\r\n    rustc 1.4.0-dev (d2e13e822 2015-09-15)\r\n    binary: rustc\r\n    commit-hash: d2e13e822a73e0ea46ae9e21afdd3155fc997f6d\r\n    commit-date: 2015-09-15\r\n    host: x86_64-apple-darwin\r\n    release: 1.4.0-dev\r\n$ git clone https://github.com/kylewlacy/rust-segfault.git\r\n$ cd rust-segfault\r\n$ cargo build --release --verbose\r\n   Compiling my_crate v0.1.0 (file:///Users/kyle/Desktop/rust-segfault)\r\n     Running `rustc my_crate/src/lib.rs --crate-name my_crate --crate-type lib -C opt-level=3 -C metadata=ab97f46dd8433ebe -C extra-filename=-ab97f46dd8433ebe --out-dir /Users/kyle/Desktop/rust-segfault/target/release/deps --emit=dep-info,link -L dependency=/Users/kyle/Desktop/rust-segfault/target/release/deps -L dependency=/Users/kyle/Desktop/rust-segfault/target/release/deps`\r\n   Compiling segfault v0.1.0 (file:///Users/kyle/Desktop/rust-segfault)\r\n     Running `rustc src/lib.rs --crate-name segfault --crate-type lib -C opt-level=3 --out-dir /Users/kyle/Desktop/rust-segfault/target/release --emit=dep-info,link -L dependency=/Users/kyle/Desktop/rust-segfault/target/release -L dependency=/Users/kyle/Desktop/rust-segfault/target/release/deps --extern my_crate=/Users/kyle/Desktop/rust-segfault/target/release/deps/libmy_crate-ab97f46dd8433ebe.rlib`\r\nCould not compile `segfault`.\r\n\r\nCaused by:\r\n  Process didn't exit successfully: `rustc src/lib.rs --crate-name segfault --crate-type lib -C opt-level=3 --out-dir /Users/kyle/Desktop/rust-segfault/target/release --emit=dep-info,link -L dependency=/Users/kyle/Desktop/rust-segfault/target/release -L dependency=/Users/kyle/Desktop/rust-segfault/target/release/deps --extern my_crate=/Users/kyle/Desktop/rust-segfault/target/release/deps/libmy_crate-ab97f46dd8433ebe.rlib` (signal: 11)\r\n```\r\n\r\n# Explanation\r\n\r\nSo I have a crate in my project, brilliantly named `my_crate`. `my_crate` is pretty simple, it contains a struct, called `Foo`, made up of zero-sized types. `Foo` also has a constructor function called `Foo::new()`:\r\n\r\n```rust\r\n// my_crate/lib.rs\r\npub struct Foo(());\r\n\r\nimpl Foo {\r\n    fn new() -> Self {\r\n        Foo(())\r\n    }\r\n}\r\n``` \r\n\r\nNow, in my library, `segfault`, I have a single function, called `box_foo()`, that just returns a `Box<Foo>`. It constructs a `Foo`, then boxes it:\r\n\r\n```rust\r\n// segfault/lib.rs\r\nextern crate my_crate;\r\nuse my_crate::Foo;\r\n\r\npub fn box_foo() -> Box<Foo> {\r\n    Box::new(Foo::new())\r\n}\r\n```\r\n\r\nWell, that's about it. Building `segfault` and `my_crate` with `cargo build` works perfectly fine. However, `cargo build --release` crashes with a signal 11, a segfault.\r\n\r\n# Some observations\r\n\r\n- `Foo` must be a zero-sized type, but cannot be a unit struct\r\n- `Foo` must be constructed with a function (e.g `Box::new(Foo(())` would not segfault)\r\n- `Foo` must be from another crate\r\n- The segfault only occurs if `box_foo()` is public (otherwise it's dead code, and I guess `rustc` doesn't even attempt to compile it?)\r\n- The segfault only occurs when optimizing the outer library\r\n- The optimization level doesn't matter, it just has to be >0\r\n- The constructor fn doesn't have to be in `impl Foo`, but it does have to come from `my_crate`\r\n- The fn that creates the box has to be in the outer library (e.g. `let boxed: Box<Foo> = Foo::new_box();` would not segfault)\r\n- Using a newtype in place of `Foo` has the same issue\r\n- The crash is not caused by *returning* a `Box<Foo>`, but by *constructing* one with `Box::new`. That is, the following also causes a segfault:\r\n```rust\r\npub fn foo_ptr_mut() -> *mut Foo {\r\n    let boxed = Box::new(Foo::new());\r\n    Box::into_raw(boxed)\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/146282198","html_url":"https://github.com/rust-lang/rust/issues/28766#issuecomment-146282198","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/28766","id":146282198,"user":{"login":"arielb1","id":1830974,"avatar_url":"https://avatars.githubusercontent.com/u/1830974?v=3","gravatar_id":"","url":"https://api.github.com/users/arielb1","html_url":"https://github.com/arielb1","followers_url":"https://api.github.com/users/arielb1/followers","following_url":"https://api.github.com/users/arielb1/following{/other_user}","gists_url":"https://api.github.com/users/arielb1/gists{/gist_id}","starred_url":"https://api.github.com/users/arielb1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arielb1/subscriptions","organizations_url":"https://api.github.com/users/arielb1/orgs","repos_url":"https://api.github.com/users/arielb1/repos","events_url":"https://api.github.com/users/arielb1/events{/privacy}","received_events_url":"https://api.github.com/users/arielb1/received_events","type":"User","site_admin":false},"created_at":"2015-10-07T18:13:58Z","updated_at":"2015-10-07T18:13:58Z","body":"Problematic IR:\r\n```\r\n; ModuleID = 'segfault.0.rs'\r\ntarget datalayout = \"e-m:e-i64:64-f80:128-n8:16:32:64-S128\"\r\ntarget triple = \"x86_64-unknown-linux-gnu\"\r\n\r\n%\"9.my_crate::Foo\" = type { {} }\r\n\r\n; Function Attrs: uwtable\r\ndefine noalias %\"9.my_crate::Foo\"* @_ZN7box_foo20hf984887980016f2cgaaE() unnamed_addr #0 {\r\nentry-block:\r\n  %0 = tail call %\"9.my_crate::Foo\" @\"_ZN13_$LT$impl$GT$3new20h7a0183b89d396887kaaE\"()\r\n  ret %\"9.my_crate::Foo\"* inttoptr (i64 1 to %\"9.my_crate::Foo\"*)\r\n}\r\n\r\ndeclare %\"9.my_crate::Foo\" @\"_ZN13_$LT$impl$GT$3new20h7a0183b89d396887kaaE\"() unnamed_addr\r\n\r\nattributes #0 = { uwtable }\r\n```\r\n\r\nWhy is there a `tail call` followed by a `ret`? The unoptimized code is\r\n```\r\n; ModuleID = 'segfault.0.rs'\r\ntarget datalayout = \"e-m:e-i64:64-f80:128-n8:16:32:64-S128\"\r\ntarget triple = \"x86_64-unknown-linux-gnu\"\r\n\r\n%str_slice = type { i8*, i64 }\r\n%\"2.core::fmt::Formatter\" = type { i32, i32, i8, %\"2.core::option::Option<usize>\", %\"2.core::option::Option<usize>\", { i8*, void (i8*)** }, %\"2.core::slice::Iter<core::fmt::ArgumentV1>\", { %\"2.core::fmt::ArgumentV1\"*, i64 } }\r\n%\"2.core::option::Option<usize>\" = type { i64, [0 x i64], [1 x i64] }\r\n%\"2.core::slice::Iter<core::fmt::ArgumentV1>\" = type { %\"2.core::fmt::ArgumentV1\"*, %\"2.core::fmt::ArgumentV1\"*, %\"2.core::marker::PhantomData<&'static core::fmt::ArgumentV1>\" }\r\n%\"2.core::fmt::ArgumentV1\" = type { %\"2.core::fmt::Void\"*, i8 (%\"2.core::fmt::Void\"*, %\"2.core::fmt::Formatter\"*)* }\r\n%\"2.core::fmt::Void\" = type {}\r\n%\"2.core::marker::PhantomData<&'static core::fmt::ArgumentV1>\" = type {}\r\n%\"9.my_crate::Foo\" = type { {} }\r\n%\"2.core::fmt::Arguments\" = type { { %str_slice*, i64 }, %\"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>\", { %\"2.core::fmt::ArgumentV1\"*, i64 } }\r\n%\"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>\" = type { { %\"2.core::fmt::rt::v1::Argument\"*, i64 } }\r\n%\"2.core::fmt::rt::v1::Argument\" = type { %\"2.core::fmt::rt::v1::Position\", %\"2.core::fmt::rt::v1::FormatSpec\" }\r\n%\"2.core::fmt::rt::v1::Position\" = type { i64, [0 x i64], [1 x i64] }\r\n%\"2.core::fmt::rt::v1::FormatSpec\" = type { i32, i8, i32, %\"2.core::fmt::rt::v1::Count\", %\"2.core::fmt::rt::v1::Count\" }\r\n%\"2.core::fmt::rt::v1::Count\" = type { i64, [0 x i64], [1 x i64] }\r\n\r\n@const2476 = internal unnamed_addr constant i64 0\r\n@const2480 = internal unnamed_addr constant {}* inttoptr (i64 1 to {}*)\r\n@const2481 = internal unnamed_addr constant i8* inttoptr (i64 1 to i8*)\r\n@const2497 = internal unnamed_addr constant i8 1\r\n@_ZN4heap24check_size_and_alignment14_MSG_FILE_LINE20hc3b2d56120089136JbaE = external global { %str_slice, %str_slice, i32 }\r\n@const2504 = internal unnamed_addr constant i64 64\r\n@const2505 = internal unnamed_addr constant i64 -9223372036854775808\r\n@const2506 = internal unnamed_addr constant i64 9223372036854775807\r\n@const2514 = internal unnamed_addr constant { { i8*, i8* } } zeroinitializer\r\n@_ZN4heap24check_size_and_alignment15__STATIC_FMTSTR20hfa6992380310c546wcaE = external global { %str_slice*, i64 }\r\n@const2621 = internal unnamed_addr constant i8 (i64*, %\"2.core::fmt::Formatter\"*)* @\"_ZN3fmt3num13_$LT$impl$GT$3fmt20h61c12488bb3d5903AZVE\"\r\n@_ZN4heap24check_size_and_alignment10_FILE_LINE20hcf2a8ce10e9354d6gcaE = external global { %str_slice, i32 }\r\n@const2632 = internal unnamed_addr constant i64 1\r\n@_ZN4heap24check_size_and_alignment15__STATIC_FMTSTR20hfa6992380310c546qdaE = external global { %str_slice*, i64 }\r\n@_ZN4heap24check_size_and_alignment10_FILE_LINE20hcf2a8ce10e9354d6adaE = external global { %str_slice, i32 }\r\n@const2641 = internal unnamed_addr constant i8* null\r\n\r\n; Function Attrs: uwtable\r\ndefine noalias %\"9.my_crate::Foo\"* @_ZN7box_foo20hf984887980016f2cgaaE() unnamed_addr #0 {\r\nentry-block:\r\n  %0 = call %\"9.my_crate::Foo\" @\"_ZN13_$LT$impl$GT$3new20h7a0183b89d396887kaaE\"()\r\n  %1 = call i8* @_ZN4heap15exchange_malloc20h496cd3d208c78b0aJfaE(i64 0, i64 1)\r\n  %2 = bitcast i8* %1 to %\"9.my_crate::Foo\"*\r\n  ret %\"9.my_crate::Foo\"* %2\r\n}\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal i8* @_ZN4heap15exchange_malloc20h496cd3d208c78b0aJfaE(i64, i64) unnamed_addr #1 {\r\nentry-block:\r\n  %sret_slot = alloca i8*\r\n  %size = alloca i64\r\n  %align = alloca i64\r\n  %ptr = alloca i8*\r\n  %2 = alloca i8\r\n  store i64 %0, i64* %size, align 8\r\n  store i64 %1, i64* %align, align 8\r\n  %3 = load i64, i64* %size, align 8\r\n  %4 = icmp eq i64 %3, 0\r\n  br i1 %4, label %then-block-41-, label %else-block\r\n\r\nthen-block-41-:                                   ; preds = %entry-block\r\n  store i8* inttoptr (i64 1 to i8*), i8** %sret_slot, align 8\r\n  br label %join\r\n\r\nelse-block:                                       ; preds = %entry-block\r\n  %5 = load i64, i64* %size, align 8\r\n  %6 = load i64, i64* %align, align 8\r\n  %7 = call i8* @_ZN4heap8allocate20h8f9906da8b1122b2PdaE(i64 %5, i64 %6)\r\n  store i8* %7, i8** %ptr, align 8\r\n  %8 = load i8*, i8** %ptr, align 8\r\n  %9 = call zeroext i1 @\"_ZN3ptr13_$LT$impl$GT$7is_null7is_null21h14748829460356738718E\"(i8* %8)\r\n  %10 = zext i1 %9 to i8\r\n  store i8 %10, i8* %2, align 1\r\n  %11 = load i8, i8* %2, align 1, !range !0\r\n  %12 = trunc i8 %11 to i1\r\n  br i1 %12, label %then-block-59-, label %next-block\r\n\r\nthen-block-59-:                                   ; preds = %else-block\r\n  call void @_ZN3oom20hd9170b7f1397402fatbE()\r\n  unreachable\r\n\r\nnext-block:                                       ; preds = %else-block\r\n  %13 = load i8*, i8** %ptr, align 8\r\n  store i8* %13, i8** %sret_slot, align 8\r\n  br label %join\r\n\r\njoin:                                             ; preds = %next-block, %then-block-41-\r\n  %14 = load i8*, i8** %sret_slot, align 8\r\n  ret i8* %14\r\n}\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal i8* @_ZN4heap8allocate20h8f9906da8b1122b2PdaE(i64, i64) unnamed_addr #1 {\r\nentry-block:\r\n  %size.i = alloca i64\r\n  %align.i = alloca i64\r\n  %2 = alloca %\"2.core::fmt::Arguments\"\r\n  %3 = alloca { %str_slice*, i64 }\r\n  %4 = alloca [1 x %\"2.core::fmt::ArgumentV1\"]\r\n  %5 = alloca { i64* }\r\n  %match.i = alloca { i64* }\r\n  %__llmatch.i = alloca i64**\r\n  %__arg0.i = alloca i64*\r\n  %__coerce_target.i = alloca { %\"2.core::fmt::ArgumentV1\"*, i64 }\r\n  %6 = alloca i8\r\n  %7 = alloca %\"2.core::fmt::Arguments\"\r\n  %8 = alloca { %str_slice*, i64 }\r\n  %9 = alloca [1 x %\"2.core::fmt::ArgumentV1\"]\r\n  %10 = alloca { i64* }\r\n  %match2.i = alloca { i64* }\r\n  %__llmatch4.i = alloca i64**\r\n  %__arg05.i = alloca i64*\r\n  %__coerce_target7.i = alloca { %\"2.core::fmt::ArgumentV1\"*, i64 }\r\n  %size = alloca i64\r\n  %align = alloca i64\r\n  %__arg = alloca i64\r\n  %__arg1 = alloca i64\r\n  store i64 %0, i64* %size, align 8\r\n  store i64 %1, i64* %align, align 8\r\n  %11 = load i64, i64* %size, align 8\r\n  %12 = load i64, i64* %align, align 8\r\n  store i64 %11, i64* %size.i, align 8\r\n  store i64 %12, i64* %align.i, align 8\r\n  %13 = load i64, i64* %size.i, align 8\r\n  %14 = icmp ne i64 %13, 0\r\n  %15 = xor i1 %14, true\r\n  br i1 %15, label %then-block-112-.i, label %next-block.i\r\n\r\nthen-block-112-.i:                                ; preds = %entry-block\r\n  call void @_ZN9panicking5panic20h52df14a965b04688KKKE({ %str_slice, %str_slice, i32 }* noalias readonly dereferenceable(40) @_ZN4heap24check_size_and_alignment14_MSG_FILE_LINE20hc3b2d56120089136JbaE)\r\n  unreachable\r\n\r\nnext-block.i:                                     ; preds = %entry-block\r\n  %16 = load i64, i64* %size.i, align 8\r\n  %17 = icmp ule i64 %16, 9223372036854775807\r\n  %18 = xor i1 %17, true\r\n  br i1 %18, label %then-block-145-.i, label %next-block1.i\r\n\r\nthen-block-145-.i:                                ; preds = %next-block.i\r\n  %19 = bitcast { %str_slice*, i64 }* %3 to i8*\r\n  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %19, i8* bitcast ({ %str_slice*, i64 }* @_ZN4heap24check_size_and_alignment15__STATIC_FMTSTR20hfa6992380310c546wcaE to i8*), i64 16, i32 8, i1 false)\r\n  %20 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %3, i32 0, i32 0\r\n  %21 = load %str_slice*, %str_slice** %20\r\n  %22 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %3, i32 0, i32 1\r\n  %23 = load i64, i64* %22\r\n  %24 = getelementptr inbounds { i64* }, { i64* }* %5, i32 0, i32 0\r\n  store i64* %size.i, i64** %24, align 8\r\n  %25 = bitcast { i64* }* %5 to i64*\r\n  %26 = load i64, i64* %25, align 8\r\n  %27 = bitcast { i64* }* %match.i to i64*\r\n  store i64 %26, i64* %27, align 8\r\n  %28 = getelementptr inbounds { i64* }, { i64* }* %match.i, i32 0, i32 0\r\n  store i64** %28, i64*** %__llmatch.i\r\n  %29 = load i64**, i64*** %__llmatch.i\r\n  %30 = load i64*, i64** %29, align 8, !nonnull !1\r\n  store i64* %30, i64** %__arg0.i, align 8\r\n  %31 = getelementptr inbounds [1 x %\"2.core::fmt::ArgumentV1\"], [1 x %\"2.core::fmt::ArgumentV1\"]* %4, i32 0, i32 0\r\n  %32 = load i64*, i64** %__arg0.i, align 8, !nonnull !1\r\n  call void @\"_ZN3fmt13_$LT$impl$GT$3new3new20h4621647584932494472E\"(%\"2.core::fmt::ArgumentV1\"* noalias nocapture sret dereferenceable(16) %31, i64* noalias readonly dereferenceable(8) %32, i8 (i64*, %\"2.core::fmt::Formatter\"*)* @\"_ZN3fmt3num13_$LT$impl$GT$3fmt20h61c12488bb3d5903AZVE\")\r\n  %33 = bitcast [1 x %\"2.core::fmt::ArgumentV1\"]* %4 to %\"2.core::fmt::ArgumentV1\"*\r\n  %34 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target.i, i32 0, i32 0\r\n  store %\"2.core::fmt::ArgumentV1\"* %33, %\"2.core::fmt::ArgumentV1\"** %34\r\n  %35 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target.i, i32 0, i32 1\r\n  store i64 1, i64* %35\r\n  %36 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target.i, i32 0, i32 0\r\n  %37 = load %\"2.core::fmt::ArgumentV1\"*, %\"2.core::fmt::ArgumentV1\"** %36\r\n  %38 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target.i, i32 0, i32 1\r\n  %39 = load i64, i64* %38\r\n  call void @\"_ZN3fmt13_$LT$impl$GT$6new_v120h5e9764a905143b40HJWE\"(%\"2.core::fmt::Arguments\"* noalias nocapture sret dereferenceable(48) %2, %str_slice* noalias nonnull readonly %21, i64 %23, %\"2.core::fmt::ArgumentV1\"* noalias nonnull readonly %37, i64 %39)\r\n  call void @_ZN9panicking9panic_fmt20h9106226f5abb116edMKE(%\"2.core::fmt::Arguments\"* noalias nocapture dereferenceable(48) %2, { %str_slice, i32 }* noalias readonly dereferenceable(24) @_ZN4heap24check_size_and_alignment10_FILE_LINE20hcf2a8ce10e9354d6gcaE)\r\n  unreachable\r\n\r\nnext-block1.i:                                    ; preds = %next-block.i\r\n  %40 = load i64, i64* %align.i, align 8\r\n  %41 = call zeroext i1 @\"_ZN3num13_$LT$impl$GT$15is_power_of_two20hcabd0a0fb3e6b19ar8iE\"(i64 %40)\r\n  %42 = zext i1 %41 to i8\r\n  store i8 %42, i8* %6, align 1\r\n  %43 = load i8, i8* %6, align 1, !range !0\r\n  %44 = trunc i8 %43 to i1\r\n  %45 = xor i1 %44, true\r\n  br i1 %45, label %then-block-201-.i, label %_ZN4heap24check_size_and_alignment20hfe4e6278eec1ce19mbaE.exit\r\n\r\nthen-block-201-.i:                                ; preds = %next-block1.i\r\n  %46 = bitcast { %str_slice*, i64 }* %8 to i8*\r\n  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %46, i8* bitcast ({ %str_slice*, i64 }* @_ZN4heap24check_size_and_alignment15__STATIC_FMTSTR20hfa6992380310c546qdaE to i8*), i64 16, i32 8, i1 false)\r\n  %47 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %8, i32 0, i32 0\r\n  %48 = load %str_slice*, %str_slice** %47\r\n  %49 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %8, i32 0, i32 1\r\n  %50 = load i64, i64* %49\r\n  %51 = getelementptr inbounds { i64* }, { i64* }* %10, i32 0, i32 0\r\n  store i64* %align.i, i64** %51, align 8\r\n  %52 = bitcast { i64* }* %10 to i64*\r\n  %53 = load i64, i64* %52, align 8\r\n  %54 = bitcast { i64* }* %match2.i to i64*\r\n  store i64 %53, i64* %54, align 8\r\n  %55 = getelementptr inbounds { i64* }, { i64* }* %match2.i, i32 0, i32 0\r\n  store i64** %55, i64*** %__llmatch4.i\r\n  %56 = load i64**, i64*** %__llmatch4.i\r\n  %57 = load i64*, i64** %56, align 8, !nonnull !1\r\n  store i64* %57, i64** %__arg05.i, align 8\r\n  %58 = getelementptr inbounds [1 x %\"2.core::fmt::ArgumentV1\"], [1 x %\"2.core::fmt::ArgumentV1\"]* %9, i32 0, i32 0\r\n  %59 = load i64*, i64** %__arg05.i, align 8, !nonnull !1\r\n  call void @\"_ZN3fmt13_$LT$impl$GT$3new3new20h4621647584932494472E\"(%\"2.core::fmt::ArgumentV1\"* noalias nocapture sret dereferenceable(16) %58, i64* noalias readonly dereferenceable(8) %59, i8 (i64*, %\"2.core::fmt::Formatter\"*)* @\"_ZN3fmt3num13_$LT$impl$GT$3fmt20h61c12488bb3d5903AZVE\")\r\n  %60 = bitcast [1 x %\"2.core::fmt::ArgumentV1\"]* %9 to %\"2.core::fmt::ArgumentV1\"*\r\n  %61 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target7.i, i32 0, i32 0\r\n  store %\"2.core::fmt::ArgumentV1\"* %60, %\"2.core::fmt::ArgumentV1\"** %61\r\n  %62 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target7.i, i32 0, i32 1\r\n  store i64 1, i64* %62\r\n  %63 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target7.i, i32 0, i32 0\r\n  %64 = load %\"2.core::fmt::ArgumentV1\"*, %\"2.core::fmt::ArgumentV1\"** %63\r\n  %65 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %__coerce_target7.i, i32 0, i32 1\r\n  %66 = load i64, i64* %65\r\n  call void @\"_ZN3fmt13_$LT$impl$GT$6new_v120h5e9764a905143b40HJWE\"(%\"2.core::fmt::Arguments\"* noalias nocapture sret dereferenceable(48) %7, %str_slice* noalias nonnull readonly %48, i64 %50, %\"2.core::fmt::ArgumentV1\"* noalias nonnull readonly %64, i64 %66)\r\n  call void @_ZN9panicking9panic_fmt20h9106226f5abb116edMKE(%\"2.core::fmt::Arguments\"* noalias nocapture dereferenceable(48) %7, { %str_slice, i32 }* noalias readonly dereferenceable(24) @_ZN4heap24check_size_and_alignment10_FILE_LINE20hcf2a8ce10e9354d6adaE)\r\n  unreachable\r\n\r\n_ZN4heap24check_size_and_alignment20hfe4e6278eec1ce19mbaE.exit: ; preds = %next-block1.i\r\n  %67 = load i64, i64* %size, align 8\r\n  %68 = load i64, i64* %align, align 8\r\n  store i64 %67, i64* %__arg, align 8\r\n  %69 = load i64, i64* %__arg\r\n  store i64 %68, i64* %__arg1, align 8\r\n  %70 = load i64, i64* %__arg1\r\n  %71 = call i8* @__rust_allocate(i64 %69, i64 %70)\r\n  ret i8* %71\r\n}\r\n\r\n; Function Attrs: cold noinline noreturn\r\ndeclare void @_ZN9panicking5panic20h52df14a965b04688KKKE({ %str_slice, %str_slice, i32 }* noalias readonly dereferenceable(40)) unnamed_addr #2\r\n\r\n; Function Attrs: cold noinline noreturn\r\ndeclare void @_ZN9panicking9panic_fmt20h9106226f5abb116edMKE(%\"2.core::fmt::Arguments\"* noalias nocapture dereferenceable(48), { %str_slice, i32 }* noalias readonly de\r\nreferenceable(24)) unnamed_addr #2\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal void @\"_ZN3fmt13_$LT$impl$GT$6new_v120h5e9764a905143b40HJWE\"(%\"2.core::fmt::Arguments\"* noalias nocapture sret dereferenceable(48), %str_slice* noalias nonnull readonly, i64, %\"2.core::fmt::ArgumentV1\"* noalias nonnull readonly, i64) unnamed_addr #1 {\r\nentry-block:\r\n  %pieces = alloca { %str_slice*, i64 }\r\n  %args = alloca { %\"2.core::fmt::ArgumentV1\"*, i64 }\r\n  %5 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %pieces, i32 0, i32 0\r\n  store %str_slice* %1, %str_slice** %5\r\n  %6 = getelementptr inbounds { %str_slice*, i64 }, { %str_slice*, i64 }* %pieces, i32 0, i32 1\r\n  store i64 %2, i64* %6\r\n  %7 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %args, i32 0, i32 0\r\n  store %\"2.core::fmt::ArgumentV1\"* %3, %\"2.core::fmt::ArgumentV1\"** %7\r\n  %8 = getelementptr inbounds { %\"2.core::fmt::ArgumentV1\"*, i64 }, { %\"2.core::fmt::ArgumentV1\"*, i64 }* %args, i32 0, i32 1\r\n  store i64 %4, i64* %8\r\n  %9 = getelementptr inbounds %\"2.core::fmt::Arguments\", %\"2.core::fmt::Arguments\"* %0, i32 0, i32 0\r\n  %10 = bitcast { %str_slice*, i64 }* %pieces to i8*\r\n  %11 = bitcast { %str_slice*, i64 }* %9 to i8*\r\n  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %11, i8* %10, i64 16, i32 8, i1 false)\r\n  %12 = getelementptr inbounds %\"2.core::fmt::Arguments\", %\"2.core::fmt::Arguments\"* %0, i32 0, i32 1\r\n  %13 = bitcast %\"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>\"* %12 to { { i8*, i8* } }*\r\n  %14 = bitcast { { i8*, i8* } }* %13 to i8*\r\n  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %14, i8* bitcast ({ { i8*, i8* } }* @const2514 to i8*), i64 16, i32 8, i1 false)\r\n  %15 = getelementptr inbounds %\"2.core::fmt::Arguments\", %\"2.core::fmt::Arguments\"* %0, i32 0, i32 2\r\n  %16 = bitcast { %\"2.core::fmt::ArgumentV1\"*, i64 }* %args to i8*\r\n  %17 = bitcast { %\"2.core::fmt::ArgumentV1\"*, i64 }* %15 to i8*\r\n  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %17, i8* %16, i64 16, i32 8, i1 false)\r\n  ret void\r\n}\r\n\r\n; Function Attrs: nounwind\r\ndeclare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #3\r\n\r\n; Function Attrs: uwtable\r\ndefine internal void @\"_ZN3fmt13_$LT$impl$GT$3new3new20h4621647584932494472E\"(%\"2.core::fmt::ArgumentV1\"* noalias nocapture sret dereferenceable(16), i64* noalias readonly dereferenceable(8), i8 (i64*, %\"2.core::fmt::Formatter\"*)*) unnamed_addr #0 {\r\nentry-block:\r\n  %x = alloca i64*\r\n  %f = alloca i8 (i64*, %\"2.core::fmt::Formatter\"*)*\r\n  store i64* %1, i64** %x, align 8\r\n  store i8 (i64*, %\"2.core::fmt::Formatter\"*)* %2, i8 (i64*, %\"2.core::fmt::Formatter\"*)** %f, align 8\r\n  %3 = getelementptr inbounds %\"2.core::fmt::ArgumentV1\", %\"2.core::fmt::ArgumentV1\"* %0, i32 0, i32 1\r\n  %4 = load i8 (i64*, %\"2.core::fmt::Formatter\"*)*, i8 (i64*, %\"2.core::fmt::Formatter\"*)** %f, align 8\r\n  %5 = bitcast i8 (i64*, %\"2.core::fmt::Formatter\"*)* %4 to i8 (%\"2.core::fmt::Void\"*, %\"2.core::fmt::Formatter\"*)*\r\n  store i8 (%\"2.core::fmt::Void\"*, %\"2.core::fmt::Formatter\"*)* %5, i8 (%\"2.core::fmt::Void\"*, %\"2.core::fmt::Formatter\"*)** %3\r\n  %6 = getelementptr inbounds %\"2.core::fmt::ArgumentV1\", %\"2.core::fmt::ArgumentV1\"* %0, i32 0, i32 0\r\n  %7 = load i64*, i64** %x, align 8, !nonnull !1\r\n  %8 = bitcast i64* %7 to %\"2.core::fmt::Void\"*\r\n  store %\"2.core::fmt::Void\"* %8, %\"2.core::fmt::Void\"** %6\r\n  ret void\r\n}\r\n\r\ndeclare i8 @\"_ZN3fmt3num13_$LT$impl$GT$3fmt20h61c12488bb3d5903AZVE\"(i64* noalias readonly dereferenceable(8), %\"2.core::fmt::Formatter\"* noalias dereferenceable(96)) unnamed_addr\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal zeroext i1 @\"_ZN3num13_$LT$impl$GT$15is_power_of_two20hcabd0a0fb3e6b19ar8iE\"(i64) unnamed_addr #1 {\r\nentry-block:\r\n  %self = alloca i64\r\n  %1 = alloca i64\r\n  %2 = alloca i64\r\n  %3 = alloca i64\r\n  %4 = alloca i64\r\n  store i64 %0, i64* %self, align 8\r\n  %5 = load i64, i64* %self, align 8\r\n  %6 = call i64 @\"_ZN3num13_$LT$impl$GT$3one20h790da5113c87c0645lhE\"()\r\n  store i64 %6, i64* %2, align 8\r\n  %7 = load i64, i64* %2, align 8\r\n  %8 = call i64 @\"_ZN3num13_$LT$impl$GT$12wrapping_sub20h362106a5499b8ea7s5iE\"(i64 %5, i64 %7)\r\n  store i64 %8, i64* %1, align 8\r\n  %9 = load i64, i64* %1, align 8\r\n  %10 = load i64, i64* %self, align 8\r\n  %11 = and i64 %9, %10\r\n  %12 = call i64 @\"_ZN3num13_$LT$impl$GT$4zero20hc4254551c8413675WlhE\"()\r\n  store i64 %12, i64* %3, align 8\r\n  %13 = load i64, i64* %3, align 8\r\n  %14 = icmp eq i64 %11, %13\r\n  br i1 %14, label %before_rhs, label %join\r\n\r\njoin:                                             ; preds = %before_rhs, %entry-block\r\n  %15 = phi i1 [ %14, %entry-block ], [ %22, %before_rhs ]\r\n  %16 = zext i1 %15 to i8\r\n  %17 = trunc i8 %16 to i1\r\n  ret i1 %17\r\n\r\nbefore_rhs:                                       ; preds = %entry-block\r\n  %18 = load i64, i64* %self, align 8\r\n  %19 = call i64 @\"_ZN3num13_$LT$impl$GT$4zero20hc4254551c8413675WlhE\"()\r\n  store i64 %19, i64* %4, align 8\r\n  %20 = load i64, i64* %4, align 8\r\n  %21 = icmp eq i64 %18, %20\r\n  %22 = xor i1 %21, true\r\n  br label %join\r\n}\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal i64 @\"_ZN3num13_$LT$impl$GT$12wrapping_sub20h362106a5499b8ea7s5iE\"(i64, i64) unnamed_addr #1 {\r\nentry-block:\r\n  %self = alloca i64\r\n  %rhs = alloca i64\r\n  store i64 %0, i64* %self, align 8\r\n  store i64 %1, i64* %rhs, align 8\r\n  %2 = load i64, i64* %self, align 8\r\n  %3 = load i64, i64* %rhs, align 8\r\n  %4 = sub i64 %2, %3\r\n  ret i64 %4\r\n}\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal i64 @\"_ZN3num13_$LT$impl$GT$3one20h790da5113c87c0645lhE\"() unnamed_addr #1 {\r\nentry-block:\r\n  ret i64 1\r\n}\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal i64 @\"_ZN3num13_$LT$impl$GT$4zero20hc4254551c8413675WlhE\"() unnamed_addr #1 {\r\nentry-block:\r\n  ret i64 0\r\n}\r\n\r\n; Function Attrs: nounwind\r\ndeclare noalias i8* @__rust_allocate(i64, i64) unnamed_addr #3\r\n\r\n; Function Attrs: inlinehint uwtable\r\ndefine internal zeroext i1 @\"_ZN3ptr13_$LT$impl$GT$7is_null7is_null21h14748829460356738718E\"(i8*) unnamed_addr #1 {\r\nentry-block:\r\n  %self = alloca i8*\r\n  store i8* %0, i8** %self, align 8\r\n  %1 = load i8*, i8** %self, align 8\r\n  %2 = icmp eq i8* %1, null\r\n  %3 = zext i1 %2 to i8\r\n  %4 = trunc i8 %3 to i1\r\n  ret i1 %4\r\n}\r\n\r\n; Function Attrs: cold noinline noreturn\r\ndeclare void @_ZN3oom20hd9170b7f1397402fatbE() unnamed_addr #2\r\n\r\ndeclare %\"9.my_crate::Foo\" @\"_ZN13_$LT$impl$GT$3new20h7a0183b89d396887kaaE\"() unnamed_addr\r\n\r\nattributes #0 = { uwtable }\r\nattributes #1 = { inlinehint uwtable }\r\nattributes #2 = { cold noinline noreturn }\r\nattributes #3 = { nounwind }\r\n\r\n!0 = !{i8 0, i8 2}\r\n!1 = !{}\r\n```\r\n\r\nand compiles on vanilla and rustc"}}