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

    <tr>
        <th>Summary</th>
        <td>
            Failure to form vwadd.wv when wide operand has additional use
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:RISC-V
      </td>
    </tr>

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

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

<pre>
    This test case should form vwadd.wv but doesn't

```
define <vscale x 2 x i32> @quux(<vscale x 2 x i8> %arg, <vscale x 2 x i32> %arg1, i32 signext %arg2) {
bb: 
  %tmp = call <vscale x 2 x i32> @llvm.vp.sext.nxv2i32.nxv2i8(<vscale x 2 x i8> %arg, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> poison, i1 true, i32 0), <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer), i32 %arg2)
  %tmp3 = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %arg1, <vscale x 2 x i32> %tmp, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> poison, i1 true, i32 0), <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer), i32 %arg2)
 %tmp4 = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> poison, i1 true, i32 0), <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x i32> %tmp3, <vscale x 2 x i32> %arg1, i32 %arg2)
  ret <vscale x 2 x i32> %tmp4 

 
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)      
declare <vscale x 2 x i32> @llvm.vp.sext.nxv2i32.nxv2i8(<vscale x 2 x i8>, <vscale x 2 x i1>, i32) #0
 
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)      
declare <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i1>, i32) #0
 
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none) 
declare <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1>, <vscale x 2 x i32>, <vscale x 2 x i32>, i32) #0
 
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
```

The issue appears to be that %arg1 has 2 uses so the algorithm adds the vp.merge to the worklist but it's not a widenable instruction. The formation of vwadd.wv only affects the vp.sext so we only need to consider it's uses.

I think there's an ordering issue between the worklist management and determining which strategy we are going to use.

CC: @qcolombet 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkVsGO4jgQ_RpzKTVKnEDgkEM3LNJcd0d7d-JK4m3HztgVAvP1K5swva1uUPfsZVaLUEJS5XK9V-VHCe9VaxBLtnpiq_1CjNRZV5IdBnT1orLyXH7tlAdCT1ALj-A7O2oJjXU9HCch5XI6QjUSSIveMF4QS_YseZyv62T-xkeJjTIILNsdfS00wgk4nEBlnGW_AcuTb-N4YnzzxmET7XwlXMv47maA6JAGD5VxiNhONL_mjG-BFU-XTKqKZY9w-Q3Bg_oBWLaHWmh9J0Gtj_3yOCw9nmhpTkeuMn65b34m7zTYfTc2jcYj1mQdvBcmuinj0RFq7NHQbbfBKm9N5CAFciNe6UgY395O4mXZDfDf0VllFCmh1Xd0c7AQ-IXf13xmnyE0dNLM53vQ3hT4tgf1w_-I6wvg_DNU9-havEf2f56pu82RfVxB3na2Q7ofPZ9FhRX7q7zML7InOIymJmUNPBI5HxTI2FC0StTPYGzjEMFYfzY1GDuaSRkJk9LaIY3OQI-9dWfGN8YaDHIWP1dprbVw97T1J6TrZmFmgqKk8iz5NYF-RFJu98Ivg_2zsD90vD-J-4flFnBB5FQ1Evpoi3LEiqd_C73YvztHXK5fOwTl_YgghgGF80AWKgTqxPVPP4VOeOAwevTgLVCHIHRrnaKuByGlj6-urIUA4Xmy7lkrT3GwUcR44cFYAgGTkmhEpTEIH7kxVnoJIZUwEolYeNu8jEbW6DOIpsGafuwVTmDIZsKL2SDKsHVtjVcS3XXLkPXyn4i_AHXKPIc4DqOLMGCdRKdMO3NRIU2I5jWOXhjRXiRaGAkSCV2vTFg1daruwJMThO055BTarLXBRjbk8CqF3S4OTnnyrbba9hUSLGSZyW22FQss03WR8HWxyteLrmzSpMYqEYjbPG_WK5FgKjZJVnEs8m1TL1TJE85TnqzSbcr5epmkQiZCNuuNxA2uVyxPsBdKL2NzW9cuIshytc3y1UKLCrWPwyvnocfQSJY9_v7lj93Dn4zzMNK6Mix9qMbWhzOiPPmXYKRIY3kQSo8uFv_1WDt1aGLFwQ7oAnGhm4SUKpRZ6EDOYnS67IiGcNIZPzB-aBV1Y7Wsbc_4Iew13x4GZ__Cmhg_RBSe8UME8ncAAAD__1CgiXM">