diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index 6f2aeb83a451af..66ad701d839585 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -40,7 +40,6 @@ FunctionPass *createAArch64ISelDag(AArch64TargetMachine &TM, FunctionPass *createAArch64StorePairSuppressPass(); FunctionPass *createAArch64ExpandPseudoPass(); FunctionPass *createAArch64SLSHardeningPass(); -FunctionPass *createAArch64IndirectThunks(); FunctionPass *createAArch64SpeculationHardeningPass(); FunctionPass *createAArch64LoadStoreOptimizationPass(); ModulePass *createAArch64LowerHomogeneousPrologEpilogPass(); diff --git a/llvm/lib/Target/AArch64/AArch64SLSHardening.cpp b/llvm/lib/Target/AArch64/AArch64SLSHardening.cpp index 7660de5c082d12..00ba31b3e500dc 100644 --- a/llvm/lib/Target/AArch64/AArch64SLSHardening.cpp +++ b/llvm/lib/Target/AArch64/AArch64SLSHardening.cpp @@ -13,20 +13,16 @@ #include "AArch64InstrInfo.h" #include "AArch64Subtarget.h" -#include "Utils/AArch64BaseInfo.h" #include "llvm/CodeGen/IndirectThunks.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Pass.h" -#include "llvm/Support/CodeGen.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetMachine.h" #include @@ -36,38 +32,42 @@ using namespace llvm; #define AARCH64_SLS_HARDENING_NAME "AArch64 sls hardening pass" +static const char SLSBLRNamePrefix[] = "__llvm_slsblr_thunk_"; + namespace { -class AArch64SLSHardening : public MachineFunctionPass { -public: - const TargetInstrInfo *TII; - const TargetRegisterInfo *TRI; - const AArch64Subtarget *ST; +// Set of inserted thunks: bitmask with bits corresponding to +// indexes in SLSBLRThunks array. +typedef uint32_t ThunksSet; - static char ID; - - AArch64SLSHardening() : MachineFunctionPass(ID) { - initializeAArch64SLSHardeningPass(*PassRegistry::getPassRegistry()); +struct SLSHardeningInserter : ThunkInserter { +public: + const char *getThunkPrefix() { return SLSBLRNamePrefix; } + bool mayUseThunk(const MachineFunction &MF) { + ComdatThunks &= !MF.getSubtarget().hardenSlsNoComdat(); + // We are inserting barriers aside from thunk calls, so + // check hardenSlsRetBr() as well. + return MF.getSubtarget().hardenSlsBlr() || + MF.getSubtarget().hardenSlsRetBr(); } + ThunksSet insertThunks(MachineModuleInfo &MMI, MachineFunction &MF, + ThunksSet ExistingThunks); + void populateThunk(MachineFunction &MF); - bool runOnMachineFunction(MachineFunction &Fn) override; +private: + bool ComdatThunks = true; - StringRef getPassName() const override { return AARCH64_SLS_HARDENING_NAME; } + bool hardenReturnsAndBRs(MachineModuleInfo &MMI, MachineBasicBlock &MBB); + bool hardenBLRs(MachineModuleInfo &MMI, MachineBasicBlock &MBB, + ThunksSet &Thunks); -private: - bool hardenReturnsAndBRs(MachineBasicBlock &MBB) const; - bool hardenBLRs(MachineBasicBlock &MBB) const; - MachineBasicBlock &ConvertBLRToBL(MachineBasicBlock &MBB, - MachineBasicBlock::instr_iterator) const; + void convertBLRToBL(MachineModuleInfo &MMI, MachineBasicBlock &MBB, + MachineBasicBlock::instr_iterator MBBI, + ThunksSet &Thunks); }; } // end anonymous namespace -char AArch64SLSHardening::ID = 0; - -INITIALIZE_PASS(AArch64SLSHardening, "aarch64-sls-hardening", - AARCH64_SLS_HARDENING_NAME, false, false) - static void insertSpeculationBarrier(const AArch64Subtarget *ST, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, @@ -90,18 +90,18 @@ static void insertSpeculationBarrier(const AArch64Subtarget *ST, BuildMI(MBB, MBBI, DL, TII->get(BarrierOpc)); } -bool AArch64SLSHardening::runOnMachineFunction(MachineFunction &MF) { - ST = &MF.getSubtarget(); - TII = MF.getSubtarget().getInstrInfo(); - TRI = MF.getSubtarget().getRegisterInfo(); +ThunksSet SLSHardeningInserter::insertThunks(MachineModuleInfo &MMI, + MachineFunction &MF, + ThunksSet ExistingThunks) { + const AArch64Subtarget *ST = &MF.getSubtarget(); - bool Modified = false; for (auto &MBB : MF) { - Modified |= hardenReturnsAndBRs(MBB); - Modified |= hardenBLRs(MBB); + if (ST->hardenSlsRetBr()) + hardenReturnsAndBRs(MMI, MBB); + if (ST->hardenSlsBlr()) + hardenBLRs(MMI, MBB, ExistingThunks); } - - return Modified; + return ExistingThunks; } static bool isBLR(const MachineInstr &MI) { @@ -120,9 +120,10 @@ static bool isBLR(const MachineInstr &MI) { return false; } -bool AArch64SLSHardening::hardenReturnsAndBRs(MachineBasicBlock &MBB) const { - if (!ST->hardenSlsRetBr()) - return false; +bool SLSHardeningInserter::hardenReturnsAndBRs(MachineModuleInfo &MMI, + MachineBasicBlock &MBB) { + const AArch64Subtarget *ST = + &MBB.getParent()->getSubtarget(); bool Modified = false; MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(), E = MBB.end(); MachineBasicBlock::iterator NextMBBI; @@ -138,78 +139,55 @@ bool AArch64SLSHardening::hardenReturnsAndBRs(MachineBasicBlock &MBB) const { return Modified; } -static const char SLSBLRNamePrefix[] = "__llvm_slsblr_thunk_"; - +static const unsigned NumPermittedRegs = 29; static const struct ThunkNameAndReg { const char* Name; Register Reg; -} SLSBLRThunks[] = { - { "__llvm_slsblr_thunk_x0", AArch64::X0}, - { "__llvm_slsblr_thunk_x1", AArch64::X1}, - { "__llvm_slsblr_thunk_x2", AArch64::X2}, - { "__llvm_slsblr_thunk_x3", AArch64::X3}, - { "__llvm_slsblr_thunk_x4", AArch64::X4}, - { "__llvm_slsblr_thunk_x5", AArch64::X5}, - { "__llvm_slsblr_thunk_x6", AArch64::X6}, - { "__llvm_slsblr_thunk_x7", AArch64::X7}, - { "__llvm_slsblr_thunk_x8", AArch64::X8}, - { "__llvm_slsblr_thunk_x9", AArch64::X9}, - { "__llvm_slsblr_thunk_x10", AArch64::X10}, - { "__llvm_slsblr_thunk_x11", AArch64::X11}, - { "__llvm_slsblr_thunk_x12", AArch64::X12}, - { "__llvm_slsblr_thunk_x13", AArch64::X13}, - { "__llvm_slsblr_thunk_x14", AArch64::X14}, - { "__llvm_slsblr_thunk_x15", AArch64::X15}, - // X16 and X17 are deliberately missing, as the mitigation requires those - // register to not be used in BLR. See comment in ConvertBLRToBL for more - // details. - { "__llvm_slsblr_thunk_x18", AArch64::X18}, - { "__llvm_slsblr_thunk_x19", AArch64::X19}, - { "__llvm_slsblr_thunk_x20", AArch64::X20}, - { "__llvm_slsblr_thunk_x21", AArch64::X21}, - { "__llvm_slsblr_thunk_x22", AArch64::X22}, - { "__llvm_slsblr_thunk_x23", AArch64::X23}, - { "__llvm_slsblr_thunk_x24", AArch64::X24}, - { "__llvm_slsblr_thunk_x25", AArch64::X25}, - { "__llvm_slsblr_thunk_x26", AArch64::X26}, - { "__llvm_slsblr_thunk_x27", AArch64::X27}, - { "__llvm_slsblr_thunk_x28", AArch64::X28}, - { "__llvm_slsblr_thunk_x29", AArch64::FP}, - // X30 is deliberately missing, for similar reasons as X16 and X17 are - // missing. - { "__llvm_slsblr_thunk_x31", AArch64::XZR}, +} SLSBLRThunks[NumPermittedRegs] = { + {"__llvm_slsblr_thunk_x0", AArch64::X0}, + {"__llvm_slsblr_thunk_x1", AArch64::X1}, + {"__llvm_slsblr_thunk_x2", AArch64::X2}, + {"__llvm_slsblr_thunk_x3", AArch64::X3}, + {"__llvm_slsblr_thunk_x4", AArch64::X4}, + {"__llvm_slsblr_thunk_x5", AArch64::X5}, + {"__llvm_slsblr_thunk_x6", AArch64::X6}, + {"__llvm_slsblr_thunk_x7", AArch64::X7}, + {"__llvm_slsblr_thunk_x8", AArch64::X8}, + {"__llvm_slsblr_thunk_x9", AArch64::X9}, + {"__llvm_slsblr_thunk_x10", AArch64::X10}, + {"__llvm_slsblr_thunk_x11", AArch64::X11}, + {"__llvm_slsblr_thunk_x12", AArch64::X12}, + {"__llvm_slsblr_thunk_x13", AArch64::X13}, + {"__llvm_slsblr_thunk_x14", AArch64::X14}, + {"__llvm_slsblr_thunk_x15", AArch64::X15}, + // X16 and X17 are deliberately missing, as the mitigation requires those + // register to not be used in BLR. See comment in ConvertBLRToBL for more + // details. + {"__llvm_slsblr_thunk_x18", AArch64::X18}, + {"__llvm_slsblr_thunk_x19", AArch64::X19}, + {"__llvm_slsblr_thunk_x20", AArch64::X20}, + {"__llvm_slsblr_thunk_x21", AArch64::X21}, + {"__llvm_slsblr_thunk_x22", AArch64::X22}, + {"__llvm_slsblr_thunk_x23", AArch64::X23}, + {"__llvm_slsblr_thunk_x24", AArch64::X24}, + {"__llvm_slsblr_thunk_x25", AArch64::X25}, + {"__llvm_slsblr_thunk_x26", AArch64::X26}, + {"__llvm_slsblr_thunk_x27", AArch64::X27}, + {"__llvm_slsblr_thunk_x28", AArch64::X28}, + {"__llvm_slsblr_thunk_x29", AArch64::FP}, + // X30 is deliberately missing, for similar reasons as X16 and X17 are + // missing. + {"__llvm_slsblr_thunk_x31", AArch64::XZR}, }; -namespace { -struct SLSBLRThunkInserter : ThunkInserter { - const char *getThunkPrefix() { return SLSBLRNamePrefix; } - bool mayUseThunk(const MachineFunction &MF) { - ComdatThunks &= !MF.getSubtarget().hardenSlsNoComdat(); - return MF.getSubtarget().hardenSlsBlr(); - } - bool insertThunks(MachineModuleInfo &MMI, MachineFunction &MF, - bool ExistingThunks); - void populateThunk(MachineFunction &MF); - -private: - bool ComdatThunks = true; -}; -} // namespace - -bool SLSBLRThunkInserter::insertThunks(MachineModuleInfo &MMI, - MachineFunction &MF, - bool ExistingThunks) { - if (ExistingThunks) - return false; - // FIXME: It probably would be possible to filter which thunks to produce - // based on which registers are actually used in BLR instructions in this - // function. But would that be a worthwhile optimization? - for (auto T : SLSBLRThunks) - createThunkFunction(MMI, T.Name, ComdatThunks); - return true; +unsigned getThunkIndex(Register Reg) { + for (unsigned I = 0; I < NumPermittedRegs; ++I) + if (SLSBLRThunks[I].Reg == Reg) + return I; + llvm_unreachable("Unexpected register"); } -void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) { +void SLSHardeningInserter::populateThunk(MachineFunction &MF) { assert(MF.getFunction().hasComdat() == ComdatThunks && "ComdatThunks value changed since MF creation"); // FIXME: How to better communicate Register number, rather than through @@ -258,8 +236,9 @@ void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) { Entry->end(), DebugLoc(), true /*AlwaysUseISBDSB*/); } -MachineBasicBlock &AArch64SLSHardening::ConvertBLRToBL( - MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator MBBI) const { +void SLSHardeningInserter::convertBLRToBL( + MachineModuleInfo &MMI, MachineBasicBlock &MBB, + MachineBasicBlock::instr_iterator MBBI, ThunksSet &Thunks) { // Transform a BLR to a BL as follows: // Before: // |-----------------------------| @@ -285,7 +264,6 @@ MachineBasicBlock &AArch64SLSHardening::ConvertBLRToBL( // | barrierInsts | // |-----------------------------| // - // The __llvm_slsblr_thunk_xN thunks are created by the SLSBLRThunkInserter. // This function merely needs to transform BLR xN into BL // __llvm_slsblr_thunk_xN. // @@ -318,37 +296,16 @@ MachineBasicBlock &AArch64SLSHardening::ConvertBLRToBL( } DebugLoc DL = BLR.getDebugLoc(); - // If we'd like to support also BLRAA and BLRAB instructions, we'd need - // a lot more different kind of thunks. - // For example, a - // - // BLRAA xN, xM - // - // instruction probably would need to be transformed to something like: - // - // BL __llvm_slsblraa_thunk_x_x - // - // __llvm_slsblraa_thunk_x_x: - // BRAA x, x - // barrierInsts - // - // Given that about 30 different values of N are possible and about 30 - // different values of M are possible in the above, with the current way - // of producing indirect thunks, we'd be producing about 30 times 30, i.e. - // about 900 thunks (where most might not be actually called). This would - // multiply further by two to support both BLRAA and BLRAB variants of those - // instructions. - // If we'd want to support this, we'd probably need to look into a different - // way to produce thunk functions, based on which variants are actually - // needed, rather than producing all possible variants. - // So far, LLVM does never produce BLRA* instructions, so let's leave this - // for the future when LLVM can start producing BLRA* instructions. MachineFunction &MF = *MBBI->getMF(); MCContext &Context = MBB.getParent()->getContext(); - auto ThunkIt = - llvm::find_if(SLSBLRThunks, [Reg](auto T) { return T.Reg == Reg; }); - assert (ThunkIt != std::end(SLSBLRThunks)); - MCSymbol *Sym = Context.getOrCreateSymbol(ThunkIt->Name); + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + unsigned ThunkIndex = getThunkIndex(Reg); + StringRef ThunkName = SLSBLRThunks[ThunkIndex].Name; + MCSymbol *Sym = Context.getOrCreateSymbol(ThunkName); + if (!(Thunks & (1u << ThunkIndex))) { + Thunks |= 1u << ThunkIndex; + createThunkFunction(MMI, ThunkName, ComdatThunks); + } MachineInstr *BL = BuildMI(MBB, MBBI, DL, TII->get(BLOpcode)).addSym(Sym); @@ -386,13 +343,11 @@ MachineBasicBlock &AArch64SLSHardening::ConvertBLRToBL( RegIsKilled /*isKill*/)); // Remove BLR instruction MBB.erase(MBBI); - - return MBB; } -bool AArch64SLSHardening::hardenBLRs(MachineBasicBlock &MBB) const { - if (!ST->hardenSlsBlr()) - return false; +bool SLSHardeningInserter::hardenBLRs(MachineModuleInfo &MMI, + MachineBasicBlock &MBB, + ThunksSet &Thunks) { bool Modified = false; MachineBasicBlock::instr_iterator MBBI = MBB.instr_begin(), E = MBB.instr_end(); @@ -401,31 +356,30 @@ bool AArch64SLSHardening::hardenBLRs(MachineBasicBlock &MBB) const { MachineInstr &MI = *MBBI; NextMBBI = std::next(MBBI); if (isBLR(MI)) { - ConvertBLRToBL(MBB, MBBI); + convertBLRToBL(MMI, MBB, MBBI, Thunks); Modified = true; } } return Modified; } -FunctionPass *llvm::createAArch64SLSHardeningPass() { - return new AArch64SLSHardening(); -} - namespace { -class AArch64IndirectThunks : public ThunkInserterPass { +class AArch64SLSHardening : public ThunkInserterPass { public: static char ID; - AArch64IndirectThunks() : ThunkInserterPass(ID) {} + AArch64SLSHardening() : ThunkInserterPass(ID) {} - StringRef getPassName() const override { return "AArch64 Indirect Thunks"; } + StringRef getPassName() const override { return AARCH64_SLS_HARDENING_NAME; } }; } // end anonymous namespace -char AArch64IndirectThunks::ID = 0; +char AArch64SLSHardening::ID = 0; + +INITIALIZE_PASS(AArch64SLSHardening, "aarch64-sls-hardening", + AARCH64_SLS_HARDENING_NAME, false, false) -FunctionPass *llvm::createAArch64IndirectThunks() { - return new AArch64IndirectThunks(); +FunctionPass *llvm::createAArch64SLSHardeningPass() { + return new AArch64SLSHardening(); } diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 37ce07d4a09de2..bcd677310d1247 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -861,7 +861,6 @@ void AArch64PassConfig::addPreEmitPass() { } void AArch64PassConfig::addPostBBSections() { - addPass(createAArch64IndirectThunks()); addPass(createAArch64SLSHardeningPass()); addPass(createAArch64PointerAuthPass()); if (EnableBranchTargets) diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll index a0306b8e1e9244..78a7b84b8479b5 100644 --- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -74,7 +74,6 @@ ; CHECK-NEXT: StackMap Liveness Analysis ; CHECK-NEXT: Live DEBUG_VALUE analysis ; CHECK-NEXT: Machine Sanitizer Binary Metadata -; CHECK-NEXT: AArch64 Indirect Thunks ; CHECK-NEXT: AArch64 sls hardening pass ; CHECK-NEXT: AArch64 Pointer Authentication ; CHECK-NEXT: AArch64 Branch Targets diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll index 84e672d14d99d5..c5d604a5a2783e 100644 --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -227,7 +227,6 @@ ; CHECK-NEXT: Machine Sanitizer Binary Metadata ; CHECK-NEXT: Machine Outliner ; CHECK-NEXT: FunctionPass Manager -; CHECK-NEXT: AArch64 Indirect Thunks ; CHECK-NEXT: AArch64 sls hardening pass ; CHECK-NEXT: AArch64 Pointer Authentication ; CHECK-NEXT: AArch64 Branch Targets diff --git a/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll b/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll index 3ffaf962425b38..08c314e538734c 100644 --- a/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll +++ b/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll @@ -34,10 +34,6 @@ ; HOTNESS-NEXT: Executing Pass 'Function Pass Manager' ; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... ; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... -; HOTNESS-NEXT: Executing Pass 'AArch64 Indirect Thunks' on Function 'empty_func'... -; HOTNESS-NEXT: Freeing Pass 'AArch64 Indirect Thunks' on Function 'empty_func'... -; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... -; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... ; HOTNESS-NEXT: Executing Pass 'AArch64 sls hardening pass' on Function 'empty_func'... ; HOTNESS-NEXT: Freeing Pass 'AArch64 sls hardening pass' on Function 'empty_func'... ; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... @@ -83,10 +79,6 @@ ; NO_HOTNESS-NEXT: Executing Pass 'Function Pass Manager' ; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... ; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... -; NO_HOTNESS-NEXT: Executing Pass 'AArch64 Indirect Thunks' on Function 'empty_func'... -; NO_HOTNESS-NEXT: Freeing Pass 'AArch64 Indirect Thunks' on Function 'empty_func'... -; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... -; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... ; NO_HOTNESS-NEXT: Executing Pass 'AArch64 sls hardening pass' on Function 'empty_func'... ; NO_HOTNESS-NEXT: Freeing Pass 'AArch64 sls hardening pass' on Function 'empty_func'... ; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... diff --git a/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr-bti.mir b/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr-bti.mir index 92353b648943a6..46e42bbe6bf82b 100644 --- a/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr-bti.mir +++ b/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr-bti.mir @@ -8,8 +8,6 @@ # These BLR/BTI bundles are produced when calling a returns_twice function # (like setjmp) indirectly. --- | - $__llvm_slsblr_thunk_x8 = comdat any - define dso_local void @fn() #0 { entry: %fnptr = alloca ptr, align 8 @@ -22,15 +20,8 @@ ; Function Attrs: returns_twice declare i32 @setjmp(ptr noundef) #1 - ; Function Attrs: naked nounwind - define linkonce_odr hidden void @__llvm_slsblr_thunk_x8() #2 comdat { - entry: - ret void - } - attributes #0 = { "target-features"="+harden-sls-blr" } attributes #1 = { returns_twice } - attributes #2 = { naked nounwind } !llvm.module.flags = !{!0} !0 = !{i32 8, !"branch-target-enforcement", i32 1} @@ -75,14 +66,3 @@ body: | early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.1) RET undef $lr ... ---- -name: __llvm_slsblr_thunk_x8 -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x8 - - $x16 = ORRXrs $xzr, $x8, 0 - BR $x16 - SpeculationBarrierISBDSBEndBB -... diff --git a/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr.mir b/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr.mir index 81f95348f511e5..7f85ce8485a07f 100644 --- a/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr.mir +++ b/llvm/test/CodeGen/AArch64/speculation-hardening-sls-blr.mir @@ -1,12 +1,17 @@ # RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu \ # RUN: -start-before aarch64-sls-hardening \ # RUN: -stop-after aarch64-sls-hardening -o - %s \ -# RUN: | FileCheck %s --check-prefixes=CHECK +# RUN: | FileCheck %s --check-prefixes=CHECK \ +# RUN: --implicit-check-not=__llvm_slsblr_thunk_x7 +# RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu \ +# RUN: -start-before aarch64-sls-hardening \ +# RUN: -asm-verbose=0 -o - %s \ +# RUN: | FileCheck %s --check-prefixes=ASM \ +# RUN: --implicit-check-not=__llvm_slsblr_thunk_x7 # Check that the BLR SLS hardening transforms a BLR into a BL with operands as # expected. --- | - $__llvm_slsblr_thunk_x8 = comdat any @a = dso_local local_unnamed_addr global i32 (...)* null, align 8 @b = dso_local local_unnamed_addr global i32 0, align 4 @@ -17,12 +22,6 @@ store i32 %call, i32* @b, align 4 ret void } - - ; Function Attrs: naked nounwind - define linkonce_odr hidden void @__llvm_slsblr_thunk_x8() naked nounwind comdat { - entry: - ret void - } ... --- name: fn1 @@ -46,13 +45,15 @@ body: | ... ---- -name: __llvm_slsblr_thunk_x8 -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x8 - BR $x8 - SpeculationBarrierISBDSBEndBB -... +# CHECK: name: __llvm_slsblr_thunk_x8 +# +# CHECK: $x16 = ORRXrs $xzr, $x8, 0 +# CHECK-NEXT: BR $x16 +# CHECK-NEXT: SpeculationBarrierISBDSBEndBB + +# ASM-LABEL: __llvm_slsblr_thunk_x8: +# ASM-NEXT: mov x16, x8 +# ASM-NEXT: br x16 +# ASM-NEXT: dsb sy +# ASM-NEXT: isb