On Fri, 1 May 2020 at 12:57, Kyrylo Tkachov <kyrylo.tkac...@arm.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Christophe Lyon <christophe.l...@linaro.org>
> > Sent: 30 April 2020 09:51
> > To: Kyrylo Tkachov <kyrylo.tkac...@arm.com>
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: Re: arm: Fix vfp_operand_register for VFP HI regs
> >
> > On Wed, 29 Apr 2020 at 18:40, Kyrylo Tkachov <kyrylo.tkac...@arm.com>
> > wrote:
> > >
> > > Hi Christophe,
> > >
> > > > -----Original Message-----
> > > > From: Gcc-patches <gcc-patches-boun...@gcc.gnu.org> On Behalf Of
> > > > Christophe Lyon via Gcc-patches
> > > > Sent: 29 April 2020 16:53
> > > > To: gcc Patches <gcc-patches@gcc.gnu.org>
> > > > Subject: arm: Fix vfp_operand_register for VFP HI regs
> > > >
> > > > Hi,
> > > >
> > > > While looking at PR target/94743 I noticed an ICE when I tried to save
> > > > all the FP registers: this was because all HI registers wouldn't match
> > > > vfp_register_operand.
> > >
> > > Hmm, I see that arm_regno_class indeed never returns VFP_REGS and
> > would return VFP_HI_REGS here.
> > > So the patch looks correct to me.
> > > Do you have a testcase for the ICE to add to the testsuite?
> > >
> >
> > No C source code: I found that while extending the list of registers
> > pushed in the prologue of an IRQ handler, more-or-less modifying
> > arm_save_coproc_regs so that more registers are handled by
> > vfp_emit_fstmd.
> > The problem occurs when trying to push d16-d31.
>
> I'd be comfortable taking this now for trunk (GCC 11) so it has time to bake.
> Once you're ready to post the IRQ handler work we can see about backporting 
> this fix it to the branch, if we deem it necessary.
> Thanks,
> Kyrill
>

Hi,

I've just sent several patches for PR 94743:
https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545747.html
is v2 of my previous patch: it only emits a warning, and might be
sufficient to close the PR, if we decide that
we don't want to save the FP registers without explicit user request...

Then,
[1] https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545748.html
[2] https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545749.html
are refactorization patches that would make implementing the patch
attached here easier.

If you apply the attached on top of [1] and [2], you'll notice an ICE
fixed by the original patch of this thread.

So hopefully applying [1], [2] and the attached should help convince you that
the vfp_operand_register is OK.

Thanks

> >
> >
> > > Thanks,
> > > Kyrill
> > >
> > > >
> > > > Regression-tested and bootstrapped OK.
> > > >
> > > > 2020-04-29  Christophe Lyon  <christophe.l...@linaro.org>
> > > >
> > > >         gcc/
> > > >         * config/arm/predicates.md (vfp_register_operand): Use
> > VFP_HI_REGS
> > > >         instead of VFP_REGS.
> > > >
> > > > OK?
> > > >
> > > > Thanks,
> > > >
> > > > Christophe
From 834868c176adbec0f84b71289c2fbae7500b3fce Mon Sep 17 00:00:00 2001
From: Christophe Lyon <christophe.l...@linaro.org>
Date: Thu, 14 May 2020 11:14:59 +0000
Subject: [PATCH] arm: Save FP regs in interrupt handlers [PR target/94743]

2020-05-xx  Christophe Lyon  <christophe.l...@linaro.org>

	gcc/
	* config/arm/arm.c (reg_needs_saving_p): Remove limit to core
	registers.

	gcc/testsuite/
	* gcc.target/arm/pr94743-4.c: New test.
	* gcc.target/arm/pr94743-5.c: New test.
---
 gcc/config/arm/arm.c                     |  4 ++--
 gcc/testsuite/gcc.target/arm/pr94743-4.c | 31 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/arm/pr94743-5.c | 35 ++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pr94743-4.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pr94743-5.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0107f50..38413fb 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4200,8 +4200,8 @@ static bool reg_needs_saving_p (unsigned reg)
 
   if (IS_INTERRUPT (func_type))
     if (df_regs_ever_live_p (reg)
-	/* Save call-clobbered core registers.  */
-	|| (! crtl->is_leaf && call_used_or_fixed_reg_p (reg) && reg < FIRST_VFP_REGNUM))
+	/* Save call-clobbered registers.  */
+	|| (! crtl->is_leaf && call_used_or_fixed_reg_p (reg)))
       return true;
     else
       return false;
diff --git a/gcc/testsuite/gcc.target/arm/pr94743-4.c b/gcc/testsuite/gcc.target/arm/pr94743-4.c
new file mode 100644
index 0000000..378981a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr94743-4.c
@@ -0,0 +1,31 @@
+/* PR target/94743 */
+/* { dg-do compile } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } {"-mfloat-abi=hard" } } */
+/* { dg-options "-mfloat-abi=hard" } */
+
+/* Check that we emit a warning when compiling an IRQ handler without
+   -mgeneral-regs-only.  */
+/* Also check that we save and restore the VFP registers clobbered
+   locally.  */
+typedef struct {
+  double fpdata[32];
+} dummy_t;
+
+dummy_t global_d;
+dummy_t global_d1;
+
+/* This function may clobber VFP registers, but it is a leaf function:
+   we can analyze which registers to save.  */
+__attribute__ ((interrupt("IRQ"))) void IRQ_HDLR_Test(void)
+{ /* { dg-warning { FP registers might be clobbered despite 'interrupt' attribute: compile with -mgeneral-regs-only} "" { target *-*-* } . } */
+  global_d.fpdata[3] += global_d.fpdata[3] * global_d1.fpdata[3];
+}
+/* { dg-final { scan-assembler-times "vpush.64\t{d\\d+, d\\d+, d\\d+}" 1 } } */
+/* { dg-final { scan-assembler-times "vldm\tsp!, {d\\d+-d\\d+}" 1 } } */
+
+/* This function does not need to clobber VFP registers.  */
+/* Do we want to emit a (useless?) warning?  */
+__attribute__ ((interrupt("IRQ"))) void IRQ_HDLR_Test2(void)
+{ /* { dg-warning { FP registers might be clobbered despite 'interrupt' attribute: compile with -mgeneral-regs-only} "" { target *-*-* } . } */
+  global_d.fpdata[3] = 1.0;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr94743-5.c b/gcc/testsuite/gcc.target/arm/pr94743-5.c
new file mode 100644
index 0000000..55fb1dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr94743-5.c
@@ -0,0 +1,35 @@
+/* PR target/94743 */
+/* { dg-do compile } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } {"-mfloat-abi=hard" } } */
+/* Require Neon so that we push d16-d31.  */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-add-options arm_neon } */
+/* { dg-additional-options "-mfloat-abi=hard" } */
+
+/* Check that we emit a warning when compiling an IRQ handler without
+   -mgeneral-regs-only.  */
+/* Also check that we save and restore the call-clobbered VFP registers.  */
+typedef struct {
+  double fpdata[32];
+} dummy_t;
+
+dummy_t global_d;
+dummy_t global_d1;
+
+/* This function may clobber VFP registers.  */
+__attribute__ ((interrupt("IRQ"))) void IRQ_HDLR_Test(void)
+{ /* { dg-warning { FP registers might be clobbered despite 'interrupt' attribute: compile with -mgeneral-regs-only} "" { target *-*-* } . } */
+  /* Force implicit call to memcpy.  */
+  global_d = global_d1;
+  global_d.fpdata[3] += global_d.fpdata[3] * global_d1.fpdata[3];
+}
+/* { dg-final { scan-assembler-times "vpush.64\t{d0, d1, d2, d3, d4, d5, d6, d7}" 1 } } */
+/* { dg-final { scan-assembler-times "vpush.64\t{d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}" 1 } } */
+/* { dg-final { scan-assembler-times "vldm\tsp!, {d16-d31}" 1 } } */
+/* { dg-final { scan-assembler-times "vldm\tsp!, {d0-d7}" 1 } } */
+
+/* This function does not need to clobber VFP registers.  */
+__attribute__ ((interrupt("IRQ"))) void IRQ_HDLR_Test2(void)
+{ /* { dg-warning { FP registers might be clobbered despite 'interrupt' attribute: compile with -mgeneral-regs-only} "" { target *-*-* } . } */
+  global_d.fpdata[3] = 1.0;
+}
-- 
2.7.4

Reply via email to