[llvm] [ARM] Run SLS hardening, BTI, and constant islands after BasicBlockSections (PR #196679)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 19:02:09 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: LumioseSil (LumioseSil)

<details>
<summary>Changes</summary>

ARM's SLS hardening, indirect-thunk insertion, AES erratum fix-up, branch-target (BTI) insertion, and constant-island placement all run before BasicBlockSections, MachineFunctionSplitter, and the machine outliner. That is the wrong place for them. It should be in PostBB.

---
Full diff: https://github.com/llvm/llvm-project/pull/196679.diff


3 Files Affected:

- (modified) llvm/lib/Target/ARM/ARMSLSHardening.cpp (+14) 
- (modified) llvm/lib/Target/ARM/ARMTargetMachine.cpp (+25-8) 
- (modified) llvm/test/CodeGen/ARM/O3-pipeline.ll (+5-7) 


``````````diff
diff --git a/llvm/lib/Target/ARM/ARMSLSHardening.cpp b/llvm/lib/Target/ARM/ARMSLSHardening.cpp
index 03f461f536eb0..6f03ec8092fea 100644
--- a/llvm/lib/Target/ARM/ARMSLSHardening.cpp
+++ b/llvm/lib/Target/ARM/ARMSLSHardening.cpp
@@ -219,6 +219,20 @@ void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) {
   bool isThumb = ThunkIt->isThumb;
 
   const TargetInstrInfo *TII = MF.getSubtarget<ARMSubtarget>().getInstrInfo();
+
+  // Depending on whether this pass is in the same FunctionPassManager as the
+  // IR->MIR conversion, the thunk may be completely empty (no MBB at all),
+  // or contain a single basic block with a single return instruction.
+  // Normalise it to contain a single empty basic block.
+  if (MF.size() == 1) {
+    assert(MF.front().size() == 1);
+    assert(MF.front().front().isReturn());
+    MF.front().erase(MF.front().begin());
+  } else {
+    assert(MF.size() == 0);
+    MF.push_back(MF.CreateMachineBasicBlock());
+  }
+
   MachineBasicBlock *Entry = &MF.front();
   Entry->clear();
 
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 0de6f3d16eff4..1f94179afe8b4 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -318,6 +318,7 @@ class ARMPassConfig : public TargetPassConfig {
   void addPreRegAlloc() override;
   void addPreSched2() override;
   void addPreEmitPass() override;
+  void addPostBBSections() override;
   void addPreEmitPass2() override;
 
   std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
@@ -520,8 +521,6 @@ void ARMPassConfig::addPreSched2() {
   }
 
   addPass(createMVEVPTBlockPass());
-  addPass(createARMIndirectThunks());
-  addPass(createARMSLSHardeningPass());
 }
 
 void ARMPassConfig::addPreEmitPass() {
@@ -542,19 +541,37 @@ void ARMPassConfig::addPreEmitPass() {
   }
 }
 
-void ARMPassConfig::addPreEmitPass2() {
+void ARMPassConfig::addPostBBSections() {
+  // ARMIndirectThunks emits the __llvm_slsblr_thunk_* helpers in the module,
+  // and ARMSLSHardening rewrites returns/indirect branches/indirect calls in
+  // the function (with indirect calls turning into direct calls into those
+  // helpers).  The hardening pass therefore requires the thunk declarations
+  // to already be present, so insertion must come first.  Both must run after
+  // BasicBlockSections / MachineFunctionSplitter and after the machine
+  // outliner so that any outlined code is also hardened and so block
+  // addresses are final before barriers/thunk calls are inserted.
+  addPass(createARMIndirectThunks());
+  addPass(createARMSLSHardeningPass());
 
   // Inserts fixup instructions before unsafe AES operations. Instructions may
-  // be inserted at the start of blocks and at within blocks so this pass has to
-  // come before those below.
+  // be inserted at the start of blocks and at within blocks so this pass has
+  // to come before BTI insertion below.
   addPass(createARMFixCortexA57AES1742098Pass());
+
   // Inserts BTIs at the start of functions and indirectly-called basic blocks,
   // so passes cannot add to the start of basic blocks once this has run.
+  // Placing it here lets it see the final post-section, post-outliner,
+  // post-SLS layout.
   addPass(createARMBranchTargetsPass());
-  // Inserts Constant Islands. Block sizes cannot be increased after this point,
-  // as this may push the branch ranges and load offsets of accessing constant
-  // pools out of range..
+
+  // Inserts Constant Islands. Block sizes cannot be increased after this
+  // point, as this may push the branch ranges and load offsets of accessing
+  // constant pools out of range, so this must run after BasicBlockSections
+  // (and the machine outliner) so it sees final block placement.
   addPass(createARMConstantIslandPass());
+}
+
+void ARMPassConfig::addPreEmitPass2() {
   // Finalises Low-Overhead Loops. This replaces pseudo instructions with real
   // instructions, but the pseudos all have conservative sizes so that block
   // sizes will only be decreased by this pass.
diff --git a/llvm/test/CodeGen/ARM/O3-pipeline.ll b/llvm/test/CodeGen/ARM/O3-pipeline.ll
index 9f4d70531a3f7..55facee477f8e 100644
--- a/llvm/test/CodeGen/ARM/O3-pipeline.ll
+++ b/llvm/test/CodeGen/ARM/O3-pipeline.ll
@@ -175,8 +175,6 @@
 ; CHECK-NEXT:      PostRA Machine Instruction Scheduler
 ; CHECK-NEXT:      Post RA top-down list latency scheduler
 ; CHECK-NEXT:      MVE VPT block insertion pass
-; CHECK-NEXT:      ARM Indirect Thunks
-; CHECK-NEXT:      ARM sls hardening pass
 ; CHECK-NEXT:      Analyze Machine Code For Garbage Collection
 ; CHECK-NEXT:      MachineDominator Tree Construction
 ; CHECK-NEXT:      Machine Natural Loop Construction
@@ -199,19 +197,19 @@
 ; CHECK-NEXT:      Machine Sanitizer Binary Metadata
 ; CHECK-NEXT:    Machine Outliner
 ; CHECK-NEXT:    FunctionPass Manager
-; CHECK-NEXT:      Lazy Machine Block Frequency Analysis
-; CHECK-NEXT:      Machine Optimization Remark Emitter
-; CHECK-NEXT:      Stack Frame Layout Analysis
+; CHECK-NEXT:      ARM Indirect Thunks
+; CHECK-NEXT:      ARM sls hardening pass
 ; CHECK-NEXT:      Reaching Definitions Analysis
 ; CHECK-NEXT:      ARM fix for Cortex-A57 AES Erratum 1742098
 ; CHECK-NEXT:      ARM Branch Targets
 ; CHECK-NEXT:      MachineDominator Tree Construction
 ; CHECK-NEXT:      ARM constant island placement and branch shortening pass
+; CHECK-NEXT:      Lazy Machine Block Frequency Analysis
+; CHECK-NEXT:      Machine Optimization Remark Emitter
+; CHECK-NEXT:      Stack Frame Layout Analysis
 ; CHECK-NEXT:      MachineDominator Tree Construction
 ; CHECK-NEXT:      Machine Natural Loop Construction
 ; CHECK-NEXT:      Reaching Definitions Analysis
 ; CHECK-NEXT:      ARM Low Overhead Loops pass
-; CHECK-NEXT:      Lazy Machine Block Frequency Analysis
-; CHECK-NEXT:      Machine Optimization Remark Emitter
 ; CHECK-NEXT:      ARM Assembly Printer
 ; CHECK-NEXT:      Free MachineFunction

``````````

</details>


https://github.com/llvm/llvm-project/pull/196679


More information about the llvm-commits mailing list