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

    <tr>
        <th>Summary</th>
        <td>
            [IndVarSimplify] WRONG code
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:transforms
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            nikic,
            preames
      </td>
    </tr>

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

<pre>
    IndVarSimplify seems to make an incorrect transformation, as seen below. Given that the code to the left is correct, it does not seem right to substitute %dec in left to %1 in right. %dec is after first iteration %b.promoted - 1, while %1 is %b.promoted - 1 - %umin..?

opt -mtriple=s390x-unknown-linux -mcpu=z15 wrong0_indvar.bc -O3 -o - -S -scev-cheap-expansion-budget=8
[wrong0_indvar.tar.gz](https://github.com/llvm/llvm-project/files/13928920/wrong0_indvar.tar.gz)



` opt -O3  <=> opt -O3 -scev-cheap-expansion-budget=8
`
```
; *** IR Dump After IndVarSimplifyPass on for   ; *** IR Dump After IndVarSimplifyPass on for

; Preheader:                                    ; Preheader:
entry:                                          entry:
 %b.promoted = load i128, ptr @b, align 1, !     %b.promoted = load i128, ptr @b, align 1, !
  %0 = add i128 %b.promoted, -1                   %0 = add i128 %b.promoted, -1
  %umin = call i128 @llvm.umin.i128(i128 %0, %umin = call i128 @llvm.umin.i128(i128 %0, 
  %1 = trunc i128 %umin to i64 |   %1 = sub i128 %0, %umin
  %2 = add nuw nsw i64 %1, 1 |   %2 = trunc i128 %umin to i64
 >   %3 = add nuw nsw i64 %2, 1
  br label %for.body br label %for.body

; Loop: ; Loop:
for.body: for.body:                                    
  %storemerge3 = phi i64 [ 0, %entry ], [ %in     %storemerge3 = phi i64 [ 0, %entry ], [ %in
 %dec12 = phi i128 [ %b.promoted, %entry ],      %dec12 = phi i128 [ %b.promoted, %entry ], 
  %dec = add nsw i128 %dec12, -1 %dec = add nsw i128 %dec12, -1
  %tobool.not = icmp eq i128 %dec12, 1 %tobool.not = icmp eq i128 %dec12, 1
  br i1 %tobool.not, label %return, label %fo     br i1 %tobool.not, label %return, label %fo

for.inc:                                        for.inc: 
  %inc = add nuw nsw i64 %storemerge3, 1 %inc = add nuw nsw i64 %storemerge3, 1
  %exitcond = icmp ne i64 %inc, 4 %exitcond = icmp ne i64 %inc, 4
  br i1 %exitcond, label %for.body, label %re     br i1 %exitcond, label %for.body, label %re

; Exit blocks                                   ; Exit blocks
return: return: 
  %dec.lcssa = phi i128 [ %dec, %for.inc ], [ |   %dec.lcssa = phi i128 [ %1, %for.inc ], [ %
  %storemerge.lcssa = phi i64 [ %2, %for.inc  | %storemerge.lcssa = phi i64 [ %3, %for.inc 
  %retval.0 = phi i16 [ 0, %for.inc ], [ 6, %     %retval.0 = phi i16 [ 0, %for.inc ], [ 6, %
  store i128 %dec.lcssa, ptr @b, align 8, !tb     store i128 %dec.lcssa, ptr @b, align 8, !tb
  store i64 %storemerge.lcssa, ptr @a, align      store i64 %storemerge.lcssa, ptr @a, align 
  ret i16 %retval.0 ret i16 %retval.0

return: return:                                      
  %dec.lcssa = phi i128 [ %dec, %for.inc ], [ |   %dec.lcssa = phi i128 [ %1, %for.inc ], [ %
 %storemerge.lcssa = phi i64 [ %2, %for.inc  |   %storemerge.lcssa = phi i64 [ %3, %for.inc 
  %retval.0 = phi i16 [ 0, %for.inc ], [ 6, %     %retval.0 = phi i16 [ 0, %for.inc ], [ 6, %
  store i128 %dec.lcssa, ptr @b, align 8, !tb     store i128 %dec.lcssa, ptr @b, align 8, !tb
  store i64 %storemerge.lcssa, ptr @a, align      store i64 %storemerge.lcssa, ptr @a, align 
  ret i16 %retval.0                               ret i16 %retval.0
; *** IR Dump After LoopDeletionPass on for.b   ; *** IR Dump After LoopDeletionPass on for.b
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWMFu4zYTfhr6MpBAkZZjH3xw4vVif_zoLnaB9lhQ0thmI5EqSSXZffqClGRLjpPa3ksLVAgciZzvm-FwZqShsFbuFOKSpPeEMSUfZU4YI-yBMFYbFBVa_5yuJ6Jxe22W_9Pqi7VaJZNMF9-Xn1TxqzDfZFWXcvsdLGJlwWmoxCOCUCBVro3B3IEzQtmtNpVwUivCHkBYL68gw1I_x_BRPqECtxcO3B4h1wV6Jn9f4taBtNBxebB0UGi0oLQLWsHI3d55gG0y66RrHAJhaYE5SNUyOO1HEv8cpOODgAWxdWhgK411IB2aYKWfz-La6Eo7LCCCxKt-3ssSOyb7WgQiP9ZUUsUx4RtC14Su2l9dO4gqZ2RdIuFryxf0JWrUo9LPKiqlal4gqvK6IXz9I0nh2Wi1o79LVTwJE2c5RJ85RBoiiL5BZHN8ivI9ijrCl1ooK7WKsqbYoSN8Pe_0pvdjFidMvPtB0jVh871ztSV8RdiGsM1Oun2TxbmuCNuU5VP_L6qN_iN4fbOVpY-HTcIXbL5glLDNWXa2GK569DujELzwmQMQ_kD4mvAPh6ELFzWjx5v2r33k90DYqv2DT19h3VQ1rMLOjgP1i7AWtIKtNuDtuAE3WhW_hy8G9ygKNISv4ILrFNMyoXLm-4UM7dUjWvxJOBK-hlKLAmTC5j52a2eATGkW8q-UO9WGNGFJa9St6E67J6ABJ4oWNqb00lFyzhuX4AZKfHoF-VyUZQeYUh-ucci81uJ5z0RbM2-DHbUmAetMo_KDkYHSaZCzKZC7BxgI2iaDcxYMGNlh0ap5BmWfWx6WBscmR0b2vup-9_mHVpy_xcsCb29BZqAUGZZ-ZqtN7Gv62cHTaP-_1rUP08F9O3kA8BUM7y_JiKNbrNMGKzQ7bBdS72W7gPQeek-GwIdQyR7CBGGpVH003c5wTKQC84Qd0cHrrdQ4Mk-pehtuxQ8c4d9Oh530u9htfaDusukysQGp05nWZexfnR4k86oG_PM1KLlKeBBT8gTp5w8hZdA1Ro2Gtjq47CbkMDJ9wEmVX1E_B4iBg6TK38qfQVwdXHSF-EAJvkiXa1Uc3aqwh3mT2ANML5V75fsedOKsLh_HTh37_hrkaVX48CIdZKXOH-0l-T5GtDTdHvMVHO_G-RCXubXibFoVmHf51O3rKLn7Uvo-R_IOA0vP1qhTtq7M9NV2QBaMuBDLTw05qjbonkQZ08ECZqPKdsb4WTfVF6ef4ehNCcsYloJ2Nec_Febdp4LLggk3Yk9Un2bZKxJxJBmqvQbXqzToWicNnHdmbJgU56L5ouufF_I_E_EX58t_Mf8viPn3r7cz4p0uy39CrrFE33QPeqw4-5vu7E3c2f5wUix5seALMcFlckfTZJZyPpvsl7jg6azIEkHzRbqd5tmMi4RznE0Ltt0WOJFLRtmUJglP7iij03jKE1ZgniaU0hlllEwpVkKWcegltNlNpLUNLu_mNE0m4ZVpu0OW0Frz1eE8pD9gMcvQbWfNzvqeRFpnj2xOujKc0oz7UZKu4bevn3_5GI5LJo0pl1c39cFQ39UHW_8KAAD___wJBZo">