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

    <tr>
        <th>Summary</th>
        <td>
            [LV][EVL] Incorrect behavior of fixed-order recurrence idiom with EVL tail folding
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            vectorizers
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            Mel-Chen
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Mel-Chen
      </td>
    </tr>
</table>

<pre>
    When enabling EVL tail folding, the llvm.splice operation may encounter errors in the final iteration because the EVL in the second-to-last iteration might not equal VF * UF. 
This could result in unexpected behavior, such as:
```
llvm.splice([A, B, C, poison], [D, E, poison, poison], -1) ==> [poison, D, E, poison]  
```
This issue was identified by the LLVM test-suite in `SingleSource/UnitTests/Vectorizer/recurrences.test`.
```
Checking first_order_recurrence
Checking second_order_recurrence
Checking third_order_recurrence
Miscompare
```
Currently, we have temporarily disabled this feature using https://github.com/llvm/llvm-project/pull/122458. It will be re-enabled after implementing the following fixes.
```
vector.ph:                                        ; preds = %for.body.preheader.i.i.i
  ...
  %max.vf.1 = tail call i32 @llvm.vscale.i32()
  %max.vf = shl nuw nsw i32 %max.vf.1, 2 
  br label %vector.body

vector.body:                                      ; preds = %vector.body, %vector.ph
  %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  %evl.based.iv = phi i64 [ 0, %vector.ph ], [ %index.evl.next, %vector.body ]

 ### Record the evl of previous iteration. Initialized by VF ###
  %prev.evl = phi i32 [ %max.vf, %vector.ph ], [ %17, %vector.body ]    

  %vector.recur = phi <vscale x 4 x i32> [ %vector.recur.init, %vector.ph ], [ %vp.op.load, %vector.body ]
 %vector.recur8 = phi <vscale x 4 x i32> [ %vector.recur.init7, %vector.ph ], [ %19, %vector.body ]
  %vector.recur10 = phi <vscale x 4 x i32> [ %vector.recur.init9, %vector.ph ], [ %20, %vector.body ]
  %avl = sub i64 %wide.trip.count.i.i.i, %evl.based.iv
  %17 = tail call i32 @llvm.experimental.get.vector.length.i64(i64 %avl, i32 4, i1 true)
  %18 = getelementptr inbounds nuw i32, ptr %__args.val, i64 %evl.based.iv
 %vp.op.load = tail call <vscale x 4 x i32> @llvm.vp.load.nxv4i32.p0(ptr align 4 %18, <vscale x 4 x i1> splat (i1 true), i32 %17), !tbaa !6

### Replace llvm.splice with llvm.experimental.vp.splice. ###
  %19 = tail call <vscale x 4 x i32> @llvm.experimental.vp.splice.nxv4i32(<vscale x 4 x i32> %vector.recur, <vscale x 4 x i32> %vp.op.load, i32 -1, <vscale x 4 x i1> splat (i1 true), i32 %prev.evl, i32 %17)
  %20 = tail call <vscale x 4 x i32> @llvm.experimental.vp.splice.nxv4i32(<vscale x 4 x i32> %vector.recur8, <vscale x 4 x i32> %19, i32 -1, <vscale x 4 x i1> splat (i1 true), i32 %prev.evl, i32 %17)
  %21 = tail call <vscale x 4 x i32> @llvm.experimental.vp.splice.nxv4i32(<vscale x 4 x i32> %vector.recur10, <vscale x 4 x i32> %20, i32 -1, <vscale x 4 x i1> splat (i1 true), i32 %prev.evl, i32 %17)

  %vp.op = tail call <vscale x 4 x i32> @llvm.vp.add.nxv4i32(<vscale x 4 x i32> %20, <vscale x 4 x i32> %19, <vscale x 4 x i1> splat (i1 true), i32 %17)
  %vp.op11 = tail call <vscale x 4 x i32> @llvm.vp.add.nxv4i32(<vscale x 4 x i32> %vp.op, <vscale x 4 x i32> %21, <vscale x 4 x i1> splat (i1 true), i32 %17)
  %22 = getelementptr inbounds nuw i32, ptr %__args1.val, i64 %evl.based.iv
  tail call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> %vp.op11, ptr align 4 %22, <vscale x 4 x i1> splat (i1 true), i32 %17), !tbaa !6
  %23 = zext i32 %17 to i64
  %index.evl.next = add nuw i64 %evl.based.iv, %23
  %index.next = add nuw i64 %index, %7
  %24 = icmp eq i64 %index.next, %n.vec
  br i1 %24, label %"_ZSt10__invoke_rIvRZ4mainE3$_1JPjS2_jEENSt9enable_ifIX16is_invocable_r_vIT_T0_DpT1_EES4_E4typeEOS5_DpOS6_.exit", label %vector.body, !llvm.loop !39
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEWEtv4zgS_jX0pWBCpCw_Dj7kYQNZdO8sJpnsYi4CLZUt9tCkhqQUp3_9gpT8TDrpBLsziWElUj2_Kn5kSTgnNxpxTrJrwvlXVMObCjXhnGS3A9H4ytj5_u5gZcrn-b8r1IBarJTUG1g8fgEvpIK1UaXUG8JvwFcISrVb6molCwRToxVeGg1b8QyoC9NojxbQWmMdSB011lILBdLvZVdYiMZhfBa89GIOC6PLoTdDJZw_kd_KTeVBGw_4ZyMUPC6B8Cv4bUmBJFcPlXRQmEaVYNE1ygd7jcZdjYXHElZYiVYaG-J3TVGBcCS9IskVGSf9J7k6SYrwKcmur4L4dfi6CV-1kc5okt2Gf0h2Ha-LkyeXMkNG-AxIehs_i6BzlHyhnd0CXEQU05LONQhPwoEsUXu5liGh5wjXly-PX8Gj80PXSI8hazJO7qXeKLw3jQ2ZLH_T0j-g847w5SMW3lj5HS3hS4tFYy3qAh0NRsg4oRcR3FRY_BE6YS2t87mxJdr8qHcq0ZXuTRFfSfuqxFfpCrOthcVL_1HGq-cA1BNCJVoEj9vaWGGleoZSOrFSWAbbDtYofGMRGhfcVd7Xsc58SfhyI33VrGhhtoQvQ637y7C25hsWnvBl3ShF-JJxPsqmFO48PEmlYIVgcRgXBZYg1qG75bZWuA31iHlhWCHKPHVQ7dBdAtlG4GldkfQKfvKHpNdQWyxd6CEgPFsbS8MqpbXFCkWJlsrwS5IrAEppvBKebcWOtmvKol5cv4VQCmTKgYyS2OetK4RCKlMeep3PzlWjoqsU6OYJtHvqVI-GQzU4RJ2VBSVWqMLjPskQYkj_kHW88bN5v8j61EhYeYc7dbWPWuoSd1G-riTI8SisNUguxeG4eA9aVOPOnwsGT1G0t46toivhsKSy_aSTYOJNR8EX4Wn3gV-xMLaMfYWtArMOiLTSNO5IiRTutPRSKPm9I4RIib2FfehBLTg_hh0K2UXWFfOd8Nnk9ZBjpbqwT57GRX3wRdKbrs1gByPYBd89DV6qUKmlfyeStqampsqI8sfVujA7_Wwok_dQmb3dMacGWfLZKGbvRMGTt6MQfd1ds-ralWdPskTqraxp3KZ7-uisnLb53gSbvMEhYXu1MpCgUHSDnvZxKNQbX1E5HhE-7R2LVgU3QX0U_2DgbYMnzMO6am3QY8estbcg9co0unSRiCJZ3UC4T3iW58JuHG1FZ7hzc5nDWd9cpPKjauwZslOieteOZMppnRA-Db6FkhsNoy7miN2lIRbsuFoJDwGBY6o9Av266uvL_EqIcB13C-qUBmolivPj1pP0FbyEv617AfqSBNjsY5n_wHAPRNgvfqB_3sOvQnOUPFvOAZUh-yyYe5Z7gW8PAE_-FgBeb46DKJv9BZlfngH-msxZ8nbqHXP931I_0HDosQ-velGWP5UwfyfJfpP4NDmcJsE-WMcPpBHtv1OuTxfpvBn5ZxievUPxJ6C0RpanEDhvLJ4T-Ds4MLb3f8LynP-vWb6DI41wfMedP8qDNyHRs4Pt4fQY5UVZdli9Ake3kR-Z_3jCfU01Pu11JoeoRlFUFtsa8M8z0dMTrA6b_X4AkKzTDM8OwwDhPP_93rMkz6VuzR-Y27v2199HWyH1IiV8lLN__OvbPc-_LRb_vPezbr7K5fruP2wsXVQq4i2bt3cP-UOS39YPLF8s7kf5YuSfa1z8cp_lt_Uv9-Oc4i6cIPlZCC8mBxY7Q5nACpyls9MhbVDO03KWzsQA52ySjjM2ZdPJoJqvJuMCeTpOeckyNp5kZcn4esYSlo2T6bQYyDlPeJYwlrBRMhulNEtYOSkKNk2SFEerhIwS3AqpaHRv7GYQh_p5GDTHbBDjdf1LmvYwobv-PY2dxzF11Wxc6G3pvDsa8tKr-H7ny2M4-WXXi8cv4Xh-pwtjLRb-8O4jTBFhNC2HcQCH4wAOspRm250sLt_4DBqr5h8epGN6rh-lx2zQzvl_AwAA__-WyYUT">