[Bug middle-end/92455] New: Unnecessary memory read in a loop

antoshkka at gmail dot com gcc-bugzilla@gcc.gnu.org
Mon Nov 11 13:39:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92455

            Bug ID: 92455
           Summary: Unnecessary memory read in a loop
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: antoshkka at gmail dot com
  Target Milestone: ---

Consider the example:

typedef struct {
    int* ptr_; 
} int_ptr;  

int_ptr f1(int_ptr* x) {
    int_ptr* max = x;
    for (int i =0 ; i < 5; ++ i) {
        ++ x;
        if (*max->ptr_ < *x->ptr_) {
            max = x;
        }
    }
    return *max;
}

GCC with -O2 generates the following assembly:

f1(int_ptr*):
  lea rsi, [rdi+40]
  mov rax, rdi
.L3:
  mov rcx, QWORD PTR [rax]  ; <== This could be removed from the loop
  mov rdx, QWORD PTR [rdi+8]
  add rdi, 8
  mov edx, DWORD PTR [rdx]
  cmp DWORD PTR [rcx], edx
  cmovl rax, rdi
  cmp rsi, rdi
  jne .L3
  mov rax, QWORD PTR [rax]
  ret


If we rewrite the example to avoid int_ptr:

int* f2(int** x) {
    int** max = x;
    for (int i =0 ; i < 5; ++ i) {
        ++ x;
        if (**max < **x) {
            max = x;
        }
    }
    return *max;
}

Then there'll be less memory accesses in a loop:
f2(int**):
  mov rax, QWORD PTR [rdi] ; <=== Not in a loop any more
  lea rcx, [rdi+40]
.L8:
  mov rdx, QWORD PTR [rdi+8]
  add rdi, 8
  mov esi, DWORD PTR [rdx]
  cmp DWORD PTR [rax], esi
  cmovl rax, rdx
  cmp rcx, rdi
  jne .L8
  ret


Please improve the memory accesses for the first case

Godbolt playground: https://godbolt.org/z/CaGbT2


More information about the Gcc-bugs mailing list