diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -568,4 +568,15 @@ if (Args.hasArg(options::OPT_mno_neg_immediates)) Features.push_back("+no-neg-immediates"); + + if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769, + options::OPT_mno_fix_cortex_a53_835769)) { + if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769)) + Features.push_back("+fix-cortex-a53-835769"); + else + Features.push_back("-fix-cortex-a53-835769"); + } else if (Triple.isAndroid()) { + // Enabled A53 errata (835769) workaround by default on android + Features.push_back("+fix-cortex-a53-835769"); + } } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1806,19 +1806,6 @@ RenderAArch64ABI(Triple, Args, CmdArgs); - if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769, - options::OPT_mno_fix_cortex_a53_835769)) { - CmdArgs.push_back("-mllvm"); - 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"); - } else if (Triple.isAndroid()) { - // Enabled A53 errata (835769) workaround by default on android - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1"); - } - // Forward the -mglobal-merge option for explicit control over the pass. if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, options::OPT_mno_global_merge)) { diff --git a/clang/test/Driver/aarch64-fix-cortex-a53-835769.c b/clang/test/Driver/aarch64-fix-cortex-a53-835769.c --- a/clang/test/Driver/aarch64-fix-cortex-a53-835769.c +++ b/clang/test/Driver/aarch64-fix-cortex-a53-835769.c @@ -8,6 +8,6 @@ // RUN: %clang -target aarch64-android-eabi %s -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-YES %s -// CHECK-DEF-NOT: "-mllvm" "-aarch64-fix-cortex-a53-835769" -// CHECK-YES: "-mllvm" "-aarch64-fix-cortex-a53-835769=1" -// CHECK-NO: "-mllvm" "-aarch64-fix-cortex-a53-835769=0" +// CHECK-DEF-NOT: "{[+-]}fix-cortex-a53-835769" +// CHECK-YES: "+fix-cortex-a53-835769" +// CHECK-NO: "-fix-cortex-a53-835769" diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -455,6 +455,9 @@ def FeatureEL3 : SubtargetFeature<"el3", "HasEL3", "true", "Enable Exception Level 3">; +def FeatureFixCortexA53_835769 : SubtargetFeature<"fix-cortex-a53-835769", + "FixCortexA53_835769", "true", "Mitigate Cortex-A53 Erratum 835769">; + //===----------------------------------------------------------------------===// // Architectures. // diff --git a/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp b/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp --- a/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp +++ b/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "AArch64.h" +#include "AArch64Subtarget.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -116,8 +117,13 @@ bool AArch64A53Fix835769::runOnMachineFunction(MachineFunction &F) { LLVM_DEBUG(dbgs() << "***** AArch64A53Fix835769 *****\n"); + auto &STI = F.getSubtarget(); + // Fix not requested, skip pass. + if (!STI.fixCortexA53_835769()) + return false; + bool Changed = false; - TII = F.getSubtarget().getInstrInfo(); + TII = STI.getInstrInfo(); for (auto &MBB : F) { Changed |= runOnBasicBlock(MBB); diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -116,6 +116,8 @@ bool HasFP16FML = false; bool HasSPE = false; + bool FixCortexA53_835769 = false; + // ARMv8.1 extensions bool HasVH = false; bool HasPAN = false; @@ -571,6 +573,8 @@ bool hasEL2VMSA() const { return HasEL2VMSA; } bool hasEL3() const { return HasEL3; } + bool fixCortexA53_835769() const { return FixCortexA53_835769; } + bool addrSinkUsingGEPs() const override { // Keeping GEPs inbounds is important for exploiting AArch64 // addressing-modes in ILP32 mode. diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -116,11 +116,6 @@ cl::desc("Enable the condition optimizer pass"), cl::init(true), cl::Hidden); -static cl::opt -EnableA53Fix835769("aarch64-fix-cortex-a53-835769", cl::Hidden, - cl::desc("Work around Cortex-A53 erratum 835769"), - cl::init(false)); - static cl::opt EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden, cl::desc("Enable optimizations on complex GEPs"), @@ -764,8 +759,7 @@ if (TM->getOptLevel() >= CodeGenOpt::Aggressive && EnableLoadStoreOpt) addPass(createAArch64LoadStoreOptimizationPass()); - if (EnableA53Fix835769) - addPass(createAArch64A53Fix835769()); + addPass(createAArch64A53Fix835769()); if (EnableBranchTargets) addPass(createAArch64BranchTargetsPass()); diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll --- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -60,6 +60,7 @@ ; CHECK-NEXT: Insert fentry calls ; CHECK-NEXT: Insert XRay ops ; CHECK-NEXT: Implement the 'patchable-function' attribute +; CHECK-NEXT: Workaround A53 erratum 835769 pass ; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Branch relaxation pass ; CHECK-NEXT: Contiguously Lay Out Funclets diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -195,6 +195,7 @@ ; CHECK-NEXT: Insert XRay ops ; CHECK-NEXT: Implement the 'patchable-function' attribute ; CHECK-NEXT: AArch64 load / store optimization pass +; CHECK-NEXT: Workaround A53 erratum 835769 pass ; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Branch relaxation pass ; CHECK-NEXT: AArch64 Compress Jump Tables diff --git a/llvm/test/CodeGen/AArch64/aarch64-fix-cortex-a53-835769.ll b/llvm/test/CodeGen/AArch64/aarch64-fix-cortex-a53-835769.ll --- a/llvm/test/CodeGen/AArch64/aarch64-fix-cortex-a53-835769.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-fix-cortex-a53-835769.ll @@ -3,9 +3,9 @@ ; therefore, the tests are a bit fragile/reliant on instruction scheduling. The ; test cases have been minimized as much as possible, but still most of the test ; cases could break if instruction scheduling heuristics for cortex-a53 change -; RUN: llc < %s -mcpu=cortex-a53 -aarch64-fix-cortex-a53-835769=1 -frame-pointer=non-leaf -stats 2>&1 \ +; RUN: llc < %s -mcpu=cortex-a53 -mattr=+fix-cortex-a53-835769 -frame-pointer=non-leaf -stats 2>&1 \ ; RUN: | FileCheck %s -; RUN: llc < %s -mcpu=cortex-a53 -aarch64-fix-cortex-a53-835769=0 -frame-pointer=non-leaf -stats 2>&1 \ +; RUN: llc < %s -mcpu=cortex-a53 -mattr=-fix-cortex-a53-835769 -frame-pointer=non-leaf -stats 2>&1 \ ; RUN: | FileCheck %s --check-prefix CHECK-NOWORKAROUND ; The following run lines are just to verify whether or not this pass runs by ; default for given CPUs. Given the fragility of the tests, this is only run on