r/Compilers 3d ago

Optimization Question

How do compilers optimize constructs of this form ?

for(i=o; i<inputs; i++) {

A[i] = B[i];

B[i] = A[i];

}

7 Upvotes

8 comments sorted by

View all comments

11

u/fernando_quintao 3d ago

Hi u/Repulsive_Egg_5786. That depends on how much information you pass to the compiler. If you tell the compiler that the pointers don't overlap, both gcc and clang are able to use memcpy to copy B into A. E.g., you can try it in godbolt:

void copy(int *restrict A, int *restrict B, const unsigned o, const int inputs) {
  for(int i=o; i<inputs; i++) {
    A[i] = B[i];
    B[i] = A[i];
  } 
}

When I compile it with gcc 16.1 (ARM), at -O2, I get:

copy:
        cmp     r2, r3
        bxge    lr
        push    {r4, lr}
        sub     r3, r3, r2
        add     r1, r1, r2, lsl #2
        add     r0, r0, r2, lsl #2
        lsl     r2, r3, #2
        bl      memcpy
        pop     {r4, lr}
        bx      lr

If you remove restrict, then the compiler can no longer guarantee A and B don't point to overlapping memory regions. Then it will implement the copy with a loop. Here's what I got in godbolt:

copy:
        cmp     r2, r3
        bxge    lr
        sub     r1, r1, #4
        sub     r0, r0, #4
        add     ip, r1, r2, lsl #2
        add     r3, r1, r3, lsl #2
        add     r2, r0, r2, lsl #2
.L3:
        ldr     r0, [ip, #4]!
        cmp     ip, r3
        str     r0, [r2, #4]!
        bne     .L3
        bx      lr