Skip to content

CBE copies entire array to new variable before accessing it #21724

@ikskuh

Description

@ikskuh

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

Compile the following code with zig build-exe -lc -ofmt=c /tmp/magic.zig -O ReleaseFast and check out the generated C file:

pub fn read() u8 {
    return 1;
}
pub fn write(_: u8) void {}

pub export fn main() void {
    var buf: [1 << 31]u8 = undefined;

    for (0..255) |i| buf[i] = read();
    for (0..255) |i| write(buf[i]);
}

This code generates

void main(void) {
 uintptr_t t2;
 uintptr_t t1;
 uintptr_t t7;
 uint64_t t3;
 uint8_t *t5;
 bool t4;
 uint8_t t6;
 uint8_t t8[2147483648];
 uint8_t t0[2147483648];
 /* file:2:5 */
 /* var:buf */
 t1 = (uintptr_t)0ul;
 /* file:4:10 */
 for (;;) {
  t2 = t1;
  t3 = t2;
  t4 = t3 < UINT64_C(255);
  if (t4) {
   /* var:i */
   /* file:4:25 */
   t5 = (uint8_t *)&t0[t2];
   /* file:4:35 */
   t6 = magic_read__249();
   (*t5) = t6;
   goto zig_block_1;
  }
  goto zig_block_0;

  zig_block_1:;
  t2 = t2 + (uintptr_t)1ul;
  t1 = t2;
 }

 zig_block_0:;
 t7 = (uintptr_t)0ul;
 /* file:5:10 */
 for (;;) {
  t2 = t7;
  t3 = t2;
  t4 = t3 < UINT64_C(255);
  if (t4) {
   /* var:i */
   /* file:5:27 */
   memcpy(t8, (const char *)&t0, sizeof(uint8_t[2147483648]));
   /* file:5:31 */
   t6 = t8[t2];
   /* file:5:27 */
   magic_write__250(t6);
   goto zig_block_3;
  }
  goto zig_block_2;

  zig_block_3:;
  t2 = t2 + (uintptr_t)1ul;
  t7 = t2;
 }

 zig_block_2:;
 return;
}

Both GCC 14.2 and Clang emit the memcpy and are not able to optimize t8 away.

Expected Behavior

The array t8 is unnecessarily created copied before accessing it.

I don't expect Zig to emit the memcpy(t8, (const char *)&t0, sizeof(uint8_t[2147483648]));

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-cThe C backend (CBE) outputs C source code.enhancementSolving this issue will likely involve adding new logic or components to the codebase.frontendTokenization, parsing, AstGen, Sema, and Liveness.optimization

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions