Skip to content

Conversation

Rexicon226
Copy link
Contributor

closes #24953

New AIR
export fn a(x: *const [0]u8) void {
    _ = @as([]const u8, "") ++ x;
}

->

  %0!= arg(*const [0]u8, 0)
  %1!= dbg_stmt(2:5)
  %4!= alloc(*[0]u8)
  %5!= ret(@.void_value)

export fn b(x: *const [1]u8) void {
    _ = @as([]const u8, "") ++ x;
}

->

  %0 = arg(*const [1]u8, 0)
  %1!= dbg_stmt(2:5)
  %4 = alloc(*[1]u8)
  %5!= bitcast([*]u8, %4)
  %6 = array_to_slice([]u8, %4!)
  %7!= memcpy(%6!, %0!)
  %8!= bitcast(*const [1]u8, %4)
  %9!= ret(@.void_value)

export fn c(x: *const [0]u8) void {
    _ = @as([]const u8, "1") ++ x;
}

->

  %0!= arg(*const [0]u8, 0)
  %1!= dbg_stmt(2:5)
  %4 = alloc(*[1]u8)
  %5 = array_to_slice([]u8, %4!)
  %6 = slice_ptr([*]u8, <[]const u8, "1"[0..1]>)
  %7!= memcpy(%5!, %6!)
  %8!= bitcast(*const [1]u8, %4)
  %9!= ret(@.void_value)

export fn d(x: *const [0]u8) void {
    _ = "1" ++ x;
}

->

  %0!= arg(*const [0]u8, 0)
  %1!= dbg_stmt(2:5)
  %4 = alloc(*[1:0]u8)
  %5 = array_to_slice([]u8, %4)
  %6!= memcpy(%5!, <*const [1:0]u8, "1">)
  %7 = ptr_elem_ptr(*u8, %4!, @.one_usize)
  %8!= store(%7!, @.zero_u8)
  %9!= bitcast(*const [1:0]u8, %4)
  %10!= ret(@.void_value)

cc @jacobly0, perhaps you could double check my AIR?

Copy link
Member

@jacobly0 jacobly0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  %0 = arg(*const [1]u8, 0)
  %6 = array_to_slice([]u8, %4!)
  %7!= memcpy(%6!, %0!)

This still seems wrong, when either side is a pointer-to-array (aka comptime-known length), lhs must be pointer-to-array and rhs must be a non-slice pointer, see for reference:

comptime {
    _ = &memcpy;
}
fn memcpy(lhs: []u8, rhs: *const [5]u8) void {
    @setRuntimeSafety(false);
    @memcpy(lhs, rhs);
}
$ zig build-obj repro.zig --verbose-air -fstrip
# Begin Function AIR: repro.memcpy:
# Total AIR+Liveness bytes: 219B
# AIR Instructions:         7 (63B)
# AIR Extra Data:           9 (36B)
# Liveness tomb_bits:       8B
# Liveness Extra Data:      0 (0B)
# Liveness special table:   0 (0B)
  %0 = arg([]u8, 0)
  %1 = arg(*const [5]u8, 1)
  %2!= slice_len(usize, %0)
  %3 = slice_ptr([*]u8, %0!)
  %4 = bitcast(*[5]u8, %3!)
  %5!= memcpy(%4!, %1!)
  %6!= ret(@.void_value)
# End Function AIR: repro.memcpy

@Rexicon226
Copy link
Contributor Author

Rexicon226 commented Oct 16, 2025

Ok I've revised it with my new understanding of the semantics...

# Begin Function AIR: empty.b:
# Total AIR+Liveness bytes: 211B
# AIR Instructions:         7 (63B)
# AIR Extra Data:           7 (28B)
# Liveness tomb_bits:       8B
# Liveness Extra Data:      0 (0B)
# Liveness special table:   0 (0B)
  %0 = arg(*const [1]u8, 0)
  %3 = alloc(*[1]u8)
  %4!= memcpy(%3!, %0!)
  %5!= bitcast(*const [1]u8, %3)
  %6!= ret(@.void_value)
# End Function AIR: empty.b

and,

export fn foo(x: *const [1]u8) void {
    _ = @as([]const u8, "1") ++ x;
}
  %0 = arg(*const [1]u8, 0)
  %3 = alloc(*[2]u8)
  %4 = bitcast(*[1]u8, %3)
  %5 = slice_ptr([*]u8, <[]const u8, "1"[0..1]>)
  %6!= memcpy(%4!, %5!)
  %7 = bitcast([*]u8, %3!)
  %8 = ptr_add([*]u8, %7!, @.one_usize)
  %9 = bitcast(*[1]u8, %8!)
  %10!= memcpy(%9!, %0!)
  %11!= bitcast(*const [2]u8, %3)
  %12!= ret(@.void_value)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error(x86_67_encoder): no encoding found for: none mov r64 m128 none none

2 participants