This is part one of a two part patch I want to checkin in order to improve
argument passing on MIPS.  Right now MIPS defines TARGET_PROMOTE_PROTOTYPES
as true and so short and char arguments are getting promoted in the caller and
callee functions.  The ABI requires callers to do the promotion and so
I want to remove the definition of TARGET_PROMOTE_PROTOTYPES which will
get rid of the promotion done in the callee.  This matches what LLVM and
the MIPS Greenhills compilers do.

When I made this change I had one regression in the GCC testsuite
(gcc.dg/fixed-point/convert-sat.c).  I tracked this down to the 
fact that emit_library_call_value_1 does not do any argument promotion
because it does not have the original tree type information for library
calls.  It only knows about modes.  I can't change emit_library_call_value_1
to do the promotion because it does not know whether to do a signed or
unsigned promotion, but expand_fixed_convert could do the conversion
before calling emit_library_call_value_1 and that is what this patch does.

Note that if a target uses one of the default argument promotion functions
like default_promote_function_mode or
default_promote_function_mode_always_promote, this change will have no
affect because they call promote_mode and if promote_mode is called with
a NULL_TREE as the first argument it returns the original mode.  For target
specific promote functions, this change should just cause the promotion
to be done in expand_fixed_convert instead of in emit_library_call_value_1
and with the proper setting of unsignedp.

This patch by itself will not fix my MIPS bug because it uses one of the
default promote functions.  Part two of this patch will be to define the
TARGET_PROMOTE_FUNCTION_MODE macro on MIPS so that it promotes QI and HI
to SI even if the type tree is NULL and then everything will work.

The 'real' long term fix for this problem is to have tree types for builtin
functions so the proper promotions can always be done but that is a fairly
large change that I am not willing to tackle right now and it could probably
not be done in time for GCC 6.0 anyway.

See https://gcc.gnu.org/ml/gcc/2015-10/msg00234.html for more discussion
of this change.

Is this part of the patch OK to checkin?  Tested on mips-mti-linux-gnu.

Steve Ellcey
sell...@imgtec.com


2015-11-06  Steve Ellcey  <sell...@imgtec.com>

        * optabs.c (expand_fixed_convert): Call promote_function_mode.


diff --git a/gcc/optabs.c b/gcc/optabs.c
index fdcdc6a..964e92a 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4880,6 +4880,24 @@ expand_fixed_convert (rtx to, rtx from, int uintp, int 
satp)
   libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
   gcc_assert (libfunc);
 
+  if (SCALAR_INT_MODE_P (from_mode))
+    {
+      /*  If we need to promote the integer function argument we need to do
+         it here instead of inside emit_library_call_value because here we
+         know if we should be doing a signed or unsigned promotion.  */
+
+      machine_mode arg_mode;
+      int unsigned_p = 0;
+
+      arg_mode = promote_function_mode (NULL_TREE, from_mode,
+                                       &unsigned_p, NULL_TREE, 0);
+      if (arg_mode != from_mode)
+       {
+         from = convert_to_mode (arg_mode, from, uintp);
+         from_mode = arg_mode;
+       }
+    }
+
   start_sequence ();
   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
                                   1, from, from_mode);

Reply via email to