<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57831>57831</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[InstCombine] Generalise `((x1 ^ y1) | (x2 ^ y2)) == 0` transform to more than two pairs of variables
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:optimizations,
llvm:instcombine,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Kmeakin
</td>
</tr>
</table>
<pre>
InstCombine currently recognises `((x1 ^ y1) | (x2 ^ y2)) == 0` as an idiom for `x1 == y1 && x2 == y2`, but this idiom detection does not work when more than 2 pairs of variables are being compared:
This function
```c
bool xor2(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2) {
return ((x1 ^ y1) | (x2 ^ y2)) == 0;
}
```
is simplified to
```
define i1 @xor2(i64 %0, i64 %1, i64 %2, i64 %3) {
%5 = icmp eq i64 %0, %1
%6 = icmp eq i64 %2, %3
%7 = and i1 %5, %6
ret i1 %7
}
```
But these two functions are not:
```c
bool xor3(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, uint64_t x3,
uint64_t y3) {
return ((x1 ^ y1) | (x2 ^ y2) | (x3 ^ y3)) == 0;
}
bool xor4(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, uint64_t x3,
uint64_t y3, uint64_t x4, uint64_t y4) {
return ((x1 ^ y1) | (x2 ^ y2) | (x3 ^ y3) | (x4 ^ y4)) == 0;
}
```
```
define i1 @xor3(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
%7 = xor i64 %1, %0
%8 = xor i64 %3, %2
%9 = or i64 %8, %7
%10 = xor i64 %5, %4
%11 = or i64 %9, %10
%12 = icmp eq i64 %11, 0
ret i1 %12
}
define i1 @xor4(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7) {
%9 = xor i64 %1, %0
%10 = xor i64 %3, %2
%11 = or i64 %10, %9
%12 = xor i64 %5, %4
%13 = or i64 %11, %12
%14 = xor i64 %7, %6
%15 = or i64 %13, %14
%16 = icmp eq i64 %15, 0
ret i1 %16
}
```
[godbolt](https://godbolt.org/z/ojdexqrYP)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9VkuT2ygQ_jXShcqUeOh10CEz3t3ayiWHXPa0hQy2SSRwAGXs_Po0SLZl2dnZSVJRYRm6P31NvyRaI47N39r5J9O3Sku0HqyV2ndHZOXabLVy0qGkyBJSwThglOR_oCNOSI2S8gkFGRllBGRRTFcwUAYPIe4Q10gJZXq0MTYQBYoRcYQZKWCgQDHJSLT1hNrBI79TbnpYSC_XXhmNhIENaePRs7Gf0PNOatQbKwEMlgjac2UdMhv0hVvF2w7AHLStVHqL1qbfw0ok9G2SrZJsun8IdjaDjgYmRZGNYz2uW2M6dDAWnKwGpX3B_vXogMNOz8vj9fJArrVkjNnjSIjgstIPVqMfCC2dWJJytdjvuAR_nOr3ndooKZA36C5KyE1IuQLLLJucUwUDy3nMwTTHszmZzenCIRDlYYtIrfs9kp_RnCvyXIDFPSCZgHQGLCOQaxG3CRYmTHHCQBAnVfnfMRnvj7GupIOCeTbnpI9FAlV1qYzvFAD9qQKYa4Hp6VIL43UBL4P7ymo5y-gooy9X0JWb7Pe5OQezayr264NwlrFRxl7bWi_0EH11D53nbDbPb3tr7AQwccUZ7VxA1RJEJxCZgaK36IKpJkw5w-BsyXTqPDZH4QVVfer1-aYwudftOO4_u-1jTO6W5jLS7JdF-jwvZvPyNgP1_8nAbeDupeAmcPj0lqxvA_dSEuiS67QvfGWSLcnK5bs0oPIl2Wn7-Mrm3Rc4zr-X0uKFpsoft0a0pvNJvoK87rzfu_AuJn_CmFQPxm5h9RV-5qOQh8_2n_eQpFQ2uChoQQhmdSoaKmpa89Qr38kGiGenGyBHf0ktLe_gXPPjxxpvuXZwnunDp_Vy-ghflDvnj3SwXbPwSPnd0D7AeQQWXffl9Pdmb81HOOjAUjk3SAeTvKwoTneNqJhoM4oxxYLl6w2XOdnIvAquV3mN0463snPB5YSQSErfmr1XvfrK40cOxGMuT1oFoVlPoTnrerAsxZv5k0GZr1LVkIyQrMY1wThn9QOreLmpRAkhJ6ISOTSm7LnqHgJ_SFdqm-hWO2wdKCHq3l2U3Dm11TJmKfDzwe-Mbd71kn9SOo0RaKL73wAYib1z">