@@ -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,79 @@ 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());
14581+ // only used when both are non-zero lengths
14582+ const many_alloc = if (lhs_len != 0 and rhs_len != 0)
14583+ try block.addBitCast(many_ty, mutable_alloc)
14584+ else
14585+ undefined;
1458014586
14581- // lhs_dest_slice = dest[0..lhs.len]
14582- const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
1458314587 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- });
14594-
14595- _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
14588+ const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
1459614589
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,
14590+ if (lhs_len != 0) {
14591+ const lhs_dest_slice = switch (rhs_len) {
14592+ 0 => try block.addTyOp(.array_to_slice, slice_ty, mutable_alloc),
14593+ else => try block.addInst(.{
14594+ .tag = .slice,
14595+ .data = .{ .ty_pl = .{
14596+ .ty = slice_ty_ref,
14597+ .payload = try sema.addExtra(Air.Bin{ .lhs = many_alloc, .rhs = lhs_len_ref }),
14598+ } },
1461614599 }),
14617- } },
14618- });
14619-
14620- _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
14600+ };
14601+ const lhs_src_pointer = if (lhs_ty.isSlice(zcu))
14602+ try block.addInst(.{
14603+ .tag = .slice_ptr,
14604+ .data = .{ .ty_op = .{
14605+ .ty = many_ty_ref,
14606+ .operand = lhs,
14607+ } },
14608+ })
14609+ else
14610+ lhs;
14611+ _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs_src_pointer);
14612+ }
14613+
14614+ if (rhs_len != 0) {
14615+ const rhs_dest_slice = switch (lhs_len) {
14616+ 0 => try block.addTyOp(.array_to_slice, slice_ty, mutable_alloc),
14617+ else => s: {
14618+ const rhs_len_ref = try pt.intRef(.usize, rhs_len);
14619+ const rhs_dest_offset = switch (lhs_len) {
14620+ 0 => many_alloc,
14621+ else => try block.addInst(.{
14622+ .tag = .ptr_add,
14623+ .data = .{ .ty_pl = .{
14624+ .ty = many_ty_ref,
14625+ .payload = try sema.addExtra(Air.Bin{ .lhs = many_alloc, .rhs = lhs_len_ref }),
14626+ } },
14627+ }),
14628+ };
14629+ break :s try block.addInst(.{
14630+ .tag = .slice,
14631+ .data = .{ .ty_pl = .{
14632+ .ty = slice_ty_ref,
14633+ .payload = try sema.addExtra(Air.Bin{
14634+ .lhs = rhs_dest_offset,
14635+ .rhs = rhs_len_ref,
14636+ }),
14637+ } },
14638+ });
14639+ },
14640+ };
14641+ const rhs_src_pointer = if (rhs_ty.isSlice(zcu))
14642+ try block.addInst(.{
14643+ .tag = .slice_ptr,
14644+ .data = .{ .ty_op = .{
14645+ .ty = many_ty_ref,
14646+ .operand = rhs,
14647+ } },
14648+ })
14649+ else
14650+ rhs;
14651+ _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs_src_pointer);
14652+ }
1462114653
1462214654 if (res_sent_val) |sent_val| {
1462314655 const elem_index = try pt.intRef(.usize, result_len);
0 commit comments