<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">