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

            Bug ID: 87987
           Summary: Missed optimization with ranged-for loop on a
                    constexpr array
           Product: gcc
           Version: 8.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

This simple program:
```c++
static constexpr bool table[] = { 1, 0, 0, 1, 1, 0, 1, 0 };

int check()
  {
    int sum = 0;
    for(auto value : table) {
      sum += value;
    }
    return sum;
  }
```

after being compiled by GCC 8.2 with `-std=c++11 -O2 -Wall -Wextra -Wpedantic
-Werror`, yields a loop:

```asm
check():
        mov     edx, OFFSET FLAT:table
        xor     eax, eax
.L2:
        movzx   ecx, BYTE PTR [rdx]
        add     rdx, 1
        add     eax, ecx
        cmp     rdx, OFFSET FLAT:table+8
        jne     .L2
        ret
```

, while Clang 6.0 optimizes the body to a constant:

```asm
check():                              # @check()
        mov     eax, 4
        ret
```

( Online comparison can be viewed here:  https://gcc.godbolt.org/z/oaSr6j )

Making the function `constexpr` however overcomes this obstacle:
```c++
static constexpr bool table[] = { 1, 0, 0, 1, 1, 0, 1, 0 };

// This requires only C++11.
constexpr int check_constexpr(const bool *p, int n)
  {
    return (n == 0) ? 0 : *p + check_constexpr(p + 1, n - 1);
  }

int check()
  {
    return check_constexpr(table, sizeof(table));
  }
```

( And here is the online comparison for this one:
https://gcc.godbolt.org/z/HZjBSh )

Reply via email to