<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/56789>56789</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Odd inline asm code generation with pointless memory operand
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
torvalds
</td>
</tr>
</table>
<pre>
So I noticed this while trying to improve on the kernel bit finding functions.
On x86-64, we use 'tzcount' in an inline asm - encoded as "rep bsf" for legacy reasons. The inline asm looks like this:
static __always_inline unsigned long __ffs(unsigned long word)
{
asm("rep; bsf %1,%0"
: "=r" (word)
: "rm" (word));
return word;
}
because the instruction can take either a register or memory operand as input, and obviously a register output.
However, this seems to confuse clang no end, and it generates completely nonsensical code for it. The code happens to *work*, but it's unbelievably stupid:
unsigned long test(unsigned long arg)
{
return __ffs(arg);
}
will generate
test:
movq %rdi, -8(%rsp)
rep ; bsfq -8(%rsp), %rax
retq
instead of the much simpler and more obvious
test:
rep; bsf %rdi,%rax
ret
that gcc generates.
There is obviously nothing special about the "rep bsf" (or "tzcount") instruction.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyNlU1z2jAQhn-NfdkJY2SwzcGHpJlMe-qhvTOSvbbVyJIryVD667sSkEAamjIM_tBq993dZ4Uw7aH-ZuALaONlgy34QTrYD1IheHuQugdvQI6TNTsEo2kd4RmtRgVCeuikboNRN-vGS6PdIskek-z--PtVw6-quCtWCfsEe4TZISSs9L8bM2tPdyA1cE2_SmoE7ka4A9SNaUkJd2TLLE4gXEd30BkLCnveHMAidyEYfCc5F7uVMc8OlHzGmEiS31_KgdPHeU7JwnbL1Z4f3PbkYNZO9poiK0MZbbdd5xJWXb_dG9smbHPtLykfrl-cPySJPByzSPKHkAjltF5SOeiS0cL7-14c5_ehBkn-aEMByNe78W9ss-ObTfTNbyi16Gerj-m9tUnKx8sqCmx4aKSPpXfezrHz0FAjPafKo6QlC5yc9tJ5uqXGjTgaewAzoeU6NlfqafYBjPBsxE6a2anD1bbZk8kVUZ_NHndow7ZIqkMcXUC0MboLqhrFqU3aEEbt2Tlx2qOmwB4dGY6TQo8UShNCSO1tuILAXCRM-iNV8cXAp4ksQoCE3VN1nukS3IrZkyUR7AgbgUrijgty6fw8yfYGd9cokRj_F1_c9v-P16lpZ1JPez9o314q9VKO91RGXYGgd2OOZvczemVr28pQirsqMr62brpJZpji0wDE3W_2kJfwwH_dzPPnpdJAHXKCposQjnMzgJOhrTb2m0jDM1H_yPCm1ItRPeb4gbjLGH7gRFvTvBJ3xS-RRdoI3Ffg6eQdwhHqJmwkkcgFcR8Tuz7-qGKEJ929HJ-Manc5ggtIsV4W6022yovVJm3rvN3kG5566RXWX9v28qyMgJ9Uhvnd09jCZKQmW-feDGw6W1UP3k_xTGVP9O3JfhYLmid6UGp3vtzRf8UPbEjfk3RuRkLzaV2U1SYd6rISosvL5TKv1pnAFpergvOyajmJ7kSRKk7D5Opk_UDpadxDdBFSXT-msmYZY1nJKrZkJdss2GolULQZijxjVVEkqwxHLtUi6FgY26e2jpLE3DtaVHSuuNdF7uLoYQxH_vnsB2Nrb-yOq9alMXYdtf8BeAsf1g">