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

    <tr>
        <th>Summary</th>
        <td>
            Missed Optimization: recognize output of round() and trunc() is integral
        </td>
    </tr>

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

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

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

<pre>
    When doing `round(trunc(in))` and `trunc(round(in))` the outer operation is redundant because the inner operation is guaranteed to emit an integral value. It looks like there is already some optimizations in place to eliminate these calls when the input is known to be integral, but it doesn't seem to cover mixing the functions. GCC seems to handle this correctly.

https://godbolt.org/z/xq3sqjTzb

```cpp
#include <cmath>

// These incorrectly emit both calls
double tr(double in) {
    return trunc(round(in));
}
double rt(double in) {
    return round(trunc(in));
}

// These correctly omit the outer operation
double rr(double in) {
    return round(round(in));
}
double tt(double in) {
    return trunc(trunc(in));
}
double r(long long in) {
    return round(double(in));
}
double t(long long in) {
    return trunc(double(in));
}
```

clang outout:
```asm
tr(double): # @tr(double)
  pushq %rax
  callq round@PLT
  popq %rax
  jmp trunc@PLT # TAILCALL       <--- UNNECESSARY
rt(double): # @rt(double)
  pushq %rax
  callq trunc@PLT
  popq %rax
  jmp round@PLT # TAILCALL       <--- UNNECESSARY
rr(double): # @rr(double)
  jmp round@PLT # TAILCALL
tt(double): # @tt(double)
  jmp trunc@PLT # TAILCALL
r(long long): # @r(long long)
  cvtsi2sd %rdi, %xmm0
  retq
t(long long): # @t(long long)
  cvtsi2sd %rdi, %xmm0
  retq
```

gcc output (using `-Os` to avoid the inline expansion of `trunc()`):
```asm
tr(double):
  jmp round
rt(double):
  jmp trunc
rr(double):
  jmp round
tt(double):
  jmp trunc
r(long long):
  cvtsi2sdq %rdi, %xmm0
  ret
t(long long):
  cvtsi2sdq %rdi, %xmm0
  ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVttymzoU_Rr8orEHg_HlgQfHyTnTmZy206bT6aMQ20aJkLAkHCdf3y0BKb4lPvXI3LS09toX2MpU_pL-LECSXHG5IcE01KqWeRDNra4lwzOXQbRwYxoSKnMH6aY6aB9iCyCqtqCJqkBTy5Uk3BANOWKptCQDRmsDHsilPAZuaqoRBpATqwiU3KJVBFrYaCrIjooaRuSTJUKpJ0MEf_JUGtxiKjTQ_IUYVaKKyvKSv3pmgwykEpSBZxU4Ian1K1EKo0IY8uzC0KiqauvonqR6lm5BBm8KgmhFMjdtMWRg0POZJQagdDimduhPyfculo5qjYHy9kfk39XK44wDFhhJ4cyjFaa0BmbFyygIb4Nw2RwLaysTxMsg-gfHRuWZEnak9AbvXvG_38Zm-_jwmvUXYQKawaqqfRLFXDJR50CCeMVKaosgvjtY4w2QBx8JxHZqmthnyhZNfBp0rurMCdeY9vbaZ58Es5sGQfCnwdYaI3epTuIWG8xuD2i1vYb2YoWe0J7x8I9_yvl3plwPFV3laKfoakftVY52Dn7saKcWQUJh7fnDx3qbZVcJvpK5k3oF81ux9nPFBEV-zAgOV_2HSGrK5kmv_jz3kmChk2ASHk208qraFFuEJJruu2euqLdtJCbh1_uHN7CqjrGPZdV65pHe2MPy0_1qeX9Pmh--XcPhkPz4_Pludff9-_Lbr2Zxr6QPlR5NfKi0Z_8DpT2f_pfSSzHVZ2P6nqU2SZdct2ddfy_IrcJ-ER5pPJ7qYrezhkcm92HKuft649W-LMMOgYW7bfVepj-Z-gv6s_W-YcxVu2s4aKI2bRMefjG-mSpCd4rnbVsSXAKBfUWlcd1SrfvNuOm_jeyrX5vTZJ4v2tMcnS-ZC3wnlXCJ7zQDx5Hevhvqi4n8G5q3-A0gHU-TRRjiIRnkaZwv4gUdWG4FpP9xY3Cz8qW323CFg01GbSR_hS69mK3us-s-nm4r1Uud2250W4xBrUV61P-5LepsxFSJN0LsutOw0uoR2xneoowaDF4k09ksGRTpdMomWczGjCbrKJuw2SyDkLHJZDGfRuMJHQiagTBpkNwEUSThmXgKvA6S2wFPozCKwlk0H4_DRZKMFsAyiOYzGq7j9Tx3bymUlIuR0-E2JgOdeklZvTE4Kbix5s8kNYZvJIA3h_y0toXS6TfIb4DqPEzi8cDbT73-36H-Igw">