Skip to content

Commit 65b01cb

Browse files
committed
Use llvm.memset.p0i8.* to initialize all same-bytes arrays
1 parent 65ea9f3 commit 65b01cb

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9797
let start = dest.val.llval;
9898
let size = bx.const_usize(dest.layout.size.bytes());
9999

100-
// Use llvm.memset.p0i8.* to initialize all zero arrays
101-
if bx.cx().const_to_opt_u128(v, false) == Some(0) {
102-
let fill = bx.cx().const_u8(0);
103-
bx.memset(start, fill, size, dest.val.align, MemFlags::empty());
104-
return true;
100+
// Use llvm.memset.p0i8.* to initialize all same byte arrays
101+
if let Some(int) = bx.cx().const_to_opt_u128(v, false) {
102+
let bytes = &int.to_le_bytes()[..cg_elem.layout.size.bytes_usize()];
103+
let first = bytes[0];
104+
if bytes[1..].iter().all(|&b| b == first) {
105+
let fill = bx.cx().const_u8(first);
106+
bx.memset(start, fill, size, dest.val.align, MemFlags::empty());
107+
return true;
108+
}
105109
}
106110

107111
// Use llvm.memset.p0i8.* to initialize byte arrays

tests/codegen/slice-init.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,14 @@ pub fn nonzero_integer_array() {
6565

6666
const N: usize = 100;
6767

68-
// FIXME: The two bytes of the u16 are the same, so we should
69-
// just use memset, too.
7068
// CHECK-LABEL: @u16_init_one_bytes
7169
#[no_mangle]
7270
pub fn u16_init_one_bytes() -> [u16; N] {
7371
// CHECK-NOT: select
74-
// CHECK: br
72+
// CHECK-NOT: br
7573
// CHECK-NOT: switch
76-
// CHECK: icmp
77-
// CHECK-NOT: call void @llvm.memset.p0
74+
// CHECK-NOT: icmp
75+
// CHECK: call void @llvm.memset.p0
7876
[const { u16::from_be_bytes([1, 1]) }; N]
7977
}
8078

0 commit comments

Comments
 (0)