From patchwork Thu Jul 28 13:36:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 72949 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp856751qga; Thu, 28 Jul 2016 06:37:17 -0700 (PDT) X-Received: by 10.98.86.154 with SMTP id h26mr59202261pfj.22.1469713037634; Thu, 28 Jul 2016 06:37:17 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id lf7si12479111pab.197.2016.07.28.06.37.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Jul 2016 06:37:17 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-432696-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-432696-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-432696-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; q=dns; s=default; b=qSV/vkBTc629mWw dsSEfkjBV4V+v7Y4oUjnL74aQFF+PBXl0slH6oeMKUp9/UafQmEGGBmXOTvDxpuI ajRiu5slzta1UpEC0wmIDnH0GtOA+haUH/agF1TA5sBCBAIT6IJKJOF037yiL0g2 J6ua9CTqGKraT7EYhLbAraUgM/FU= 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; s=default; bh=fr6KfO+x+MrPocg0k5OiV sYUQws=; b=Cks/sHNs16Yd1sja2zblVeB9loCQXRv1X0EJ7VZmDiUaPM/u8ftgh e5f/doDk7pJYBRTk5mlqYQhCLuN2hyVUUg6UIYVFmUijYycyx+azwTDnNyGKFjpx yvOtDBQG3ErWmuzb54S39R4bmvvVpnXfk+GippmHMCEGJUC3awyPDk= Received: (qmail 10693 invoked by alias); 28 Jul 2016 13:36:59 -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 9217 invoked by uid 89); 28 Jul 2016 13:36:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=*insn, D*googlemail.com, sk:smalles, 2996 X-HELO: mail-io0-f175.google.com Received: from mail-io0-f175.google.com (HELO mail-io0-f175.google.com) (209.85.223.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 28 Jul 2016 13:36:45 +0000 Received: by mail-io0-f175.google.com with SMTP id q83so99987398iod.1 for ; Thu, 28 Jul 2016 06:36:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=CKCjx4A/+mAjUJVq43MiK1POj1R+hvRew+5SWEf02Pw=; b=Be495NZMFvc3D+qSiq/8WEDbdQ4/kDz8bHA1Dvs4Zx0WOK+A0eWPV/fQm6EHQwW75w 4jMo1o8tBPc83BY4BSQngcVbVfm9KsHb5G2wixI9U5B9o9u6vBXCgutTA6UCtKtDoXL9 rZhwGx+ToW9e9iu7sBkJVnoQPdxGEg4UqVVMc14BfRPdoknN/DJsxiTzR85tTQkmc29u aMIidpSQiHDjfYyfA/ds7Cp+b7UaNAUlkiTIDvZNF1HuT0KsF8CgKq6oCOi4l10fFcwk XpAk84x1X3eBzv7wjpP54MVoJ3clWMMYLAyjeDdL1c/NEuC376LNC9gPTlYMaaijK57K ni1A== X-Gm-Message-State: AEkoousUGp21AywSfHDCUEx5hmiWz4Z39ccoAq34OxrV/ZKBA8YpJIBykh//g9dZTu5buf9nA1yFHDT5dDBQzJf1 X-Received: by 10.107.159.147 with SMTP id i141mr37018890ioe.29.1469713003106; Thu, 28 Jul 2016 06:36:43 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.48.197 with HTTP; Thu, 28 Jul 2016 06:36:42 -0700 (PDT) In-Reply-To: References: From: Prathamesh Kulkarni Date: Thu, 28 Jul 2016 19:06:42 +0530 Message-ID: Subject: Re: [RFC] [2/2] divmod transform: override expand_divmod_libfunc for ARM and add test-cases To: Ramana Radhakrishnan Cc: gcc Patches , Richard Biener , Ramana Radhakrishnan , Kugan Vivekanandarajah , Jim Wilson X-IsSubscribed: yes On 27 July 2016 at 18:56, Ramana Radhakrishnan wrote: > On Wed, May 25, 2016 at 1:49 PM, Prathamesh Kulkarni > wrote: >> On 23 May 2016 at 14:28, Prathamesh Kulkarni >> wrote: >>> Hi, >>> This patch overrides expand_divmod_libfunc for ARM port and adds test-cases. >>> I separated the SImode tests into separate file from DImode tests >>> because certain arm configs (cortex-15) have hardware div insn for >>> SImode but not for DImode, >>> and for that config we want SImode tests to be disabled but not DImode tests. >>> The patch therefore has two target-effective checks: divmod and divmod_simode. >>> Cross-tested on arm*-*-*. >>> Bootstrap+test on arm-linux-gnueabihf in progress. >>> Does this patch look OK ? >> Hi, >> This version adds couple of more test-cases and fixes typo in >> divmod-3-simode.c, divmod-4-simode.c >> >> Thanks, >> Prathamesh >>> >>> Thanks, >>> Prathamesh > > From the patch (snipped out unnecessary parts) > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 201aeb4..3bbf11b 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > > > > + gcc_assert (quotient); > + gcc_assert (remainder); > + > > There's a trailing white space here. > > + *quot_p = quotient; > + *rem_p = remainder; > +} > > > > +# For ARM configs defining __ARM_ARCH_EXT_IDIV__, disable > divmod_simode test-cases > > Very unhelpful comment ... > > For versions of the architecture where there exists a DIV instruction, > the divmod helper function is not used, disable the software divmod > optimization. > > > + > +proc check_effective_target_arm_divmod_simode { } { > + return [check_no_compiler_messages arm_divmod assembly { > + #ifdef __ARM_ARCH_EXT_IDIV__ > + #error has div insn > + #endif > + int i; > + }] > +} > + > +proc check_effective_target_divmod { } { > > Missing comment above. > > + #TODO: Add checks for all targets that have either hardware divmod insn > + # or define libfunc for divmod. > + if { [istarget arm*-*-*] > + || [istarget x86_64-*-*] } { > + return 1 > + } > + return 0 > +} > > > > > > The new helper functions need documentation in doc/sourcebuild.texi > > Please repost with the doc changes, otherwise this is OK from my side. Hi Ramana, Thanks for the review, I have updated the patch with your suggestions. Cross-tested on arm*-*-*. I came across following issue while bootstrapping on armv8l-unknown-linux-gnueabihf: All the divmod-*-simode.c tests which have /* { dg-require-effective-target divmod_simode } */ appear UNSUPPORTED. That's because this config appears to define __ARM_ARCH_EXT_IDIV__ however idiv appears not to be present. For instance __aeabi_div is called to perform division for the following test-case: int f(int x, int y) { int r = x / y; return r; } Compiling with -O2: f: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, lr} bl __aeabi_idiv pop {r4, pc} I assumed if __ARM_ARCH_EXT_IDIV was defined, then there should have been idiv instead of call to __aeabi_div or am I missing something ? Um I had configured with --with-tune=cortex-a9. Is that incorrect for armv8l-unknown-linux-gnueabihf ? xgcc -v: Using built-in specs. COLLECT_GCC=armhf-bootstrap-build/gcc/xgcc Target: armv8l-unknown-linux-gnueabihf Configured with: ../gcc/configure --enable-languages=c,c++,fortran --with-arch=armv8-a --with-fpu=neon-fp-armv8 --with-float=hard --with-mode=thumb --enable-multiarch --with-tune=cortex-a9 --disable-multilib Thread model: posix gcc version 7.0.0 20160727 (experimental) (GCC) Thanks, Prathamesh > > Thanks, > Ramana diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 195de48..f449e46 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -61,6 +61,7 @@ #include "builtins.h" #include "tm-constrs.h" #include "rtl-iter.h" +#include "optabs-libfuncs.h" /* This file should be included last. */ #include "target-def.h" @@ -299,6 +300,7 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*); static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); +static void arm_expand_divmod_libfunc (bool, machine_mode, rtx, rtx, rtx *, rtx *); /* Table of machine attributes. */ @@ -729,6 +731,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_SCHED_FUSION_PRIORITY #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority +#undef TARGET_EXPAND_DIVMOD_LIBFUNC +#define TARGET_EXPAND_DIVMOD_LIBFUNC arm_expand_divmod_libfunc + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -30486,6 +30491,38 @@ arm_sched_fusion_priority (rtx_insn *insn, int max_pri, return; } +/* Expand call to __aeabi_[mode]divmod (op0, op1). */ + +static void +arm_expand_divmod_libfunc (bool unsignedp, machine_mode mode, + rtx op0, rtx op1, + rtx *quot_p, rtx *rem_p) +{ + if (mode == SImode) + gcc_assert (!TARGET_IDIV); + + optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab; + rtx libfunc = optab_libfunc (tab, mode); + gcc_assert (libfunc); + + machine_mode libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode), + MODE_INT); + + rtx libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, + libval_mode, 2, + op0, GET_MODE (op0), + op1, GET_MODE (op1)); + + rtx quotient = simplify_gen_subreg (mode, libval, libval_mode, 0); + rtx remainder = simplify_gen_subreg (mode, libval, libval_mode, + GET_MODE_SIZE (mode)); + + gcc_assert (quotient); + gcc_assert (remainder); + + *quot_p = quotient; + *rem_p = remainder; +} /* Construct and return a PARALLEL RTX vector with elements numbering the lanes of either the high (HIGH == TRUE) or low (HIGH == FALSE) half of diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 24b65da..b8ec25d 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1622,6 +1622,10 @@ and @code{MOVT} instructions available. ARM target generates Thumb-1 code for @code{-mthumb} with @code{CBZ} and @code{CBNZ} instructions available. +@item arm_divmod_simode +ARM target for which divmod transform is disabled, if it supports hardware +div instruction. + @end table @subsubsection AArch64-specific attributes @@ -1795,6 +1799,13 @@ Target requires a command line argument to enable a SIMD instruction set. @item pie_copyreloc The x86-64 target linker supports PIE with copy reloc. + +@item divmod +Target supporting hardware divmod insn or divmod libcall. + +@item divmod_simode +Target supporting hardware divmod insn or divmod libcall for SImode. + @end table @subsubsection Environment attributes diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 770268f..3305835 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -7609,3 +7609,42 @@ proc check_effective_target_offload_hsa { } { int main () {return 0;} } "-foffload=hsa" ] } + +#For versions of the architecture where there exists a DIV instruction, +#the divmod helper function is not used, disable the software divmod +#optimization. + +proc check_effective_target_arm_divmod_simode { } { + return [check_no_compiler_messages arm_divmod assembly { + #ifdef __ARM_ARCH_EXT_IDIV__ + #error has div insn + #endif + int i; + }] +} + +# Return 1 if target supports divmod hardware insn or divmod libcall. + +proc check_effective_target_divmod { } { + #TODO: Add checks for all targets that have either hardware divmod insn + # or define libfunc for divmod. + if { [istarget arm*-*-*] + || [istarget x86_64-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if target supports divmod for simode. The reason for +# separating this from check_effective_target_divmod is that +# some versions of ARM architecture define div instruction +# only for simode, and for these archs, we do not want to enable +# divmod transform for simode. + +proc check_effective_target_divmod_simode { } { + if { [istarget arm*-*-*] } { + return [check_effective_target_arm_divmod_simode] + } + + return [check_effective_target_divmod] +}