@@ -14562,8 +14562,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1456214562
1456314563 const mutable_alloc = try block.addTy(.alloc, alloc_ty);
1456414564
14565- // if both the source and destination are arrays
14566- // we can hotpath via a memcpy.
14565+ // there's nothing to copy
14566+ if (result_len == 0 and res_sent_val == null) return mutable_alloc;
14567+
1456714568 if (lhs_ty.zigTypeTag(zcu) == .pointer and
1456814569 rhs_ty.zigTypeTag(zcu) == .pointer)
1456914570 {
@@ -14576,48 +14577,75 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1457614577 });
1457714578
1457814579 const many_ty = slice_ty.slicePtrFieldType(zcu);
14579- const many_alloc = try block.addBitCast (many_ty, mutable_alloc );
14580+ const many_ty_ref = Air.internedToRef (many_ty.toIntern() );
1458014581
14581- // lhs_dest_slice = dest[0..lhs.len]
14582- const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
1458314582 const lhs_len_ref = try pt.intRef(.usize, lhs_len);
14584- const lhs_dest_slice = try block.addInst(.{
14585- .tag = .slice,
14586- .data = .{ .ty_pl = .{
14587- .ty = slice_ty_ref,
14588- .payload = try sema.addExtra(Air.Bin{
14589- .lhs = many_alloc,
14590- .rhs = lhs_len_ref,
14591- }),
14592- } },
14593- });
1459414583
14595- _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
14584+ // @memcpy(@as(*[lhs.len]T, dst[0..lhs.len]), lhs.ptr)
14585+ if (lhs_len != 0) {
14586+ // [lhs.len]T
14587+ const array_ty = try pt.arrayType(.{
14588+ .child = resolved_elem_ty.toIntern(),
14589+ .len = lhs_len,
14590+ });
14591+ // *[lhs.len]T
14592+ const mutable_ty = try pt.ptrTypeSema(.{
14593+ .child = array_ty.toIntern(),
14594+ .flags = .{ .address_space = ptr_as },
14595+ });
14596+ const lhs_dest_slice = try block.addBitCast(mutable_ty, mutable_alloc);
14597+
14598+ const lhs_src_pointer = if (lhs_ty.isSlice(zcu))
14599+ try block.addInst(.{
14600+ .tag = .slice_ptr,
14601+ .data = .{ .ty_op = .{
14602+ .ty = many_ty_ref,
14603+ .operand = lhs,
14604+ } },
14605+ })
14606+ else
14607+ lhs;
14608+ _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs_src_pointer);
14609+ }
1459614610
14597- // rhs_dest_slice = dest[lhs.len..][0..rhs.len]
14598- const rhs_len_ref = try pt.intRef(.usize, rhs_len);
14599- const rhs_dest_offset = try block.addInst(.{
14600- .tag = .ptr_add,
14601- .data = .{ .ty_pl = .{
14602- .ty = Air.internedToRef(many_ty.toIntern()),
14603- .payload = try sema.addExtra(Air.Bin{
14604- .lhs = many_alloc,
14605- .rhs = lhs_len_ref,
14606- }),
14607- } },
14608- });
14609- const rhs_dest_slice = try block.addInst(.{
14610- .tag = .slice,
14611- .data = .{ .ty_pl = .{
14612- .ty = slice_ty_ref,
14613- .payload = try sema.addExtra(Air.Bin{
14614- .lhs = rhs_dest_offset,
14615- .rhs = rhs_len_ref,
14616- }),
14617- } },
14618- });
14611+ if (rhs_len != 0) {
14612+ const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
14613+ const rhs_dest_offset = try block.addInst(.{
14614+ .tag = .ptr_add,
14615+ .data = .{ .ty_pl = .{
14616+ .ty = many_ty_ref,
14617+ .payload = try sema.addExtra(Air.Bin{
14618+ .lhs = many_alloc,
14619+ .rhs = lhs_len_ref,
14620+ }),
14621+ } },
14622+ });
1461914623
14620- _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
14624+ // [rhs.len]T
14625+ const array_ty = try pt.arrayType(.{
14626+ .child = resolved_elem_ty.toIntern(),
14627+ .len = lhs_len,
14628+ });
14629+ // *[rhs.len]T
14630+ const mutable_ty = try pt.ptrTypeSema(.{
14631+ .child = array_ty.toIntern(),
14632+ .flags = .{ .address_space = ptr_as },
14633+ });
14634+
14635+ const rhs_dest_slice = try block.addBitCast(mutable_ty, rhs_dest_offset);
14636+
14637+ const rhs_src_pointer = if (rhs_ty.isSlice(zcu))
14638+ try block.addInst(.{
14639+ .tag = .slice_ptr,
14640+ .data = .{ .ty_op = .{
14641+ .ty = many_ty_ref,
14642+ .operand = rhs,
14643+ } },
14644+ })
14645+ else
14646+ rhs;
14647+ _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs_src_pointer);
14648+ }
1462114649
1462214650 if (res_sent_val) |sent_val| {
1462314651 const elem_index = try pt.intRef(.usize, result_len);
0 commit comments