From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28895 invoked by alias); 3 Mar 2011 16:32:15 -0000 Received: (qmail 28885 invoked by uid 22791); 3 Mar 2011 16:32:13 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_FN,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mtagate7.uk.ibm.com (HELO mtagate7.uk.ibm.com) (194.196.100.167) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 Mar 2011 16:32:06 +0000 Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate7.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p23GW3Fx031961 for ; Thu, 3 Mar 2011 16:32:03 GMT Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p23GWFhJ1339474 for ; Thu, 3 Mar 2011 16:32:15 GMT Received: from d06av10.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p23GW3ur014265 for ; Thu, 3 Mar 2011 09:32:03 -0700 Received: from bart (dyn-9-152-224-59.boeblingen.de.ibm.com [9.152.224.59]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p23GW1Cq014209 for ; Thu, 3 Mar 2011 09:32:02 -0700 Received: by bart (sSMTP sendmail emulation); Thu, 03 Mar 2011 17:32:01 +0100 From: "Andreas Krebbel" Date: Thu, 03 Mar 2011 16:32:00 -0000 To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR46399 - missing mode promotion for libcall args - updated Message-ID: <20110303163201.GA6168@bart> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-03/txt/msg00141.txt.bz2 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 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