public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated
@ 2011-03-03 16:32 Andreas Krebbel
  2011-04-15 17:26 ` Bernd Schmidt
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas Krebbel @ 2011-03-03 16:32 UTC (permalink / raw)
  To: gcc-patches

Hi,

I've refreshed the patch:

[PATCH] Fix PR46399 - missing mode promotion for libcall args
http://gcc.gnu.org/ml/gcc-patches/2011-02/msg01595.html

after removing the FUNCTION_VALUE target macro with:

[Committed] S/390: Remove deprecated target macro FUNCTION_VALUE
http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00127.html

And I've moved the documentation of the new target hook to target.def
as requested by Nathan.

Bootstrapped on x86_64, s390 and s390x. No regressions.

Two testcases fixed on s390x:

< FAIL: gcc.dg/dfp/pr41049.c execution test
< FAIL: decimal/comparison.cc execution test

Ok for mainline?

Bye,

-Andreas-


2011-03-04  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	PR middle-end/46399
	* calls.c (emit_library_call_value_1): Promote libcall arguments
	using promote_libcall_mode.
	* explow.c (promote_libcall_mode): New function.
	* expr.h (promote_libcall_mode): New prototype.
	* target.def (promote_libcall_mode): New target hook.
	* targhooks.c (default_promote_libcall_mode): New function.
	* targhooks.h (default_promote_libcall_mode): New prototype.
	* config/s390/s390.c (s390_promote_libcall_mode): New function.

	* doc/tm.texi: Regenerate.


Index: gcc/calls.c
===================================================================
*** gcc/calls.c.orig
--- gcc/calls.c
*************** emit_library_call_value_1 (int retval, r
*** 3481,3486 ****
--- 3481,3487 ----
      {
        rtx val = va_arg (p, rtx);
        enum machine_mode mode = (enum machine_mode) va_arg (p, int);
+       int unsigned_p = 0;
  
        /* We cannot convert the arg value to the mode the library wants here;
  	 must do it earlier where we know the signedness of the arg.  */
*************** emit_library_call_value_1 (int retval, r
*** 3528,3536 ****
  	  val = force_operand (XEXP (slot, 0), NULL_RTX);
  	}
  
!       argvec[count].value = val;
        argvec[count].mode = mode;
! 
        argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode,
  						      NULL_TREE, true);
  
--- 3529,3537 ----
  	  val = force_operand (XEXP (slot, 0), NULL_RTX);
  	}
  
!       mode = promote_libcall_mode (mode, &unsigned_p, fntype, 1);
        argvec[count].mode = mode;
!       argvec[count].value = convert_modes (mode, GET_MODE (val), val, unsigned_p);
        argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode,
  						      NULL_TREE, true);
  
Index: gcc/explow.c
===================================================================
*** gcc/explow.c.orig
--- gcc/explow.c
*************** promote_function_mode (const_tree type, 
*** 783,788 ****
--- 783,807 ----
        return mode;
      }
  }
+ 
+ /* Return the mode to use to pass or return a scalar of MODE for a libcall.
+    PUNSIGNEDP points to the signedness of the type and may be adjusted
+    to show what signedness to use on extension operations.
+ 
+    FOR_RETURN is nonzero if the caller is promoting the return value
+    of FNDECL, else it is for promoting args.  */
+ 
+ enum machine_mode
+ promote_libcall_mode (enum machine_mode mode, int *punsignedp,
+ 		      const_tree funtype, int for_return)
+ {
+   if (INTEGRAL_MODE_P (mode))
+       return targetm.calls.promote_libcall_mode (mode, punsignedp, funtype,
+ 						 for_return);
+   else
+     return mode;
+ }
+ 
  /* Return the mode to use to store a scalar of TYPE and MODE.
     PUNSIGNEDP points to the signedness of the type and may be adjusted
     to show what signedness to use on extension operations.  */
Index: gcc/expr.h
===================================================================
*** gcc/expr.h.orig
--- gcc/expr.h
*************** extern rtx force_not_mem (rtx);
*** 613,618 ****
--- 613,623 ----
  extern enum machine_mode promote_function_mode (const_tree, enum machine_mode, int *,
  					        const_tree, int);
  
+ /* Return mode and signedness to use when an libcall argument or
+    result in the given mode is promoted.  */
+ extern enum machine_mode promote_libcall_mode (enum machine_mode, int *,
+ 					       const_tree, int);
+ 
  /* Return mode and signedness to use when an object in the given mode
     is promoted.  */
  extern enum machine_mode promote_mode (const_tree, enum machine_mode, int *);
Index: gcc/target.def
===================================================================
*** gcc/target.def.orig
--- gcc/target.def
*************** DEFHOOK
*** 1918,1923 ****
--- 1918,1935 ----
   default_promote_function_mode)
  
  DEFHOOK
+ (promote_libcall_mode,
+  "Like @code{TARGET_PROMOTE_FUNCTION_MODE}, but it is applied to libcall\
+  arguments only.  Define this if your target requires function\
+  arguments to be promoted to a larger mode and uses C compiled libcall\
+  routines (e.g. libdecnumber).\
+ \
+  The default is not promote arguments and return values.",
+  enum machine_mode, (enum machine_mode mode, int *punsignedp,
+ 		     const_tree funtype, int for_return),
+  default_promote_libcall_mode)
+ 
+ DEFHOOK
  (promote_prototypes,
   "",
   bool, (const_tree fntype),
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig
--- gcc/targhooks.c
*************** default_promote_function_mode_always_pro
*** 139,144 ****
--- 139,153 ----
    return promote_mode (type, mode, punsignedp);
  }
  
+ enum machine_mode
+ default_promote_libcall_mode (enum machine_mode mode,
+ 			      int *punsignedp ATTRIBUTE_UNUSED,
+ 			      const_tree funtype ATTRIBUTE_UNUSED,
+ 			      int for_return ATTRIBUTE_UNUSED)
+ {
+   return mode;
+ }
+ 
  
  enum machine_mode
  default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig
--- gcc/targhooks.h
*************** extern enum machine_mode default_promote
*** 28,33 ****
--- 28,35 ----
  							int *, const_tree, int);
  extern enum machine_mode default_promote_function_mode_always_promote
  			(const_tree, enum machine_mode, int *, const_tree, int);
+ extern enum machine_mode default_promote_libcall_mode (enum machine_mode,
+ 						       int *, const_tree, int);
  
  extern enum machine_mode default_cc_modes_compatible (enum machine_mode,
  						      enum machine_mode);
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_promote_function_mode (const_tree t
*** 8687,8692 ****
--- 8687,8706 ----
    return mode;
  }
  
+ /* Libcall arguments and return values are promoted to word size.  */
+ 
+ static enum machine_mode
+ s390_promote_libcall_mode (enum machine_mode mode,
+ 			   int *punsignedp ATTRIBUTE_UNUSED,
+ 			   const_tree fntype ATTRIBUTE_UNUSED,
+ 			   int for_return ATTRIBUTE_UNUSED)
+ {
+   if (GET_MODE_SIZE (mode) < UNITS_PER_LONG)
+    return Pmode;
+ 
+   return mode;
+ }
+ 
  /* Define where to return a (scalar) value of type RET_TYPE.
     If RET_TYPE is null, define where to return a (scalar)
     value of mode MODE from a libcall.  */
*************** s390_function_and_libcall_value (enum ma
*** 8698,8710 ****
  				 bool outgoing ATTRIBUTE_UNUSED)
  {
    /* For normal functions perform the promotion as
!      promote_function_mode would do.  */
    if (ret_type)
      {
        int unsignedp = TYPE_UNSIGNED (ret_type);
        mode = promote_function_mode (ret_type, mode, &unsignedp,
  				    fntype_or_decl, 1);
      }
  
    gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
    gcc_assert (GET_MODE_SIZE (mode) <= 8);
--- 8712,8732 ----
  				 bool outgoing ATTRIBUTE_UNUSED)
  {
    /* For normal functions perform the promotion as
!      promote_function_mode would do and for libcalls use
!      promote_libcall_mode instead.  */
    if (ret_type)
      {
        int unsignedp = TYPE_UNSIGNED (ret_type);
        mode = promote_function_mode (ret_type, mode, &unsignedp,
  				    fntype_or_decl, 1);
      }
+   else
+     {
+       int unsignedp = 0;
+       mode = promote_libcall_mode (mode, &unsignedp,
+ 				   fntype_or_decl, 1);
+     }
+ 
  
    gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
    gcc_assert (GET_MODE_SIZE (mode) <= 8);
*************** s390_loop_unroll_adjust (unsigned nunrol
*** 10715,10720 ****
--- 10737,10745 ----
  
  #undef TARGET_PROMOTE_FUNCTION_MODE
  #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
+ #undef TARGET_PROMOTE_LIBCALL_MODE
+ #define TARGET_PROMOTE_LIBCALL_MODE s390_promote_libcall_mode
+ 
  #undef TARGET_PASS_BY_REFERENCE
  #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
  
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig
--- gcc/doc/tm.texi
*************** Do not define this macro if it would nev
*** 959,964 ****
--- 959,968 ----
  @end defmac
  
  @deftypefn {Target Hook} {enum machine_mode} TARGET_PROMOTE_FUNCTION_MODE (const_tree @var{type}, enum machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return})
+ 
+ @deftypefn {Target Hook} {enum machine_mode} TARGET_PROMOTE_LIBCALL_MODE (enum machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return})
+ Like @code{TARGET_PROMOTE_FUNCTION_MODE}, but it is applied to libcall arguments only.  Define this if your target requires function arguments to be promoted to a larger mode and uses C compiled libcall routines (e.g. libdecnumber). The default is not promote arguments and return values.
+ @end deftypefn
  Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or
  function return values.  The target hook should return the new mode
  and possibly change @code{*@var{punsignedp}} if the promotion should

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated
  2011-03-03 16:32 [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated Andreas Krebbel
@ 2011-04-15 17:26 ` Bernd Schmidt
  2011-04-18  9:26   ` Andreas Krebbel
  0 siblings, 1 reply; 4+ messages in thread
From: Bernd Schmidt @ 2011-04-15 17:26 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches, Julian Brown

On 03/03/2011 05:32 PM, Andreas Krebbel wrote:
> [PATCH] Fix PR46399 - missing mode promotion for libcall args
> http://gcc.gnu.org/ml/gcc-patches/2011-02/msg01595.html
> 
> after removing the FUNCTION_VALUE target macro with:
> 
> [Committed] S/390: Remove deprecated target macro FUNCTION_VALUE
> http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00127.html
> 
> And I've moved the documentation of the new target hook to target.def
> as requested by Nathan.
> 
> Bootstrapped on x86_64, s390 and s390x. No regressions.
> 
> Two testcases fixed on s390x:
> 
> < FAIL: gcc.dg/dfp/pr41049.c execution test
> < FAIL: decimal/comparison.cc execution test

The problem is quite real, it's just bitten us with some ARM changes.
The fact that we don't have types for libcall function args is very
unfortunate. Maybe that's something we need to change? It would be a
much better fix, and it might not even be _that_ much work to add an
optional type field to each optab entry, which could then be passed to
emit_library_call - if it's nonnull, we'd use the normal
promote_function_mode hook otherwise ignore the problem as before. This
would allow us to solve the s390 problem reasonably quickly and lets us
add more libcall types later.

As to the existing patch, isn't fntype NULL throughout
emit_library_call_value_1? It might make sense to lose that argument
from the hook. I also doubt that the unsignedp bit is very useful
without an argument type, but I'm at a loss to think of something
sensible to do about it.


Bernd

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated
  2011-04-15 17:26 ` Bernd Schmidt
@ 2011-04-18  9:26   ` Andreas Krebbel
  2011-05-04 14:15     ` Bernd Schmidt
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas Krebbel @ 2011-04-18  9:26 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: gcc-patches

> The problem is quite real, it's just bitten us with some ARM changes.
> The fact that we don't have types for libcall function args is very
> unfortunate. Maybe that's something we need to change? It would be a
> much better fix, and it might not even be _that_ much work to add an
> optional type field to each optab entry, which could then be passed to
> emit_library_call - if it's nonnull, we'd use the normal
> promote_function_mode hook otherwise ignore the problem as before. This
> would allow us to solve the s390 problem reasonably quickly and lets us
> add more libcall types later.

If it is not for ABI differences anymore what's the reason for
handling libcalls differently from normal calls anymore?  Couldn't we
get rid of all the special handling and deal with them like normal
calls?

Bye,

-Andreas-

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated
  2011-04-18  9:26   ` Andreas Krebbel
@ 2011-05-04 14:15     ` Bernd Schmidt
  0 siblings, 0 replies; 4+ messages in thread
From: Bernd Schmidt @ 2011-05-04 14:15 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

On 04/18/2011 10:26 AM, Andreas Krebbel wrote:
> If it is not for ABI differences anymore what's the reason for
> handling libcalls differently from normal calls anymore?  Couldn't we
> get rid of all the special handling and deal with them like normal
> calls?

That would be desirable IMO.


Bernd

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-05-04 14:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-03 16:32 [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated Andreas Krebbel
2011-04-15 17:26 ` Bernd Schmidt
2011-04-18  9:26   ` Andreas Krebbel
2011-05-04 14:15     ` Bernd Schmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).