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

    <tr>
        <th>Summary</th>
        <td>
            InstCombine of is.fpclass pessimizes codegen for comparison with fast math flags
        </td>
    </tr>

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

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

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

<pre>
    Test case:
```
define i1 @f(float %x) {
  %y = fmul nnan float%x, 3.0
  %i = bitcast float %y to i32
  %c = icmp ne i32 %i, 0
  ret i1 %c
}
```
AMD64 codegen:
```
$ llc -mtriple=amd64 < fpc.ll
...
        mulss   .LCPI0_0(%rip), %xmm0
        movd    %xmm0, %eax
        testl   %eax, %eax
        setne   %al
```
AMD64 codegen after InstCombine:
```
$ opt -S -passes=instcombine < fpc.ll | llc -mtriple=amd64
...
        mulss   .LCPI0_0(%rip), %xmm0
        movd    %xmm0, %eax
        movl    %eax, %ecx
        negl    %ecx
        seto    %cl
        andl    $2147483647, %eax # imm = 0x7FFFFFFF
        cmpl    $2139095040, %eax               # imm = 0x7F800000
        sete    %dl
        orb     %cl, %dl
        leal    -1(%rax), %ecx
        cmpl    $8388607, %ecx                  # imm = 0x7FFFFF
        setb    %cl
        orb     %dl, %cl
        addl    $-8388608, %eax # imm = 0xFF800000
        cmpl    $2130706432, %eax               # imm = 0x7F000000
        setb    %al
        orb     %cl, %al
```
Here's what happens:
1. InstCombine recognizes the icmp-of-bitcast and turns it into llvm.is.fpclass(%y, 0x3bf)
2. InstCombine recognizes that %y cannot be nan and turns this into llvm.is.fpclass(%y, 0x3bc) (see https://github.com/llvm/llvm-project/blob/14d57e21e1cc76de554314015e11a9d6e9b797f5/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp#L1036). This seems dubious to me - it could just as well set these bits, or leave them alone. I guess clearing them works as a kind of canonicalization so that we could CSE two calls to llvm.is.fpclass that differ only in the "nan" bits if the argument is known not to be nan. Really it would be nice if we could set these bits to a "don't care" value.
3. CodeGen does not recognize this as a special case and has to emit a long sequence of comparisons. This could be improved if the "not nan" information is still available at this point.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8VluP2zYT_TX0y8ACRd0f_JDYn78GSIGiyXtBkSObCUWqImXv5tcXpHzRrnfb9KXCAmuRhzNnzlxE7pw6GMQNKT6SYrfikz_acfONP3eWy1Vr5fPmKzoPgjsk2QdCd4R-ICW9_MVXiZ0yCCoFktOOsLrTlnsgrHgirAFSfZxxEJaegWQ76PpJgzHcQMTO0C1kCV1AVYS2ygvuPNyMPoO3oDK2QIqIVKIfIBDJWDweLN7sjegjQ1aISxDV7s1oPvy6K3MQVuIBzXshE5aD1gLWvR_VoJFkO97LMgeSbaEbRKL1DEyS5HKCNv2knSO0ST5vf_tE_6CE1YQVoxoIawLXoELf0zveniShzXV5RiB_ugE8Oq9nRFh-BDj0BmcA1_8cLfDO4wifjPNb27fKvJvyEL8dPKy_wHrgzqEj2U4Z58V8bqEDkGr7plb_gUC9PT3qI-77Bg_XffFCNTuvCn1b5EbO0JyleZXXWZlXd49AWAaq72Md0qdqPz-306IfbqezhjYFzRd84eXz2lZNw7Okd8mpvNOzY3ujPNtdbGoM2W_W6UXQoEXzhhx3lnVW1yWt7hh4eN6KeMmxfZDwxlFeOS71lVd917Pz-l11968VeaEurWiZZ-yn1aUP6ravOuYtdd9pp19wRMIqB-cj93Dkw4DG3ZooTZa9BSMKezDqBzrwR4zja2279XXgcSPBT6NxoDwo4y1ofeoT5ZJuEJo7N2fzOY65p6ztQlKjH_Y3fq4zVHBjrIcWIUzhuy9_VO5nvIk42lntEOHo_RCjZHvC9gflj1ObCNsTtg9GLv_Ww2i_ofCE7VttW8L2aS6LClmKqRBVKbEo8izNaVpgmvJGlti0VVN1xcKOCue-jty4zo69I2y_nFYv3rZca5eIYSAs-5zSrCSsSeBriM8h9g7k1Co7ufA56RHWQWZhJy3h2xTkd3BGrcGhD-lxGL5ELoRvR9DITxiWe-DaGkzgExwmdA6ERj4qc5g3z3b87oIpDt-VkWC7ILw1SnCtfnCvrAFn57Sc8eJ---V_4M8WRAgAHjMxw6XqOhzBGv0MysQKIowZbghjkSqoLq7y8TD1aDwoB9-NPRsIiff2kvsEfkeugxEP5-g_rCuB4fyN00sVwmke3ElrCKvC9SDUPYMT1xNeBnqWwNZK_D8akBZd9HorxbnOojBuQKG4jleMWIhHHh1grzxw0NYcwOGfExqBUUDbD3xUzhp3Sae40lb9MNoTymvoQRDr4SKKMqFmZtFDEXilNfATV5q3GoH7mdRglfHJSm4y2WQNX-EmrVhWp3VTN6vjRlQtrcuUlyJvu6pqsiytS1nlXc4oo127UhtGWU7rtEzzrGR1UnDZpdjmVdXxqpApySn2XOkk5tWOh5VybsJNSvOiqVaat6hdvJExZvAMcZcwFi5o4ya2UjsdHMmpVs67uxmvvMbNsvVtB4u6GdA51cdBcP3id3ZcCApn5Y_QhenT8_BL84NbTaPe_OsWj6RDf16iOm3YXwEAAP__j3wQmA">