<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/67813>67813</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Missed optimization of Loop Unswitch (could be a regression)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ZY546
      </td>
    </tr>
</table>

<pre>
    Hello, we found some optimizations (regarding Loop Unswitch) that LLVM may have missed. We would greatly appreicate if you can take a look and let us know you think.

The control flow graph for this code is simple. Additionally, these optimizations work as expected on llvm-10.0.0.


Here are two examples.


Example 1:
https://godbolt.org/z/GKr3EP5WE

Given the following code: 
```c++
void test(int var_0, int var_1, int var_2, int var_3) {
 for (int i_0 = var_7 - 2121007231; i_0 < var_3 + 1860531184; i_0 += -838747044 - var_3 - var_0 + 543053277) 
    {
        var_8 += -1112137106 - var_3 + 5 - 333186413;
        var_1 += var_1;
 var_10 += var_2 + var_0;
        if (var_3)
        {
 var_20 += var_0 + var_1 + 16777216 - 23;
            var_28 += var_0 + var_8 - var_3 + var_0 - var_0;
            var_2 += var_16 + var_10 + var_30 - var_0 + var_1;
        }

        var_34 += var_2 - var_1 / var_3 - var_1 + var_2 - var_2;
        var_35 += var_34 & var_3 | ((var_1 + 2147483647) >> (var_0 + 545253533)) + var_12;
        var_0 += var_1 + 1694456005 + var_3 + var_0 + var_20 + var_1 - var_3;
        var_38 += var_2 - 2147483643 + 2147483647 + (var_1 && var_0) + 1369228270 + var_2;
 var_39 += var_2 + var_35 - var_3 + var_26;
        var_41 += var_19 + var_0 + var_28;
    }
}
```

Because `var_3` is a loop invariant so we can hoist the if condition out of the loop, but clang-trunk -O3 dose not (main parts):
```asm
.LBB0_2: # %for.body
        ...   
        jne     .LBB0_6 #if-else
        ...
```


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

Given the following code: 
```c++
void test(int var_0, int var_1, int var_2, int var_3, int var_4) {
    for (int i_0 = 0; i_0 < 4 + -1986643035 + 1 - 1 + 1986643054; i_0 += var_3 - var_1 - var_3 - var_10 + var_10 - 636989219 + var_2 - 691490232 - 1995983094) {
        var_11 += 691490244 + 1118573265 - 1740428269 - 15 + var_1 - var_1 + var_3 - var_1;
        var_2 += 691490244 - var_2 + var_9 - var_4 + 524287 + var_0 - 130944 - var_8;
 var_2 += var_1 - var_2 - 1278891492 + var_0 + var_10 / var_2 - 1060987095 / var_10;
        
        if (var_4) {
            var_15 += var_3 + var_2 + var_12 - var_10 + var_4 - var_10 + var_2 + var_0;
        }
 
        var_0 += var_2 + var_2 + var_17 - var_11 + 908521917 + 691490232 + var_18 + var_2;
        var_3 += -2147483627 - var_15 + var_4 - -4 - 1026228299;
        var_25 += var_3 / var_0 / (var_10 / var_9) * (28 / var_0 / (var_8 / var_3));
    }
}
```

Similarly, `var_4` is an loop invariant and should be hoisted out of the loop as well.
But clang-trunk -O3 does not:
```asm
.LBB0_1: # %for.body
        ...
        je      .LBB0_3 #if-else
        ...
```

Thank you very much for your time and effort! We look forward to hearing from you. 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV0uP4joW_jVhcxTkVxJ7waLoKvpKU1fT0tyZq5nNlSEOuCvEjG2gq3_9yM6DBNIP9WaqEMT28efz8vlypHN63yi1SrJ1kj0v5NkfjF39598ZyxdbU76vflN1bRLyAa4KKnNuSnDmqMCcvD7qr9Jr0zhICLdqL22pmz28GnOCfzbuqv3ukBAB_iA9vL7-63c4ync4yIuCo3ZOlUv4U8HVnOsS9lZJX7-DPJ2s0jvpFegK3s0ZdrIBL98USKiNeQPZlFArD2cHb425Rhl_0M3bMkHPCXpqv_84KNiZxltTQ1WbK-ytPB2gMjYIO9iZUoF24PTxVKslPJWlDrbIun4P1vqDcvdWXo19A-lAfTmpnVclmAbq-nJMMVqG__H57fdvyiqQVoG_GlBfZDjLzci9tEuAE9rNHLw_uTAim4Rs9qbcmtovjd0nZPM1IZuPf7P05VP258sY5qO-qCaoDpWpa3MN0QiGJvQJOrkctZ9dQtbhE2cvRpfglfMJ4brxcJH2LxS80A_weEDGAxoCnBQdUPRvB6L_QpDQ5yhVQAoEE4xQQShO6Lpb_dBiQELWgHmOMooxZ8M6WQeAlFNesAIxBmkn3_5GCcgYRRklRRE1adUAGOnU_YUdfMDEGBNMC4zyATSCQQqUUsxzhmlCZyBwD9H6ZRCJQzReJBGx9eU9kq6Cm3oHTtdumkeUCSYaMHHrtLwoCoKDEeRR315nwucx-MT2di39hsYD1sT-_KbPDZaiSYDuHDVY-TxO3fERlE3dmA4GbybxxwN8L0NmQ0azMV5Ez3u7iw8hEF0sWkCCWcE4zVmbUfQloS99tPqUy0hGMxpjF2R6K-fPn0Swj5tgLMsRym5eGwVhsGsc7y5W8ybye5cNVtA7o-JwZHDeewP1pmCaC0I4KUaKTBOdivlEp9lDRpF8VmE2vUdizng-2XlLmOGhL2bjRFqrnTw7BUmOWnflKNT5SB4n0M1FWi0bD84ERgvkcjDa-Vg1dRU4oyUCMGcPporzYWsoetuzh10tm33q7bl5g_TvFErjFDTGB5cepW7gJK13ITH6Uj6oKd2xnVm-rtco-PQJEhJclVXGLgPdTh21XC6D4ZO5z41q1yJGuH9UV6mqnXrY-x0vTWmH_DTt_Jd_lJ-qyyf7_6ed24BNOQhgjobQmHVigYEUC57njKK2QEC4Yt317Bayey6alp8pHY0qIA4VMKe54IKMcjvcy1xgJhCh4RkLkQlOkXi0YKCb4Z50G1mrO8aYZwUlebhxuGCIEU5yEQbZQ83AoyKTfqMeT2r77az07oaLbqbVIiOM8GLCHjiY0-_j07Ix5Y4BOwVMCs7DmWSmDkS_bm6yKEeCF0hkwzR-pKtv0e28pwdvT5liFLhbiX-MNnuc-h73D_ULfkAVZO78oj-sDapAPCNY4DYIt-Qa5PlcDR8zx_BK1FMEGY7IJiamLHqf5IEbhJjPoAcHbga7NgPr3ALa0Weogzy-pcyI36Y7vv0VWviHPupa2vblvuMG1nNDc08Oocdwh9iYbFVLEOF1f8oIoRW4qrru6ux6lhyUC-TwQy7AP8MFd0SgYEQE9BeJ4I-DbN5iD3VR9h2O513bJL2bswWvjyr6QlWVsT4hODRssQurjL1KW4I3cFDShpJfWXMM-5awKFe0FFTIhVrhXGRCcJKjxWG12zJOM5xTwXNSIFaVolI550JRyVSWLfSKIEKRIAIzWjC0VOWOMYIZrqotF0WVMKSOUtfL0HgFYlpo585qlRcc00Utt6p2sZklpFFXiIsJIaG3tavYrG3Pe5cwVGvn3Q3Fa1-r1e-xLZ20fSHik442pOWuTw0JVu2tck6bJiFicbb16o5DtT-ct8udOSZkE47rftKTNZ_VzidkE5V0CdlEI_4XAAD__-8KLJI">