From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20923 invoked by alias); 14 Jan 2015 10:20:59 -0000 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 Received: (qmail 20897 invoked by uid 89); 14 Jan 2015 10:20:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Jan 2015 10:20:56 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by service87.mimecast.com; Wed, 14 Jan 2015 10:20:53 +0000 Received: from SHAWIN202 ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 14 Jan 2015 10:20:51 +0000 From: "Thomas Preud'homme" To: Subject: [PATCH, ARM] Fix PR64453: live high register not saved in function prolog with -Os Date: Wed, 14 Jan 2015 10:38:00 -0000 Message-ID: <000001d02fe3$c12d7d90$438878b0$@arm.com> MIME-Version: 1.0 X-MC-Unique: 115011410205304801 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-01/txt/msg01001.txt.bz2 When compiling for size, live high registers are not saved in function prol= og in ARM backend in Thumb mode. The problem comes from arm_conditional_reg= ister_usage setting call_used_regs for all high register to avoid them bein= g allocated. However, this cause prolog to not save these register even if = they are used. This patch marks high registers as really needing to be save= d in prolog if live, no matter what is the content of call_used_regs. ChangeLog entries are as follows: gcc/ChangeLog 2015-01-12 Thomas Preud'homme thomas.preudhomme@arm.com PR target/64453 * config/arm/arm.c (callee_saved_reg_p): Define. (arm_compute_save_reg0_reg12_mask): Use callee_saved_reg_p to check if register is callee saved instead of !call_used_regs[reg]. (thumb1_compute_save_reg_mask): Likewise. gcc/testsuite/ChangeLog 2014-12-31 Thomas Preud'homme thomas.preudhomme@arm.com * gcc.target/arm/pr64453.c: New. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 0ec526b..fcc14c2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -18989,6 +18989,14 @@ output_ascii_pseudo_op (FILE *stream, const unsign= ed char *p, int len) fputs ("\"\n", stream); } =20 +/* Whether a register is callee saved or not. This is necessary because h= igh + registers are marked as caller saved when optimizing for size on Thumb-1 + targets despite being callee saved in order to avoid using them. */ +#define callee_saved_reg_p(reg) \ + (!call_used_regs[reg] \ + || (TARGET_THUMB1 && optimize_size \ + && reg >=3D FIRST_HI_REGNUM && reg <=3D LAST_HI_REGNUM)) + /* Compute the register save mask for registers 0 through 12 inclusive. This code is used by arm_compute_save_reg_mask. */ =20 @@ -19049,7 +19057,7 @@ arm_compute_save_reg0_reg12_mask (void) /* In the normal case we only need to save those registers which are call saved and which are used by this function. */ for (reg =3D 0; reg <=3D 11; reg++) - if (df_regs_ever_live_p (reg) && ! call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg)) save_reg_mask |=3D (1 << reg); =20 /* Handle the frame pointer as a special case. */ @@ -19212,7 +19220,7 @@ thumb1_compute_save_reg_mask (void) =20 mask =3D 0; for (reg =3D 0; reg < 12; reg ++) - if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg)) mask |=3D 1 << reg; =20 if (flag_pic @@ -19245,7 +19253,7 @@ thumb1_compute_save_reg_mask (void) if (reg * UNITS_PER_WORD <=3D (unsigned) arm_size_return_regs ()) reg =3D LAST_LO_REGNUM; =20 - if (! call_used_regs[reg]) + if (callee_saved_reg_p (reg)) mask |=3D 1 << reg; } =20 @@ -27185,8 +27193,7 @@ arm_conditional_register_usage (void) /* When optimizing for size on Thumb-1, it's better not to use the HI regs, because of the overhead of stacking them. */ - for (regno =3D FIRST_HI_REGNUM; - regno <=3D LAST_HI_REGNUM; ++regno) + for (regno =3D FIRST_HI_REGNUM; regno <=3D LAST_HI_REGNUM; ++regno) fixed_regs[regno] =3D call_used_regs[regno] =3D 1; } =20 diff --git a/gcc/testsuite/gcc.target/arm/pr64453.c b/gcc/testsuite/gcc.tar= get/arm/pr64453.c new file mode 100644 index 0000000..17155af --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr64453.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-mthumb -Os " } */ +/* { dg-require-effective-target arm_thumb1_ok } */ + +void save_regs () { + __asm volatile ("" ::: "r8"); +} + +/* { dg-final { scan-assembler "\tmov\tr., r8" } } */ Tested by compiling an arm-none-eabi GCC cross-compiler and running the tes= tsuite on QEMU emulating Cortex-M0 without any regression. Is this ok for trunk? Best regards, Thomas