diff mbox

[AArch64] Restore recog state after finding pre-madd instruction

Message ID 5450BB85.8010903@arm.com
State New
Headers show

Commit Message

Kyrylo Tkachov Oct. 29, 2014, 10:03 a.m. UTC
Hi all,

This patch fixes an issue with the final_prescan workaround for the 
Cortex-A53 erratum 835769
where calling recog_memoized could modify the recog data for the 
multiply-accumulate instruction
when looking at a preceding asm block. This can lead to wrong code 
generation.

The solution is to call extract_constrain_insn_cached to restore the 
recog data before exiting
aarch64_madd_needs_nop.

Bootstrapped and tested on aarch64-none-linux-gnu.
A compile testcase is added demonstrating the issue.

Ok for trunk?

Thanks,
Kyrill

2014-10-28  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config/aarch64/aarch64.c (aarch64_madd_needs_nop): Restore
     recog state after aarch64_prev_real_insn call.

2014-10-28  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * gcc.target/aarch64/madd_after_asm_1.c: New test.

Comments

Marcus Shawcroft Oct. 29, 2014, 7:54 p.m. UTC | #1
On 29 October 2014 10:03, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
> Hi all,
>
> This patch fixes an issue with the final_prescan workaround for the
> Cortex-A53 erratum 835769
> where calling recog_memoized could modify the recog data for the
> multiply-accumulate instruction
> when looking at a preceding asm block. This can lead to wrong code
> generation.
>
> The solution is to call extract_constrain_insn_cached to restore the recog
> data before exiting
> aarch64_madd_needs_nop.
>
> Bootstrapped and tested on aarch64-none-linux-gnu.
> A compile testcase is added demonstrating the issue.
>
> Ok for trunk?

Ok /Marcus
diff mbox

Patch

commit e11cd63678d7c334d2f9f124e197695ea470025c
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Mon Oct 27 13:29:25 2014 +0000

    [AArch64] Restore recog state after finding pre-madd instruction

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index cbbc482..002cb44 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7769,6 +7769,10 @@  aarch64_madd_needs_nop (rtx_insn* insn)
     return false;
 
   prev = aarch64_prev_real_insn (insn);
+  /* aarch64_prev_real_insn can call recog_memoized on insns other than INSN.
+     Restore recog state to INSN to avoid state corruption.  */
+  extract_constrain_insn_cached (insn);
+
   if (!prev || !has_memory_op (prev))
     return false;
 
diff --git a/gcc/testsuite/gcc.target/aarch64/madd_after_asm_1.c b/gcc/testsuite/gcc.target/aarch64/madd_after_asm_1.c
new file mode 100644
index 0000000..523941d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/madd_after_asm_1.c
@@ -0,0 +1,14 @@ 
+/* { dg-do assemble } */
+/* { dg-options "-O2 -mfix-cortex-a53-835769" } */
+
+int
+test (int a, double b, int c, int d, int e)
+{
+  double result;
+  __asm__ __volatile ("// %0, %1"
+                      : "=w" (result)
+                      : "0" (b)
+                      :    /* No clobbers */
+                      );
+  return c * d + e;
+}