<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61073>61073</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Generate better code X < 0 ? 2 : 0 on x86
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:X86,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
kazutakahirata
</td>
</tr>
</table>
<pre>
We should generate better code for `X < 0 ? 2 : 0`, where X is of either `int32_t` or `int64_t`. We can shorten the encoding in every case, assuming nobody needs EFLAGS of the final result.
```
uint32_t srl30_and2_i32_edi(uint32_t X) {
return (X >> 30) & 2;
// We currently generate:
// 89 f8 mov %edi,%eax ; 8 bytes
// c1 e8 1e shr $0x1e,%eax
// 83 e0 fe and $0xfffffffe,%eax
// We should generate:
// c1 ef 1f shr $0x1f,%edi ; 6 bytes
// 8d 04 3f lea (%rdi,%rdi,1),%eax
}
uint32_t srl30_and2_i32_eax(uint32_t *P) {
uint32_t X = *P;
return (X >> 30) & 2;
// We currently generate:
// c1 e8 1e shr $0x1e,%eax ; 6 bytes
// 83 e0 fe and $0xfffffffe,%eax
// We should generate:
// c1 e8 1f shr $0x1f,%eax ; 5 bytes
// 01 c0 add %eax,%eax
}
uint64_t srl62_and2_i64_rdi(uint64_t X) {
return (X >> 62) & 2;
// We currently generate:
// 48 89 f8 mov %rdi,%rax ; 10 bytes
// 48 c1 e8 3e shr $0x3e,%rax
// 83 e0 fe and $0xfffffffe,%eax
// We should generate:
// 48 c1 ef 3f shr $0x3f,%rdi ; 7 bytes
// 8d 04 3f lea (%rdi,%rdi,1),%eax ; the 32-bit form
}
uint64_t srl62_and2_i64_rax(uint64_t *P) {
uint64_t X = *P;
return (X >> 62) & 2;
// We currently generate:
// 48 c1 e8 3e shr $0x3e,%rax ; 7 bytes
// 83 e0 fe and $0xfffffffe,%eax
// We should generate:
// 48 c1 e8 3f shr $0x3f,%rax ; 6 bytes
// 01 c0 add %eax,%eax ; the 32-bit form
}
uint64_t srl30_and2_i64_rdi(uint64_t X) {
return (X >> 30) & 2;
// We currently generate:
// 48 89 f8 mov %rdi,%rax ; 10 bytes
// 48 c1 e8 1e shr $0x1e,%rax
// 83 e0 02 and $0x2,%eax
// We should generate:
// c1 ef 1f shr $0x1f,%edi ; 6 bytes
// 8d 04 3f lea (%rdi,%rdi,1),%eax ; the 32-bit form
}
uint64_t srl30_and2_i64_rax(uint64_t *P) {
uint64_t X = *P;
return (X >> 30) & 2;
// We currently generate:
// 48 c1 e8 1e shr $0x1e,%rax ; 7 bytes
// 83 e0 02 and $0x2,%eax
// We should generate:
// c1 e8 1f shr $0x1f,%eax ; 5 bytes
// 01 c0 add %eax,%eax ; the 32-bit form
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV01zozgQ_TXi0hWXkDDIBw7Oh-eyh63aw-SWEqgx2mCRkkQ2mV-_JUxwbOOJvZOZqaVSASPpqT9ev0bSOb02iDmZX5P5bSQ7X7c2f5TfOi8fZa2t9DIqWvWaf0Vwdds1CtZo0EqPUKD3aKFsFULVWiApvQfCb4AC4StgQPgSKEkpYTfwT40W4R60g7YC1L7GfoU2nrMHT1IK7duLNOlfzAC-IpTShJ2tRwO-RkBTtkqbNWgD-Iz2FUrpMGwhnes2YcS0wWQwiMrB3eqP5Ze_wqZhdaWNbMCi6xo_I_SW0OXwP6XDX_-zG-wCZxtOH6RR7EFz9oBKEybG0XvCFkCy6-0iAIu-swYIEyESd4TfAaf9HJYCI3ycSNiKsFXvX2ctGt-8joElfHkwTSygEjB5bdrncCNs3pt2Ex7kCxB-DQKKV4_uAKuMAQXEOIHlarvFSuhLjCPYoTEckEI1BSCNGgGq7XUIcxyAA1odex8sriCuPrK4GrZSejchxCGdjINQQBPgU6gNypBCwub2Labbh5iwxaE_2e17x07yRr685w1hyz_3qbOjFBB-u53AfzavLufCWZH9HQQRFxBkqI_5pPU0hpJOIAXrlYLB1A9JEDQskCBlAwnS5MGO4tGPniEeKfvxJCdi0I-dVOxo_T6jfVBiOhmVRAxR5rgXU44j0GUs-GQKDPZVoaD37KvG-t33M_u-KAQJ6DE-UoEtWmgtnF0V2odOuLmMFaM09KPH0gA7xpypDZ9EmzHjE0V1mP2zovs7KCFOUuI8NdvqQSj9oc2-q_6D2rmUBWOD-E_a8BkNYNSG4-uEWpyjEccNZaqbnJIMyk7w4w2A_U8_KX6inuwx6SM9uVhOPolpF5JjP-LfU5RfxZhf9Y3xo0Kzf5SJVM7Vgi9khHmcZlnKY74QUZ1LUdEsK0smS5UuUGZCIM5FQZnK4liISOeMMk45jSlNeCxmmIlMikzOyyJRmCxIQnEjdTNrmufNrLXrSDvXYZ7GNONRIwtsXH-2ZKyQ5SMaRfjyXqSEbTPCNto5VFftk9cb_U163ZowNr-NbB4wr4pu7UhCG-282-3itW8w_zJ1EJ04gUJr4EWkUWebvPb-yYXs9olYa193xaxsN4StAvpwu3qy7d9YesJWvUOOsFXv078BAAD__4d05D8">