From patchwork Fri Oct 28 17:27:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 80001 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1290817qge; Fri, 28 Oct 2016 10:28:30 -0700 (PDT) X-Received: by 10.99.137.66 with SMTP id v63mr22276799pgd.117.1477675710246; Fri, 28 Oct 2016 10:28:30 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id bx8si12114033pab.12.2016.10.28.10.28.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Oct 2016 10:28:30 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439848-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439848-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439848-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; q=dns; s= default; b=nZfN9Pme9h/2YCo9g5SPSCtm4d52m47CzEwl3ricykhpYZkqFzkL7 LSPHh+oQC4mbgNA0xcXcofo+nOsyu2vR1B6LIe+JcGIqbTBtaUPyGFufvM16oTNw OLineMkYSmArB1q/ITfAOCtGJ1XicuKozEqusQmP/maF7+gGIfPnyE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=default; bh=C2gOn6VIlrih/wwN6LXuJOGP58I=; b=bbOwEY2ru8sM55MDCYfBBQBThB+o FW/YOXMU4xPHu5gzyMTrW86i4coTuhRaEe2ozZONu2MI/622klScTEpb4hUxF8iD Tjf1ePA3kWIvPjThhGzCKaWA8PxMed1/Ko4QYF/F3E3e5FZSWw4FoyW0Wu5/o5qG +3MgEf2EZtJ9qwY= Received: (qmail 56901 invoked by alias); 28 Oct 2016 17:28:16 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 56884 invoked by uid 89); 28 Oct 2016 17:28:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=narrower, it!, sk:optimiz, integral X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 28 Oct 2016 17:28:06 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id CA7F681336; Fri, 28 Oct 2016 19:28:02 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hLZh2I7uEjt2; Fri, 28 Oct 2016 19:28:02 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 83A8481329; Fri, 28 Oct 2016 19:28:02 +0200 (CEST) From: Eric Botcazou To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Subject: Re: [SPARC] Add support for overflow arithmetic Date: Fri, 28 Oct 2016 19:27:56 +0200 Message-ID: <1901532.hOIG77dSjR@polaris> User-Agent: KMail/4.14.10 (Linux/3.16.7-45-desktop; KDE/4.14.9; x86_64; ; ) In-Reply-To: <20161021094809.GD7282@tucnak.redhat.com> References: <2518121.rYAYzHP3Zx@polaris> <20161021094809.GD7282@tucnak.redhat.com> MIME-Version: 1.0 > Then to some extent defining WORD_REGISTER_OPERATIONS on SPARC is a lie, > it only has "INT_REGISTER_OPERATIONS", i.e. all operations smaller than > int are performed on the whole register, int operations can be really done > in SImode in the IL (no need to sign/zero extend anything to DImode, if you > just ignore the high 32 bits). On the other hand SPARC perfectly matches the documentation: -- Macro: WORD_REGISTER_OPERATIONS Define this macro to 1 if operations between registers with integral mode smaller than a word are always performed on the entire register. Most RISC machines have this property and most CISC machines do not. If you don't define it for SPARC, then you'll never define it! The macro makes it possible to do some optimizations in combine.c and rtlanal.c so it looks quite useful. Note that SPARC is one of the very few RISC targets that don't define PROMOTE_MODE for variables since a patch of yours from 1999: https://gcc.gnu.org/ml/gcc-patches/1999-12n/msg00202.html so it's already parameterized to avoid sign/zero-extending to DImode. > Guess easiest would be to add some targetm constant or hook that gives > you bit precision - integral arithmetics smaller than this precision is > performed in precision. Then define it by default to > #ifdef WORD_REGISTER_OPERATIONS > BITS_PER_WORD > #else > BITS_PER_UNIT > #endif > and for sparc set to 32, then use this targetm constant or hook in > internal-fn.c instead of WORD_REGISTER_OPERATIONS and BITS_PER_WORD. Thanks for the hint. The hook is the way to go I think because BITS_PER_WORD is not a constant, so the default would not be properly initialized. Here's a tentative patch, I'll add a couple of SPARC-specific testcases if accepted. Tested on SPARC/Solaris, OK for the mainline? * doc/tm.texi.in (Target Macros) Add TARGET_MIN_ARITHMETIC_PRECISION. * doc/tm.texi: Regenerate. * internal-fn.c (expand_arith_overflow): Rewrite handling of target dependent support by means of TARGET_MIN_ARITHMETIC_PRECISION. * target.def (min_arithmetic_precision): New hook. * targhooks.c (default_min_arithmetic_precision): New function. * targhooks.h (default_min_arithmetic_precision): Declare. * config/sparc/sparc.c (TARGET_MIN_ARITHMETIC_PRECISION): Define. (sparc_min_arithmetic_precision): New function. -- Eric Botcazou Index: doc/tm.texi =================================================================== --- doc/tm.texi (revision 241611) +++ doc/tm.texi (working copy) @@ -10618,6 +10618,23 @@ smaller than a word are always performed Most RISC machines have this property and most CISC machines do not. @end defmac +@deftypefn {Target Hook} {unsigned int} TARGET_MIN_ARITHMETIC_PRECISION (void) +On some RISC architectures with 64-bit registers, the processor also +maintains 32-bit condition codes that make it possible to do real 32-bit +arithmetic, although the operations are performed on the full registers. + +On such architectures, defining this hook to 32 tells the compiler to try +using 32-bit arithmetical operations setting the condition codes instead +of doing full 64-bit arithmetic. + +More generally, define this hook on RISC architectures if you want the +compiler to try using arithmetical operations setting the condition codes +with a precision lower than the word precision. + +You need not define this hook if @code{WORD_REGISTER_OPERATIONS} is not +defined to 1. +@end deftypefn + @defmac LOAD_EXTEND_OP (@var{mem_mode}) Define this macro to be a C expression indicating when insns that read memory in @var{mem_mode}, an integral mode narrower than a word, set the Index: doc/tm.texi.in =================================================================== --- doc/tm.texi.in (revision 241611) +++ doc/tm.texi.in (working copy) @@ -7575,6 +7575,8 @@ smaller than a word are always performed Most RISC machines have this property and most CISC machines do not. @end defmac +@hook TARGET_MIN_ARITHMETIC_PRECISION + @defmac LOAD_EXTEND_OP (@var{mem_mode}) Define this macro to be a C expression indicating when insns that read memory in @var{mem_mode}, an integral mode narrower than a word, set the Index: internal-fn.c =================================================================== --- internal-fn.c (revision 241611) +++ internal-fn.c (working copy) @@ -1824,12 +1836,11 @@ expand_arith_overflow (enum tree_code co return; } - /* For sub-word operations, if target doesn't have them, start - with precres widening right away, otherwise do it only - if the most simple cases can't be used. */ - if (WORD_REGISTER_OPERATIONS - && orig_precres == precres - && precres < BITS_PER_WORD) + /* For operations with low precision, if target doesn't have them, start + with precres widening right away, otherwise do it only if the most + simple cases can't be used. */ + const int min_precision = targetm.min_arithmetic_precision (); + if (orig_precres == precres && precres < min_precision) ; else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres && prec1 <= precres) @@ -1864,7 +1875,7 @@ expand_arith_overflow (enum tree_code co /* For sub-word operations, retry with a wider type first. */ if (orig_precres == precres && precop <= BITS_PER_WORD) { - int p = WORD_REGISTER_OPERATIONS ? BITS_PER_WORD : precop; + int p = MAX (min_precision, precop); enum machine_mode m = smallest_mode_for_size (p, MODE_INT); tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m), uns0_p && uns1_p Index: target.def =================================================================== --- target.def (revision 241611) +++ target.def (working copy) @@ -5932,6 +5932,24 @@ comparison code or operands.", void, (int *code, rtx *op0, rtx *op1, bool op0_preserve_value), default_canonicalize_comparison) +DEFHOOK +(min_arithmetic_precision, + "On some RISC architectures with 64-bit registers, the processor also\n\ +maintains 32-bit condition codes that make it possible to do real 32-bit\n\ +arithmetic, although the operations are performed on the full registers.\n\ +\n\ +On such architectures, defining this hook to 32 tells the compiler to try\n\ +using 32-bit arithmetical operations setting the condition codes instead\n\ +of doing full 64-bit arithmetic.\n\ +\n\ +More generally, define this hook on RISC architectures if you want the\n\ +compiler to try using arithmetical operations setting the condition codes\n\ +with a precision lower than the word precision.\n\ +\n\ +You need not define this hook if @code{WORD_REGISTER_OPERATIONS} is not\n\ +defined to 1.", + unsigned int, (void), default_min_arithmetic_precision) + DEFHOOKPOD (atomic_test_and_set_trueval, "This value should be set if the result written by\ Index: targhooks.c =================================================================== --- targhooks.c (revision 241611) +++ targhooks.c (working copy) @@ -2127,4 +2127,12 @@ default_max_noce_ifcvt_seq_cost (edge e) return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3); } +/* Default implementation if TARGET_MIN_ARITHMETIC_PRECISION. */ + +unsigned int +default_min_arithmetic_precision (void) +{ + return WORD_REGISTER_OPERATIONS ? BITS_PER_WORD : BITS_PER_UNIT; +} + #include "gt-targhooks.h" Index: targhooks.h =================================================================== --- targhooks.h (revision 241611) +++ targhooks.h (working copy) @@ -260,7 +260,7 @@ extern void default_setup_incoming_varar int second_time ATTRIBUTE_UNUSED); extern bool default_optab_supported_p (int, machine_mode, machine_mode, optimization_type); - extern unsigned int default_max_noce_ifcvt_seq_cost (edge); +extern unsigned int default_min_arithmetic_precision (void); #endif /* GCC_TARGHOOKS_H */ Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 241611) +++ config/sparc/sparc.c (working copy) @@ -648,6 +648,7 @@ static reg_class_t sparc_secondary_reloa static machine_mode sparc_cstore_mode (enum insn_code icode); static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *); static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *); +static unsigned int sparc_min_arithmetic_precision (void); #ifdef SUBTARGET_ATTRIBUTE_TABLE /* Table of valid machine attributes. */ @@ -866,6 +867,9 @@ char sparc_hard_reg_printed[8]; #undef TARGET_FIXED_CONDITION_CODE_REGS #define TARGET_FIXED_CONDITION_CODE_REGS sparc_fixed_condition_code_regs +#undef TARGET_MIN_ARITHMETIC_PRECISION +#define TARGET_MIN_ARITHMETIC_PRECISION sparc_min_arithmetic_precision + #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 @@ -2749,6 +2753,14 @@ sparc_fixed_condition_code_regs (unsigne return true; } +/* Implement TARGET_MIN_ARITHMETIC_PRECISION. */ + +static unsigned int +sparc_min_arithmetic_precision (void) +{ + return 32; +} + /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, return the mode to be used for the comparison. For floating-point, CCFP[E]mode is used. CCNZmode should be used when the first operand