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

    <tr>
        <th>Summary</th>
        <td>
            [InstCombine] PHI folding creates pre-increment that makes vector code less efficient
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:optimizations,
            llvm:instcombine
      </td>
    </tr>

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

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

<pre>
    Consider following [example](https://godbolt.org/z/7a49q9hj7):
```c++ 
void test(const int32_t n, int32_t *__restrict *__restrict a, int32_t *__restrict b) 

    for (int32_t i = n-1; i >= 0; --i) { 
        a[i] = &b[i]; 
    } 
}
```

InstCombine replaces post-increment of an induction variable with pre-increment update:
```
***************** Before InstCombine: ****************
....
5:
  %iv = phi i32 [ %4, %3 ], [ %13, %9 ]
 %latch = icmp sge i32 %lv, 0
  br i1 %latch, label %9, label %8

9:
  %10 = zext nneg i32 %iv to i64
  %11 = getelementptr inbounds i32, ptr %2, i64 %10
....
  %iv.next = add nsw i32 %iv, -1 <<<<<<< post-increment 
  br label %5, !llvm.loop !10

**************** After InstCombine: ****************
....
4:
  %iv = phi i32 [ %0, %3 ], [ %9, %8 ]
 %latch = icmp sgt i32 %vi, 0
  br i1 %latch, label %8, label %7

8:
  %iv.next = add nsw i32 %iv, -1 <<<<<<<<< pre-increment
 %10 = zext nneg i32 %iv.next to i64
  %11 = getelementptr inbounds i32, ptr %2, i64 %10
...
  br label %4, !llvm.loop !10
```

which makes vector code less efficient as vectorizer has to be more careful with pre-increments.

In contrast, if a lower bound of the loop is [replaced with `n`](https://godbolt.org/z/1bGWfPK9E), induction is updated after all uses:
```
9:                                                ; preds = %5, %9
  %iv = phi i64 [ %6, %5 ], [ %iv.next, %9 ]
  %11 = getelementptr inbounds i32, ptr %2, i64 %iv
...
  %iv.next = add nsw i64 %10, -1 <<<<<<<<<<<< post increment
  %14 = icmp eq i64 %iv, 0
  br i1 %14, label %7, label %9, !llvm.loop !10
```
and generated vector code becomes much better
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0VkuT4yYQ_jX40mWXhIQeBx_G9jrZymVvOW4h1LLYINAC9mzm16fA8nPG2Zk8VCpbDfSD7q8f3Dm504hLwlaEbWZ873tjl3rkWvSoZ41p_1yujXayRQudUco8S70Dwlb4gw-jQsI2hFa996Mj2ROhW0K3O9M2RvmFsTtCty-Ebkue19_r_ltJaB2OJRuSPJEiOb6C0BWhKzguH4xswaPzhFbCaOdBap_Rrx40oeszQejT168WnbdS3FP88cGG0HpSRMqTSgCAzlggtDpxSSDZBvQ8JdkqEp8CnQRqPpdRyA17eDhhK0nYJrISWjQTHZguJ0m5ORuwufPERMbfz9r5tRkaqREsjooLdDAa5-dSC4sDag-mA65B6nYvvDQaDtxK3iiEZ-l7GC1end2PLff42vsTST_8wgo7YxGuDCXZE3xYUtS_WCwWxy92NhGAUCYP0Z1jL0FmNCAvrOYhwoSyDCIA16f1NJs26rhxFEMoU9yLPgqSYhjB7fAojTJ1CBzJSWNjQaZnjrCleIMqiryhqutY1bc2p0lU9YI_PGiNu5MueQBvQBb59dk0nt2hRxUDNXoLUjdmr1sXGIPWsEYoi9-yyI867h03uWuhg9ogk7ctaPd80R7Y50Hf-vV7D60rh5zvzI7OTZU6DAtlzBiI9Aa1HwbRU-fR_tcYyt-DoeQBhuppvfoJhPzJsQf5XghVN1R57bjq3uR_GMdTNK9z_3KJx8g8qvs_4PkWkvK_RdJb5fC5l6KHgf-BDg4ovLEgTIug0DnArpNCBtjy0658QQs9d-FKDcIQKpXgFru9eqM6usVt6QVhtLc8NKE1yA44KPOMFuK9Q9n1PUK0W7qAm6lAt0fRpEh0MP9dvTFtfvm9-_Jb_Sn0xti3TtVcuqlot8BjlnClYO_QPSrioQzBB5_QnEaLrZu61inJWf0ggUJ8j4lSTCfZXQJNYHqjEv8bRMnDK0Q9ypMzBH-aJ7flD-4zJorJL0mP36-seTPn0_wuxV91kHeinusWdqjRxvhfI75BYQZ0MOxFDw16j3bWLrO2zmo-w2Va1FVZ5lWVzPpl3XZMFBQ7VhdFLhgmNC_KImNlV9EuL2ZySROapUmWpiXL82SRVU3CsEmyNuEsKyuSJzhwqRbRaGN3M-ncHpdlUuV0Fq_m4vhIaThBsiczejnIFx4w7AgNMbxsSu28mAo9pWHmtMuwNW_2O0fyREnn3UWXl17F6fS6QbANfPn1cxhH2zCMCovch9noZtzxPfc_LRezvVXLuwSVvt83C2EGQrfR6OPffLTmGwpP6DY6wIWxNvjgrwAAAP__CxURUg">