https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123130
Bug ID: 123130
Summary: missed optimization for redundant instructions and
compare instructions
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: 652023330028 at smail dot nju.edu.cn
Target Milestone: ---
Hello,
For the reduced test case below, GCC at -O3 appears to miss an optimization
opportunity in function b.
When *d evaluates to ':' or ']', the generated code for b contains redundant
instructions and unnecessary comparisons.
If the nested condition
```
if (*d)
if (*d && *d != ']')
return 0;
```
is simplified to
```
if (*d && *d != ']')
return 0;
```
(as shown in b_optimized), GCC is able to optimize it as expected.
Reduced code (from ABC project
https://github.com/berkeley-abc/abc/blob/ee04349aee0a11d5ce0ad39b0de80e3cb366087e/src/base/ver/verCore.c#L2087):
https://godbolt.org/z/1Y16EYcqP
int b(char **c) {
char *d = *c;
if (!(*d))
return 2;
while (*d && *d != ':' && *d != ']')
d++;
if (*d)
if (*d && *d != ']')
return 0;
return 1;
}
int b_optimized(char **c) {
char *d = *c;
if (!(*d))
return 2;
while (*d && *d != ':' && *d != ']')
d++;
// if (*d)
if (*d && *d != ']')
return 0;
return 1;
}
GCC -O3:
b:
movq (%rdi), %rdx
movl $2, %ecx
movzbl (%rdx), %eax
testb %al, %al
je .L1
cmpb $58, %al
jne .L3
jmp .L17
.L6:
movzbl 1(%rdx), %eax
addq $1, %rdx
testb %al, %al
setne %cl
cmpb $58, %al
je .L5
testb %cl, %cl
je .L5
.L3:
cmpb $93, %al
jne .L6
.L17:
movl $1, %ecx
.L4: ;redundant instructions and unnecessary comparisons
cmpb $93, %al
setne %al
andl %eax, %ecx
xorl $1, %ecx
movzbl %cl, %ecx
.L1:
movl %ecx, %eax
ret
.L5:
testb %al, %al
jne .L19
movl $1, %ecx
movl %ecx, %eax
ret
.L19:
movl $58, %eax
jmp .L4
Expected:
b_optimized:
movq (%rdi), %rdx
movl $2, %ecx
movzbl (%rdx), %eax
testb %al, %al
je .L20
xorl %ecx, %ecx
cmpb $58, %al
jne .L22
jmp .L20
.L24:
movzbl 1(%rdx), %eax
addq $1, %rdx
testb %al, %al
je .L26
cmpb $58, %al
je .L26
.L22:
cmpb $93, %al
jne .L24
movl $1, %ecx
.L20:
movl %ecx, %eax
ret
.L26:
xorl %ecx, %ecx
testb %al, %al
sete %cl
movl %ecx, %eax
ret