[Bug tree-optimization/91645] Missed optimization with sqrt(x*x)
rguenther at suse dot de
gcc-bugzilla@gcc.gnu.org
Thu Sep 5 09:19:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91645
--- Comment #6 from rguenther at suse dot de <rguenther at suse dot de> ---
On Thu, 5 Sep 2019, lisyarus at gmail dot com wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91645
>
> --- Comment #5 from Nikita Lisitsa <lisyarus at gmail dot com> ---
> Oh, thank you a lot! Indeed, this version compiles to just mulss & sqrtss
>
> float test (float x)
> {
> float y = x*x;
> if (std::isless(y, 0.f))
> __builtin_unreachable();
> return std::sqrt(y);
> }
>
> Yet, I still don't quite understand what is happening here. Is it because the
> standard '<' operator is still subject to FE_* ?
It's probably because our jump-threading is imperfect if I interpret
Marcs comment correctly. When seeing LE_EXPR we only consider
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
}
so we know it's ORDERED but we don't register it's known to be UNLE as
well.
> Concerning pragmas, the code
>
> #pragma GCC optimize ("no-math-errno")
> float test (float x)
> {
> return std::sqrt(x*x);
> }
>
> produces the following assembly
>
> std::sqrt(float):
> pxor xmm2, xmm2
> movaps xmm1, xmm0
> ucomiss xmm2, xmm0
> sqrtss xmm1, xmm1
> ja .L8
> movaps xmm0, xmm1
> ret
> .L8:
> sub rsp, 24
> movss DWORD PTR [rsp+12], xmm1
> call sqrtf
> movss xmm1, DWORD PTR [rsp+12]
> add rsp, 24
> movaps xmm0, xmm1
> ret
> test(float):
> mulss xmm0, xmm0
> jmp std::sqrt(float)
>
> So, the only notable difference is that now 'std::sqrt(float)' is not inlined,
> but is tail-called instead. Thus, the pragma seems not to work?
True, there may already be a bug about this. The issue is that
whether functions set errno or not is decided globally and this
info isn't changed between functions according to pragmas.
More information about the Gcc-bugs
mailing list