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

            Bug ID: 111564
           Summary: Missed optimization of Loop Unswitch
           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 Unswitch) 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/G3xGvGxq1

Given the following code: 
```c++
extern int var_21;
extern int var_25;
extern int var_28;
extern int var_29;

void test(int var_0, int var_1, int var_2, int var_3, int var_4, int var_5, int
var_6, int var_7, int var_8, int var_9, int var_10, int var_11, int var_12, int
var_13, int var_14, int var_15, int var_16, int var_17) {
    for (int i_0 = 0/*0*/; i_0 < ((((((((var_17)) ? (((819565140) + (var_9))) :
((((var_16)) ? (2141366111) : (var_17)))))) ? (((((((var_4)) ? (var_16) :
(var_17)))) ? (779921519) : (((var_1) + (var_8))))) : (((((((var_10)) ?
(var_12) : (var_5)))) ? ((((var_15)) ? (var_16) : (var_12))) : ((((var_3)) ?
(var_0) : (var_11))))))) - (779921500))/*19*/; i_0 += 4/*4*/) 
    {
        var_21 += var_17;
        if (var_3)
        {
            var_25 += var_17 ? -212529188 : (((var_6) ? (var_5 ? 2029341098 :
var_13) : var_11));
            var_28 += var_8 ? ((var_10 ? (var_13 - var_1) : var_14 ? var_17 :
var_8)) : (var_6 ? 942541005 : var_1 / var_9);
            var_29 += var_2 ? var_6 : ((var_9 ? var_8 : (var_11 ? var_2 :
var_15)));
        }

    }
}

```

Because `var_3` is a loop invariant so we can hoist the if condition out of the
loop, but gcc-trunk -O3 dose not (main parts):
```asm
test(int, int, int, int, int):

        ...

        .L154:
        cmp     edx, ecx
        jle     .L9
        test    r10d, r10d
        je      .L153

        ...

        .L153:
        add     ecx, 4
        mov     eax, 1
        jmp     .L154
```


Example 2:
https://godbolt.org/z/WcMnz97jv

Given the following code: 
```c++
extern int var_13;
extern int var_15;
extern int var_17;
extern int var_19;
extern int var_20;
extern int var_24;

void test(int var_0, int var_1, int var_2, int var_3, int var_4, int var_5, int
var_6, int var_7, int var_8, int var_9, int var_10) {

    for (int i_0 = ((var_9) + (1516547146))/*0*/; i_0 < (((-((-((((var_4)) ?
(var_6) : (var_8))))))) + (960893662))/*16*/; i_0 += ((var_0) +
(1994872666))/*1*/) 
    {
        if (var_1)
        {
            var_13 += (var_0 ? var_8 : var_7) ? (var_0 ? var_7 : var_4) :
((var_7 ? var_1 : var_2) ? 1 : 2);
        }

        var_15 += (var_0 ? var_9 : var_6) ? (var_4 ? !var_5 : (var_7 ? var_3 :
var_9)) : var_8;
        var_17 += var_3 ? ((var_4 ? var_5 : var_8) ? var_3 : var_1) : (var_5 ?
var_8 : var_0);
        var_19 += (var_1 ? var_8 : var_2) ? (var_1 ? (var_7 ? var_3 : var_9) :
!var_3) : var_9;
        var_20 += var_10 ? var_3 : (var_4 ? var_10 : var_8);
        var_24 += var_0 ? -var_5 : (var_8 ? (var_3 ? var_8 : var_1) : (var_6 ?
var_6 : var_5));
    }
}
```

Similarly, `var_1` is an loop invariant and should be hoisted out of the loop
as well.
But gcc-trunk -O3 does not:
```asm
test(int, int, int, int, int):

        ...

        .L273:
        test    ecx, ecx
        je      .L87
        mov     r8d, DWORD PTR [rsp+64]
        add     DWORD PTR [rsp-28], r8d
        test    ebp, ebp
        jne     .L120
        add     DWORD PTR [rsp-32], ecx
        test    edx, edx
        jne     .L271
.L121:
        mov     BYTE PTR [rsp-14], 1
.L89:
        mov     ebx, DWORD PTR [rsp-12]
        test    r12d, r12d
        cmovne  ebx, ecx
.L92:
        add     r9d, ebx
        test    r10d, r10d
        je      .L100
.L102:
        cmp     BYTE PTR [rsp-13], 0
        mov     ebx, edx
        jne     .L103
.L99:
        mov     ebx, ebp
.L103:
        mov     r8d, DWORD PTR [rsp+88]
        add     edi, ebx
        test    r8d, r8d
        je      .L104
.L274:
        mov     ebx, r11d
        add     eax, r13d
        add     esi, edx
        sub     ebx, r12d
        cmp     r15d, eax
        jle     .L272
.L130:
        mov     r11d, ebx
        test    r10d, r10d
        jne     .L273

        ...

```

Thank you very much for your time and effort! We look forward to hearing from
you.

Reply via email to