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

            Bug ID: 82394
           Summary: Pointer imposes an optimization barrier
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: antoshkka at gmail dot com
  Target Milestone: ---

Following code

unsigned my_sorted_array() {
    unsigned data[6] = {1, 0, 7, 7, 7, 0};

    // Hand written std::min_element

    unsigned m = data[0];
    for (unsigned* it = data + 1; it != data + 6; ++it) {
        if (*it < m) {
            m = *it;
        }
    }

    return m;
}

Produces an unnecessary long assembly:

my_sorted_array():
  movabs rax, 30064771079
  lea rsi, [rsp-40]
  xor ecx, ecx
  mov QWORD PTR [rsp-32], rax
  lea rax, [rsp-40]
  xor edi, edi
  add rsi, 24
  mov QWORD PTR [rsp-40], 1
  mov QWORD PTR [rsp-24], 7
  lea rdx, [rax+4]
  mov eax, 1
  cmp ecx, eax
  cmovb eax, edi
  add rdx, 4
  cmp rdx, rsi
  je .L1
.L6:
  mov ecx, DWORD PTR [rdx]
  cmp ecx, eax
  cmovb eax, edi
  add rdx, 4
  cmp rdx, rsi
  jne .L6
.L1:
  rep ret


Changing pointers to indexes makes the assembly much better:

unsigned my_sorted_array() {
    unsigned data[6] = {1, 0, 7, 7, 7, 0};

    // Hand written std::min_element

    unsigned m = data[0];
    for (unsigned i = 1; i < 6; ++i) {
        if (data[i] < m) {
            m = data[i];
        }
    }

    return m;
}


Assembly:
my_sorted_array():
  xor eax, eax
  ret


Clang in both cases produces the following:
my_sorted_array(): # @my_sorted_array()
  xor eax, eax
  ret

Reply via email to