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

    <tr>
        <th>Summary</th>
        <td>
            s390x: `vec_subc_u128` is not recognized
        </td>
    </tr>

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

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

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

<pre>
    https://godbolt.org/z/EjoWhj8MM

I expect these to optimize to the same output, but they do not:

```llvm
define noundef <16 x i8> @vec_subc_u128_intrinsic(<16 x i8> %a, <16 x i8> %b) unnamed_addr {
start:
  %0 = bitcast <16 x i8> %a to i128
  %1 = bitcast <16 x i8> %b to i128
  %_3 = tail call noundef i128 @llvm.s390.vscbiq(i128 noundef %0, i128 noundef %1) #3
  %2 = bitcast i128 %_3 to <16 x i8>
  ret <16 x i8> %2
}

define <16 x i8> @vec_subc_u128_manual(<16 x i8> %a, <16 x i8> %b) unnamed_addr {
start:
  %0 = bitcast <16 x i8> %a to i128
  %1 = bitcast <16 x i8> %b to i128
  %_8.1 = icmp uge i128 %0, %1
  %_5 = zext i1 %_8.1 to i128
  %2 = bitcast i128 %_5 to <16 x i8>
  ret <16 x i8> %2
}

declare i128 @llvm.s390.vscbiq(i128, i128) unnamed_addr #2
```

The equivalent with `vec_addc_u128` does get optimized into just a `vaccq` instruction. For the subtraction here we get this:

```asm
vec_subc_u128_intrinsic:
        vscbiq  %v24, %v24, %v26
 br      %r14

.LCPI1_0:
        .quad   0
        .quad 1
vec_subc_u128_manual:
        veclg   %v24, %v26
        jlh .LBB1_2
        vchlgs  %v0, %v26, %v24
.LBB1_2:
        ipm     %r0
 xilf    %r0, 268435456
        afi     %r0, 1879048192
        vlvgp %v0, %r0, %r0
        larl    %r1, .LCPI1_0
        vl      %v1, 0(%r1), 3
        vrepib  %v2, 31
        vsrlb   %v0, %v0, %v2
        vsrl %v0, %v0, %v2
        vn      %v24, %v0, %v1
        br %r14
```

which is unfortunate.

in the addition case, we see

```llvm
define <16 x i8> @vec_addc_u128_manual(<16 x i8> %a, <16 x i8> %b) unnamed_addr {
start:
  %0 = bitcast <16 x i8> %a to i128
  %1 = bitcast <16 x i8> %b to i128
  %2 = tail call { i128, i1 } @llvm.uadd.with.overflow.i128(i128 %0, i128 %1)
  %_7.1 = extractvalue { i128, i1 } %2, 1
  %_5 = zext i1 %_7.1 to i128
  %3 = bitcast i128 %_5 to <16 x i8>
  ret <16 x i8> %3
}
```

so here the `@llvm.uadd.with.overflow.i128` is explicitly there. That won't work for the signed overflowing subtraction, which is too clever and just performs a compare.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUVkuP2zgM_jXKhaghy88ccphHAxRogT0U2GMgS0ysqSJlJDmZ9tcvJCfOq-0sdk8dDBBb_kiRH8lP4t6rjUFckOqRVM8zPoTeusXa6m_ogsT9rLPy-6IPYedJ8UDYkrDlxsrO6pBZtyFs-YOw5ccX-3f_0n75QugDoQ-fAN92KAKEHj1CsGB3QW3Vj_QcegTPtwh2CLshEPYE3ZCw30FaMDbEnZIjUtPxX-v9ltAHiWtlEIwdjMQ1kOIpr-ENVEuKj0BKukex8kMnVkPO2pUywSnjlSCsvYGyisd971Y7wuYwGMO3KFdcSgekeST0wQfujmFBxFEgxTN0Kgjuw70bHvNUOWtP-Pz3-O4WvyqSQeBKg-BaTylHUMw0EpL5Yk6zvRedeiWsTZ8malhFY4a3i3lMkLCiOO3EriIb3af9g72OMxk4_En0LFaqeR5LdizRO6XZcjNw_QfWpc1GEyW2Oxg2ODGW2E4En6BVAv7At0jrZHzj8Bf0V_-dfqG5w_f65NQa97Sygl0O3uj1a4-Ar4Pac40mwEGFHkidasqlHGtKagrSoocNhmneJSgTLLwMPgBPJlyI1whVxgc3iKCsyWBp3SgLQxccT4vQo0M4YHIXeuXvRYH7qAm_mvljU4x_Y_KJ8T0rj6W6fKojuHMjmrDK5eW4W_b56a9P-Ype-8teBy4BgN6t5XchHXv9Oh4UegN38dQXkBfdQ_b58TFfsUtD0euNHw3phd05oxjyaHW1o9ptp9xS1G9Kr88L7AlY3ZZFVVaXQfC1gitQ3jZzWrb5_Coovd_srkJyFw9nnOZOT_xGwETupa-pBvuEoVElRoN5fC8uwQ53qjvSmD7mV0V3uoMbrs6k3SD_DcycYztXbYJe7t25iy66HqZDr0QPysNg1taFwfCA2fhJmTQGXEqVZkBwj9H7AcEj_vZM_KngTsP5xwouuzkHSfMIZwED0jxPKjdwKbMoTZndo1tre8hGZHul0aeX1E8nrW6Oso5vSX_2XA_4072i3MYx-I3KN_cqX_x_lS_OKn_dTt6OUhkbJy6-w0aUXh_vZ1oJFfT3aOcwg689D3CwhrAm_rpvsD6JcrwhSji5UWZzqdOpPU8dHawFoXGPDriRo-zv0K2t23rgIOx2xx1mM7ko5LyY8xku8qbMaVmWrJn1i3Iui6aheblmNRM8x4rWVVXJVgpWFpWYqQWjrKIFLVjBGtpkdU7Lel53bYnNvJlLUlLccqWzRIJ1m5nyfsBFzuY1bWead6h9uu0yZvAA6SthLF5-3SIafeiGjY8sKh_82U1QQeMinqRvpHg4nX6Tyh95NTaAQ2E3Jh5-s8Hp27uzCv3QZcJuCVumCR5_PuycfUERCFumkDxhy2PM-wX7JwAA__-OSDKY">