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

            Bug ID: 99067
           Summary: Missed optimization for induction variable elimination
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: brian.grayson at sifive dot com
  Target Milestone: ---

For RISC-V, this code snippet could eliminate the induction variable for the
loop ending condition.

#include <stdint.h>
int16_t a[1000];
int64_t N = 100;
int64_t found_zero() {
  for (int i = 0; i <= N; i++) {
    if (a[i] == 0) return 1;
  }
  return 0;
}

gcc -O3 for RISC-V generates:

.L8:
  addi  a5,a5,2
  blt a2,a4,.L4
.L3:
  lh  a3,0(a5)
  addi  a4,a4,1  <-- induction variable update that can be eliminated
  bne a3,zero,.L8
  li  a0,1
  ret
.L4:
  li  a0,0
  ret

Is there a reason it doesn't do this transform (written at the C level) to do
pointer comparisons:

  for (int16_t* p = &a[0]; p <= &a[N]; p++) { ... }

That C code is able to remove the extra add instruction:

.L15:
  bgtu  a5,a3,.L12
.L11:
  lh  a4,0(a5)
  addi  a5,a5,2
  bne a4,zero,.L15
  li  a0,1
  ret
.L12:
  li  a0,0
  ret

I verified the same issue occurs in PowerPC and ARM code-gen, so this isn't
target-specific.

Reply via email to