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

            Bug ID: 123389
           Summary: Missed optimization: Loop with a break statement
                    sometimes miss that it can skip a conditional right
                    after loop
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

This bug is a weird one that it's hard for me to concisely explain it in the
title, so sorry for that.

The missed optimization only happens in -O2 and -O3 optimization levels. It
doesn't miss in -Os or -Oz. Clang doesn't miss this with -O2, -O3 or -Os as far
as I've tested.

I've tried simplified the test code when I can.
(Compiler Explorer link: https://godbolt.org/z/659jb8TWv)

```c
#include <stddef.h>
int subroutine1(char *array);

int func1(char *array, size_t len) {
    char *p = array + len;
    for (; p > array; p--) {
        int status = subroutine1(array);
        if (status != 0)
            break;
    }
    if (p <= array)
       return 0;

    __asm__("nop":);
    return 0;
}
int func2(char *array, size_t len) {
    char *end = array + len;
    char *p = array;
    for (; p < end; p++) {
        int status = subroutine1(array);
        if (status != 0)
            break;
    }
    if (p >= end)
       return 0;

    __asm__("nop":);
    return 0;
}
int func3(char *array, char *end) {
    char *p = array;
    for (; p < end; p++) {
        int status = subroutine1(array);
        if (status != 0)
            break;
    }
    if (p >= end)
       return 0;

    __asm__("nop":);
    return 0;
}
```

The loops contains a subroutine call, and a break condition based on the
subroutine's return status. An if-conditional follows the loop with the
condition that's opposite of the loop's condition to continue. I expect the
"break" inside the loop to jump to after the "if" block because it's
unnecessary to check that "if".

Reply via email to