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. >