summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2014-10-13 10:16:06 +0000
committerBradley Smith <bradley.smith@arm.com>2014-10-13 10:16:06 +0000
commit9ff64332a00baafa2c2de901ea4948369b625177 (patch)
tree817b44e9b2ef63b1ec1ee92d6270bad46bf42417
parentf2a801d8ac8c83f21ea50e1b23fb3f3496ab9ff2 (diff)
downloadbcm5719-llvm-9ff64332a00baafa2c2de901ea4948369b625177.tar.gz
bcm5719-llvm-9ff64332a00baafa2c2de901ea4948369b625177.zip
[AArch64] Add workaround for Cortex-A53 erratum (835769)
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. This patch implements clang options to enable this workaround in the backend. The work-around code generation is not enabled by default. llvm-svn: 219604
-rw-r--r--clang/include/clang/Driver/Options.td7
-rw-r--r--clang/lib/Driver/Tools.cpp9
-rw-r--r--clang/test/Driver/aarch64-fix-cortex-a53-835769-cg.c19
-rw-r--r--clang/test/Driver/aarch64-fix-cortex-a53-835769.c9
4 files changed, 44 insertions, 0 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ecccf2929bf..df0b7a4b8d4 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1169,6 +1169,13 @@ def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
+def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
+ Group<m_aarch64_Features_Group>,
+ HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
+def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
+ Group<m_aarch64_Features_Group>,
+ HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
+
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
def mpower8_vector : Flag<["-"], "mpower8-vector">,
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 0bbc964838d..c0607284e3c 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -913,6 +913,15 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
CmdArgs.push_back("-aarch64-no-strict-align");
}
+ if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
+ options::OPT_mno_fix_cortex_a53_835769)) {
+ CmdArgs.push_back("-backend-option");
+ if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
+ CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
+ else
+ CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
+ }
+
// Setting -mno-global-merge disables the codegen global merge pass. Setting
// -mglobal-merge has no effect as the pass is enabled by default.
if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
diff --git a/clang/test/Driver/aarch64-fix-cortex-a53-835769-cg.c b/clang/test/Driver/aarch64-fix-cortex-a53-835769-cg.c
new file mode 100644
index 00000000000..efe60c9aaf1
--- /dev/null
+++ b/clang/test/Driver/aarch64-fix-cortex-a53-835769-cg.c
@@ -0,0 +1,19 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang -O3 -target aarch64-linux-eabi %s -S -o- \
+// RUN: | FileCheck --check-prefix=CHECK-NO --check-prefix=CHECK %s
+// RUN: %clang -O3 -target aarch64-linux-eabi -mfix-cortex-a53-835769 %s -S -o- 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s
+// RUN: %clang -O3 -target aarch64-linux-eabi -mno-fix-cortex-a53-835769 %s -S -o- 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO --check-prefix=CHECK %s
+
+#include <stdint.h>
+
+int64_t f_load_madd_64(int64_t a, int64_t b, int64_t *c) {
+ int64_t result = a+b*(*c);
+ return result;
+}
+
+// CHECK: ldr
+// CHECK-YES-NEXT: nop
+// CHECK-NO-NEXT-NOT: nop
+// CHECK-NEXT: madd
diff --git a/clang/test/Driver/aarch64-fix-cortex-a53-835769.c b/clang/test/Driver/aarch64-fix-cortex-a53-835769.c
new file mode 100644
index 00000000000..379a3238acb
--- /dev/null
+++ b/clang/test/Driver/aarch64-fix-cortex-a53-835769.c
@@ -0,0 +1,9 @@
+// RUN: %clang -target aarch64-linux-eabi %s -### 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-DEF %s
+// RUN: %clang -target aarch64-linux-eabi -mfix-cortex-a53-835769 %s -### 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-YES %s
+// RUN: %clang -target aarch64-linux-eabi -mno-fix-cortex-a53-835769 %s -### 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-DEF-NOT: "-backend-option" "-aarch64-fix-cortex-a53-835769"
+// CHECK-YES: "-backend-option" "-aarch64-fix-cortex-a53-835769=1"
+// CHECK-NO: "-backend-option" "-aarch64-fix-cortex-a53-835769=0"
OpenPOWER on IntegriCloud