https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111563
Bug ID: 111563
Summary: Missed optimization of LICM
Product: gcc
Version: 14.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, we found some optimizations (regarding Loop Invariant Code Motion) that
GCC may have missed. We would greatly appreicate if you can take a look and let
us know what you think.
Here are two examples.
Example 1:
https://godbolt.org/z/cn9v45vdh
Given the following code:
```c++
extern int var_12;
extern int var_13;
extern int var_17;
void test(int var_0, int var_1, int var_5, int var_6, int var_9) {
for (int i_4 = 1; i_4 < var_0-2147483638; i_4 += 1)
{
var_17 += 1774623354;
if (var_9)
{
var_13 += var_1;
var_17 += var_6 + var_0;
var_12 += var_5;
}
else
{
var_17 += var_6;
}
i_4+=i_4/3;;
}
}
```
In fact, `var_6 + var_0` is a loop invariant, but gcc-trunk -O3:
```asm
test(int, int, int, int, int):
cmp edi, 2147483639
jle .L15
mov r9d, DWORD PTR var_17[rip]
lea r10d, [rdi-2147483638]
test r8d, r8d
jne .L4
lea edi, [rcx+1774623354]
mov edx, 1
lea ecx, [r9+1774623354+rcx]
.L5:
movsx rax, edx
mov esi, edx
imul rax, rax, 1431655766
sar esi, 31
shr rax, 32
sub eax, esi
lea edx, [rdx+1+rax]
mov eax, ecx
add ecx, edi
cmp r10d, edx
jg .L5
mov DWORD PTR var_17[rip], eax
ret
.L15:
ret
.L4:
mov eax, edi
mov edi, DWORD PTR var_13[rip]
push rbx
mov ebx, esi
mov r11d, edx
lea r8d, [rax+1774623354+rcx]
add edi, esi
mov esi, DWORD PTR var_12[rip]
add esi, edx
mov edx, 1
.L7:
movsx rax, edx
mov ecx, edx
add r9d, r8d
imul rax, rax, 1431655766
sar ecx, 31
shr rax, 32
sub eax, ecx
mov ecx, esi
add esi, r11d
lea edx, [rax+1+rdx]
mov eax, edi
add edi, ebx
cmp edx, r10d
jl .L7
mov DWORD PTR var_17[rip], r9d
pop rbx
mov DWORD PTR var_12[rip], ecx
mov DWORD PTR var_13[rip], eax
ret
```
Example 2:
https://godbolt.org/z/418K59eoE
Given the following code:
```c++
extern int var_24;
void test(int var_2, int var_3, int var_8, int var_10, int var_14) {
for (int i_2 = -3247424; i_2 < 19; i_2 += var_3 + 1056714155)
{
if(var_3){
var_24 += (-(200 / var_10)) + (-var_8);
var_24 += var_14 + var_2;
}
i_2+=i_2/3;
}
}
```
We note that `(-(200 / var_10)) + (-var_8) + var_14 + var_2` as a whole can be
treated as a loop invariant, but gcc-trunk -O3 does not:
```asm
test(int, int, int, int, int):
mov r10d, edi
mov r11d, edx
test esi, esi
je .L1
mov eax, -200
mov edx, -1
mov edi, DWORD PTR var_24[rip]
add r8d, r10d
idiv ecx
lea r9d, [rsi+1056714155]
mov ecx, -3247424
sub eax, r11d
.L3:
movsx rdx, ecx
mov esi, ecx
add edi, eax
imul rdx, rdx, 1431655766
sar esi, 31
add edi, r8d
shr rdx, 32
sub edx, esi
add ecx, edx
add ecx, r9d
cmp ecx, 18
jle .L3
mov DWORD PTR var_24[rip], edi
.L1:
ret
```
Thank you very much for your time and effort! We look forward to hearing from
you.