On Wed, May 8, 2019 at 12:09 PM JunMa <ju...@linux.alibaba.com> wrote:
>
> Hi
>
> As PR90106 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90106),
> when gcc meets builtin function call like:
>
>    y = sqrt (x);
>
> The cdce pass tries to transform the call into an internal function
> call and conditionally executes call with a simple range check on the
> arguments which can detect most cases and the errno does not need
> to be set. It looks like:
>
>    y = IFN_SQRT (x);
>    if (__builtin_isless (x, 0))
>      sqrt (x);
>
> However, If the call is in tail position, for example:
>
>    y =  sqrt (x);
>    return y;
>
> will become:
>
>    y = IFN_SQRT (x);
>    if (__builtin_isless (x, 0))
>      sqrt (x);
>    return y;
>
> This transformation breaks tailcall pattern, and prevents
> later tailcall optimizations.
>
> So This patch transform builtin call with return value into
> if-then-else part, which looks like:
>
>    y =  sqrt (x);
>     ==>
>    if (__builtin_isless (x, 0))
>      y = sqrt (x);
>    else
>      y = IFN_SQRT (x);
>
> BTW, y = sqrt (x) can also transform like:
>
>    y = IFN_SQRT (x);
>    if (__builtin_isless (x, 0))
>      y = sqrt (x);
>
> We don‘t choose this pattern because it emits worse assemble
> code(more move instruction and use more registers) in x86_64.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

OK.

Thanks,
Richard.


> Regards
> JunMa
>
>
> gcc/ChangeLog
>
> 2019-05-07  Jun Ma <ju...@linux.alibaba.com>
>
>      PR tree-optimization/90106
>      * tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds): Add
>      new parameter as new internal function call, also move it to new
>      basic block.
>      (use_internal_fn): Pass internal function call to
>      shrink_wrap_one_built_in_call_with_conds.
>
> gcc/testsuite/ChangeLog
>
> 2019-05-07  Jun Ma <ju...@linux.alibaba.com>
>
>      PR tree-optimization/90106
>      * gcc.dg/cdce1.c: Check tailcall code generation after cdce pass.
>      * gcc.dg/cdce2.c: Likewise.
>

Reply via email to