diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index b4aa001547c..43258078bd7 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -572,8 +572,6 @@ fn write_operand_repeatedly( ) { let zero = self.const_usize(0); let count = self.const_usize(count); - let start = dest.project_index(self, zero).llval; - let end = dest.project_index(self, count).llval; let header_bb = self.append_sibling_block("repeat_loop_header"); let body_bb = self.append_sibling_block("repeat_loop_body"); @@ -582,24 +580,18 @@ fn write_operand_repeatedly( self.br(header_bb); let mut header_bx = Self::build(self.cx, header_bb); - let current = header_bx.phi(self.val_ty(start), &[start], &[self.llbb()]); + let i = header_bx.phi(self.val_ty(zero), &[zero], &[self.llbb()]); - let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end); + let keep_going = header_bx.icmp(IntPredicate::IntULT, i, count); header_bx.cond_br(keep_going, body_bb, next_bb); let mut body_bx = Self::build(self.cx, body_bb); - let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); - cg_elem - .val - .store(&mut body_bx, PlaceRef::new_sized_aligned(current, cg_elem.layout, align)); + let dest_elem = dest.project_index(&mut body_bx, i); + cg_elem.val.store(&mut body_bx, dest_elem); - let next = body_bx.inbounds_gep( - self.backend_type(cg_elem.layout), - current, - &[self.const_usize(1)], - ); + let next = body_bx.unchecked_uadd(i, self.const_usize(1)); body_bx.br(header_bb); - header_bx.add_incoming_to_phi(current, next, body_bb); + header_bx.add_incoming_to_phi(i, next, body_bb); *self = Self::build(self.cx, next_bb); } diff --git a/tests/codegen/issues/issue-111603.rs b/tests/codegen/issues/issue-111603.rs index 90b3c314d2f..06429ed3fa9 100644 --- a/tests/codegen/issues/issue-111603.rs +++ b/tests/codegen/issues/issue-111603.rs @@ -5,6 +5,18 @@ use std::sync::Arc; +// CHECK-LABEL: @new_from_array +#[no_mangle] +pub fn new_from_array(x: u64) -> Arc<[u64]> { + // Ensure that we only generate one alloca for the array. + + // CHECK: alloca + // CHECK-SAME: [1000 x i64] + // CHECK-NOT: alloca + let array = [x; 1000]; + Arc::new(array) +} + // CHECK-LABEL: @new_uninit #[no_mangle] pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> {