forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#83698 - erikdesjardins:undefconst, r=oli-obk
Use undef for uninitialized bytes in constants Fixes rust-lang#83657 This generates good code when the const is fully uninit, e.g. ```rust #[no_mangle] pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> { const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit(); M } ``` generates ```asm fully_uninit: ret ``` as you would expect. There is no improvement, however, when it's partially uninit, e.g. ```rust pub struct PartiallyUninit { x: u64, y: MaybeUninit<[u8; 10]> } #[no_mangle] pub const fn partially_uninit() -> PartiallyUninit { const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeefcafe, y: MaybeUninit::uninit() }; X } ``` generates ```asm partially_uninit: mov rax, rdi mov rcx, qword ptr [rip + .L__unnamed_1+16] mov qword ptr [rdi + 16], rcx movups xmm0, xmmword ptr [rip + .L__unnamed_1] movups xmmword ptr [rdi], xmm0 ret .L__unnamed_1: .asciz "\376\312\357\276\255\336\000" .zero 16 .size .L__unnamed_1, 24 ``` which copies a bunch of zeros in place of the undef bytes, the same as before this change. The constant is undef where it should be, though (see the added test) so this seems to be a missed optimization in LLVM.
- Loading branch information
Showing
7 changed files
with
160 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// compile-flags: -C no-prepopulate-passes | ||
// ignore-tidy-linelength | ||
|
||
// Check that we use undef (and not zero) for uninitialized bytes in constants. | ||
|
||
#![crate_type = "lib"] | ||
|
||
use std::mem::MaybeUninit; | ||
|
||
pub struct PartiallyUninit { | ||
x: u32, | ||
y: MaybeUninit<[u8; 10]> | ||
} | ||
|
||
// CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef | ||
// CHECK: [[PARTIALLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"\EF\BE\AD\DE", [12 x i8] undef }>, align 4 | ||
|
||
// CHECK-LABEL: @fully_uninit | ||
#[no_mangle] | ||
pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> { | ||
const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit(); | ||
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{(32|64)}}(i8* align 1 %1, i8* align 1 getelementptr inbounds (<{ [10 x i8] }>, <{ [10 x i8] }>* [[FULLY_UNINIT]], i32 0, i32 0, i32 0), i{{(32|64)}} 10, i1 false) | ||
M | ||
} | ||
|
||
// CHECK-LABEL: @partially_uninit | ||
#[no_mangle] | ||
pub const fn partially_uninit() -> PartiallyUninit { | ||
const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeef, y: MaybeUninit::uninit() }; | ||
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{(32|64)}}(i8* align 4 %1, i8* align 4 getelementptr inbounds (<{ [4 x i8], [12 x i8] }>, <{ [4 x i8], [12 x i8] }>* [[PARTIALLY_UNINIT]], i32 0, i32 0, i32 0), i{{(32|64)}} 16, i1 false) | ||
X | ||
} |