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".