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

    <tr>
        <th>Summary</th>
        <td>
            [RISC-V V] Idea: Interleave independent op-chains by `vsetvli` category
        </td>
    </tr>

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

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

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

<pre>
    In my real code, I have some 512-bit subtractions, some of which can be run in parallel. Some real code would inline to something like this:

```zig
// equivalent to sub(a, b) & sub(c, d)
export fn foo(a: @Vector(8, u64), b: @Vector(8, u64), c: @Vector(8, u64), d: @Vector(8, u64)) @Vector(8, u64) {
    const c1: u8 = @as(u8, @bitCast(a < b));
    const m1: u8 = @as(u8, @bitCast(a == b));
    const s1 = a -% b;
    const ans1 = @select(u64, @as(@Vector(8, bool), @bitCast(m1 ^ ((c1 << 1) +% m1))), s1 +% @as(@Vector(8, u64), @splat(0xffffffffffffffff)), s1);


    const c2: u8 = @as(u8, @bitCast(c < d));
    const m2: u8 = @as(u8, @bitCast(c == d));
    const s2 = c -% d;
    const ans2 = @select(u64, @as(@Vector(8, bool), @bitCast(m2 ^ ((c2 << 1) +% m2))), s2 +% @as(@Vector(8, u64), @splat(0xffffffffffffffff)), s2);

    return ans1 & ans2;
}
```

Compiled for sifive_x280, we get:

```diff
foo:
- vsetivli        zero, 8, e64, m1, ta, ma
        vle64.v v9, (a1)
 vmv.v.i v8, 0
        vle64.v v10, (a2)
        vmsltu.vv       v11, v9, v10
        vmseq.vv        v12, v9, v10
-       vsetvli zero, zero, e8, mf8, ta, ma
        vmv.x.s a1, v11
        vle64.v v11, (a3)
 vmv.x.s a2, v12
        vle64.v v12, (a4)
        sh1add  a1, a1, a2
 xor     a1, a1, a2
        vmv.s.x v0, a1
-       vsetvli zero, zero, e64, m1, ta, ma
        vmsltu.vv       v14, v11, v12
        vmseq.vv v15, v11, v12
        vmerge.vim      v13, v8, 1, v0
-       vsetvli zero, zero, e8, mf8, ta, ma
        vmv.x.s a1, v14
        vmv.x.s a2, v15
        sh1add  a1, a1, a2
        xor     a1, a1, a2
        vmv.s.x v0, a1
-       vsetvli zero, zero, e64, m1, ta, ma
        vsub.vv v9, v9, v10
        vsub.vv v10, v11, v12
        vmerge.vim      v8, v8, 1, v0
 vsub.vv v9, v9, v13
        vsub.vv v8, v10, v8
        vand.vv v8, v8, v9
        vse64.v v8, (a0)
        ret
```

Notice how we have 5 `vsetivli`/`vsetvli`? That seems a bit unnecessary. With manual interleaving:

```zig
// equivalent to sub(a, b) & sub(c, d)
export fn bar(a: @Vector(8, u64), b: @Vector(8, u64), c: @Vector(8, u64), d: @Vector(8, u64)) @Vector(8, u64) {
    const c1: u8 = @as(u8, @bitCast(a < b));
 const m1: u8 = @as(u8, @bitCast(a == b));
    const c2: u8 = @as(u8, @bitCast(c < d));
    const m2: u8 = @as(u8, @bitCast(c == d));

    const s1 = a -% b;
    const s2 = c -% d;

    const ans1 = @select(u64, @as(@Vector(8, bool), @bitCast(m1 ^ ((c1 << 1) +% m1))), s1 +% @as(@Vector(8, u64), @splat(0xffffffffffffffff)), s1);
    const ans2 = @select(u64, @as(@Vector(8, bool), @bitCast(m2 ^ ((c2 << 1) +% m2))), s2 +% @as(@Vector(8, u64), @splat(0xffffffffffffffff)), s2);

    return ans1 & ans2;
}
```

We get:

```diff
bar:
+       vsetivli        zero, 8, e64, m1, ta, ma
        vle64.v v10, (a1)
        vmv.v.i v9, 0
 vle64.v v11, (a2)
        vle64.v v12, (a3)
        vle64.v v13, (a4)
 vmsltu.vv       v8, v10, v11
        vmseq.vv        v14, v10, v11
 vmsltu.vv       v15, v12, v13
        vmseq.vv        v16, v12, v13
+ vsetvli zero, zero, e8, mf8, ta, ma
        vmv.x.s a1, v8
 vmv.x.s a2, v14
        vmv.x.s a3, v15
        vmv.x.s a4, v16
 sh1add  a1, a1, a2
        xor     a1, a1, a2
        sh1add  a2, a3, a4
 xor     a2, a2, a4
        vmv.s.x v0, a1
        vmv.s.x v8, a2
+ vsetvli zero, zero, e64, m1, ta, ma
        vsub.vv v10, v10, v11
 vmerge.vim      v11, v9, 1, v0
-       vmv1r.v v0, v8
        vsub.vv v8, v12, v13
        vmerge.vim      v9, v9, 1, v0
        vsub.vv v10, v10, v11
        vsub.vv v8, v8, v9
        vand.vv v8, v8, v10
        vse64.v v8, (a0)
        ret
```

Now there are only 3 `vsetivli`/`vsetvli` instructions! We do have an extra `vmv1r.v` inserted in this version, but my feeling is that that is less expensive than the 2 `vsetvli` we eliminated.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWEuPozgX_TXO5ioIzCNkkUU9vpJq8y2mR9XLkYGb4Gljp21DpfrXj2wglQRSXT3drRmpB6GK4J577gvMKTNj-E4ibkh6S9L7BWttrfTmiQleMf1pUajqZfMooXkBjUxAqSok9A4eoWYdglENQhrRZcEtmLawmpWWK2kcxhvVFp5rXtZQMgkFgm4lcAl7ppkQKAL44FBHbnhWraiAS8ElglWexNZc7kDwTwi25obENyT0Zxb25xe-c5f0gdAHwM8t75hAab1_WxCaM5dPQegaCM2Ge6W7VxG6JuENHvZKW9hK2Crl8fENkCR8wtIqTWieO3CbJQ7uqd62l1-xV2_a19dMQFa3JLwBACiVNBbKyBG1OZD43jkxQ2jeeg-ShAW3d8xYVw-QuG-AO-NzkuYbSO4d5gqPiTwDgyWhqWvRuZnJAUCS0KDA0nH6uu6OUSd1F0qJoWdnuTQRkPR_4FxoXjreO1dh1I_41iXQREOavbsL3huuBnudj0txL5iLFB62F8cp57EN_XkyGfq-ppZ-MtWVyXwDiZ_MFR5DPUPZT6aamQz9cZOhp5Ohs5Oh55OhP2Ey9HQyrlSNttVyeApp5oseAKv708Wkd7lTzZ4LrGCrNBi-5R3-caB56MifEXZop8tQxbdbEt64JcTbltAZtLwTHIbjC2rlGHxR2HfYPad3YP0S1bAhW3d0ArMk6KDrC6c5i_rVCrqmC7qAQ-d5wjmfKByd6OA0IhojbBt03Xgd-fh9EOd2BsXPr0joInoJXY4mg9bVORY4_qLPsNnm12psuuAQGGB9ElE0W0s01hKfNMC79QlFdNaNjm7JeQtMHbGqgiHo8NdTHJT2iKnlJF8THKALB8A7WvC1MU8Gkoy9mNY2TqSL0jdAqHcYdLwZCWMP8jPo8T9jdMmcbZhP-q7uD8c_MgTTFr6v66svw4jo36z3dT6fa_yVYPFcsHxMpOc5QTBZnSDygemUYngN8vEtCM_fAo12uuz9X1leItTq2a1yXuOlQLJwXMgckD4MN4br-AF-r5kFg9gYYOC0YCsllmgM0y8BfOS2hobJlgng0qIWyDoudz9VyBVM_yJC7sequH-BcPkWVTkrbX4h3Qn_qbg3VNzHt5WaWyN6G709-YB8v2J7VV_RpfoalNv6qNxmZM6lZJsqmvgaIr7UPBN5cfZJORdcE72XTLFTuZKOH8LpZ2xCmE2wrvU_SILkc9JwVpbEU1lytA01Z872_VrlyODT6QOz5Exr0sHpaDnJ6ELmTEz5MeCbfXyv-hknfT7wSzl58g_DjJxsuki7R3FGs1yomtkn5iLYei7Wu_KeDzojlOaU1IX0-3tS6hlsjRqBaQQlxQvEX5FSwKWxuh230CL4iFCpXoYxCXiwmnmKvseDB2qLFXDpN8egQ224kn5xby00L7BFFFzugBuwTqf5P9yAQGMAD3uUhnfobjsKBArnST0joOANl8xiFSyqTVyt4zVb4CZaJeswzcI4XtQblldRVWZRlMdRFpbb9aqsqjgL01WyKso8WfANDWkaZmESZWmcxkFRpdsQVytWhVGCeUqSEBvGRSBE1wRK7xbcmBY3UULzKFkIVqAwfqeSUonP4K2EUpLeL_TGOS2LdmdIEgpurHmlsdwKv8X52-OHu-UTPJH0Hh4r9OrwcVSkCFxWuEdZOcmp9suyZlwaKF4uGlIyizulXxatFpva2r3fkvSidcdt3RZBqRpCH1z84We51-pP_0l-8FkbQh-GsroN_SsAAP___r-zew">