[PATCH][AArch64] Implement workaround for ARM Cortex-A53 erratum 835769
Andrew Pinski
pinskia@gmail.com
Fri Oct 10 17:20:00 GMT 2014
On Fri, Oct 10, 2014 at 3:53 AM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
> Hi all,
>
>
> Some early revisions of the Cortex-A53 have an erratum (835769) whereby
> it is possible for a 64-bit multiply-accumulate instruction in
> AArch64 state to generate an incorrect result. The details are quite
> complex and hard to determine statically, since branches in the code
> may exist in some circumstances, but all cases end with a memory
> (load, store, or prefetch) instruction followed immediately by the
> multiply-accumulate operation.
>
> The safest work-around for this issue is to make the compiler avoid
> emitting multiply-accumulate instructions immediately after memory
> instructions and the simplest way to do this is to insert a NOP. A
> linker patching technique can also be used, by moving potentially
> affected multiply-accumulate instruction into a patch region and
> replacing the original instruction with a branch to the patch.
>
> This patch achieves the compiler part by using the final prescan pass.
> The insn length attribute is updated accordingly using ADJUST_INSN_LENGTH
> so that conditional branches work properly.
>
> The fix is disabled by default and can be turned on by the
> -mfix-cortex-a53-835769 compiler option.
>
> I'm attaching a trunk and a 4.9 version of the patch.
> The 4.9 version is different only in that rtx_insn* is replaced by rtx.
>
> Tested on aarch64-none-linux-gnu (and bootstrap with the option) and
> built various large benchmarks with it.
>
> Ok?
A few comments:
This:
+static int
+is_mem_p (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return MEM_P (*x);
+}
+
+static bool
+is_memory_op (rtx_insn *mem_insn)
+{
+ rtx pattern = PATTERN (mem_insn);
+ return for_each_rtx (&pattern, is_mem_p, NULL);
+}
Should be using the new FOR_EACH_SUBRTX instead. This should simplify
the code something like:
static bool
is_memory_op (rtx_insn *mem_insn)
{
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, PATTERN (mem_insn), ALL)
if (MEM_P (*iter))
return true;
return false;
}
Also this should be a has_ function rather than a is_ function.
I think you should have ADJUST_INSN_LENGTH as a function call rather
than inline it there or at least wrap it with do { } while (0); which
I think is documented part of the coding style.
Also you added no comment before each function. The coding style says
each function needs a comment describing what the function does.
Thanks,
Andrew Pinski
>
> Thanks,
> Kyrill
>
> 2014-10-10 Kyrylo Tkachov<kyrylo.tkachov@arm.com>
> Ramana Radhakrishnan<ramana.radhakrishnan@arm.com>
>
> * config/aarch64/aarch64.h (FINAL_PRESCAN_INSN): Define.
> (ADJUST_INSN_LENGTH): Define.
> * config/aarch64/aarch64.opt (mfix-cortex-a53-835769): New option.
> * config/aarch64/aarch64.c (is_mem_p): New function.
> (is_memory_op): Likewise.
> (aarch64_prev_real_insn): Likewise.
> (is_madd_op): Likewise.
> (dep_between_memop_and_next): Likewise.
> (aarch64_madd_needs_nop): Likewise.
> (aarch64_final_prescan_insn): Likewise.
> * doc/invoke.texi (AArch64 Options): Document -mfix-cortex-a53-835769
> and -mno-fix-cortex-a53-835769 options.
More information about the Gcc-patches
mailing list