Index: llvm/lib/Target/AArch64/AArch64.h =================================================================== --- llvm/lib/Target/AArch64/AArch64.h +++ llvm/lib/Target/AArch64/AArch64.h @@ -58,6 +58,7 @@ FunctionPass *createAArch64PreLegalizeCombiner(bool IsOptNone); FunctionPass *createAArch64StackTaggingPass(bool MergeInit); FunctionPass *createAArch64StackTaggingPreRAPass(); +FunctionPass *createAArch64ClobberLRPass(); void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); @@ -82,6 +83,7 @@ void initializeLDTLSCleanupPass(PassRegistry&); void initializeAArch64StackTaggingPass(PassRegistry&); void initializeAArch64StackTaggingPreRAPass(PassRegistry&); +void initializeAArch64ClobberLRPass(PassRegistry &); } // end namespace llvm #endif Index: llvm/lib/Target/AArch64/AArch64ClobberLRPass.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/AArch64/AArch64ClobberLRPass.cpp @@ -0,0 +1,71 @@ +//===- AArch64ClobberLRPass.cpp - Clobber LR on call intrinsics -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains a pass that sets LR as implicit-def for statepoints, +// patchpoints and stackmap instrinsics. This is needed as these instructions +// are defined globally with no knowledge of AArch64-specific requirements. +// As these intrinsics are lowered to calls after the register allocator runs, +// it is necessary to specify that they clobber the link register beforehand. +// +//===----------------------------------------------------------------------===// + +#include "AArch64.h" +#include "AArch64RegisterInfo.h" +#include "AArch64Subtarget.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Pass.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "aarch64-dead-defs" + +#define AARCH64_CLOBBER_LR_NAME "AArch64 statepoint LR clobbering pass" + +namespace { +struct AArch64ClobberLR : public MachineFunctionPass { +public: + static char ID; + + AArch64ClobberLR() : MachineFunctionPass(ID) { + initializeAArch64ClobberLRPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + StringRef getPassName() const override { return AARCH64_CLOBBER_LR_NAME; } +}; +} // namespace + +char AArch64ClobberLR::ID = 0; + +INITIALIZE_PASS(AArch64ClobberLR, "aarch64-clobber-lr", AARCH64_CLOBBER_LR_NAME, + false, false) + +bool AArch64ClobberLR::runOnMachineFunction(MachineFunction &MF) { + auto TRI = MF.getSubtarget().getRegisterInfo(); + bool Modified = false; + for (MachineBasicBlock &MBB : MF) { + for (MachineInstr &MI : MBB) { + if (MI.getOpcode() == TargetOpcode::STACKMAP || + MI.getOpcode() == TargetOpcode::PATCHPOINT || + MI.getOpcode() == TargetOpcode::STATEPOINT) { + MI.addRegisterDefined(AArch64::LR, TRI); + Modified = true; + } + } + } + return Modified; +} + +FunctionPass *llvm::createAArch64ClobberLRPass() { + return new AArch64ClobberLR(); +} \ No newline at end of file Index: llvm/lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -185,6 +185,7 @@ initializeAArch64SpeculationHardeningPass(*PR); initializeAArch64StackTaggingPass(*PR); initializeAArch64StackTaggingPreRAPass(*PR); + initializeAArch64ClobberLRPass(*PR); } //===----------------------------------------------------------------------===// @@ -582,6 +583,8 @@ // be register coalescer friendly. addPass(&PeepholeOptimizerID); } + + addPass(createAArch64ClobberLRPass()); } void AArch64PassConfig::addPostRegAlloc() { Index: llvm/lib/Target/AArch64/CMakeLists.txt =================================================================== --- llvm/lib/Target/AArch64/CMakeLists.txt +++ llvm/lib/Target/AArch64/CMakeLists.txt @@ -29,6 +29,7 @@ AArch64CallingConvention.cpp AArch64CallLowering.cpp AArch64CleanupLocalDynamicTLSPass.cpp + AArch64ClobberLRPass.cpp AArch64CollectLOH.cpp AArch64CondBrTuning.cpp AArch64ConditionalCompares.cpp