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.