[llvm] [CodeGen] Don't schedule across frame register save/restore for sanitized functions (PR #221714)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 05:21:33 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: hev (heiher)

<details>
<summary>Changes</summary>

Even if the target's Post-RA Scheduler can reorder instructions across the frame register save/restore, it must not do so for sanitized functions. A crash can happen at any point, and sanitizers need to be able to unwind from the PC at the point of the crash using a frame register that still points to the current frame.

This is the same class of issue fixed for shrink-wrapping in 2cdcfd23cd01 ("[ShrinkWrapping] Disable the optimization for functions with sanitize like attribute.").

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


3 Files Affected:

- (modified) llvm/lib/CodeGen/TargetInstrInfo.cpp (+15) 
- (added) llvm/test/CodeGen/LoongArch/postra-sched-sanitize.ll (+15) 
- (added) llvm/test/CodeGen/RISCV/postra-sched-sanitize.ll (+15) 


``````````diff
diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp
index 92fc628e888e5..c3533a652a5f4 100644
--- a/llvm/lib/CodeGen/TargetInstrInfo.cpp
+++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp
@@ -1711,6 +1711,21 @@ bool TargetInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
   if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
     return true;
 
+  // Sanitizers need a correct stack frame at the point of a crash,
+  // which can happen anywhere. Treat frame register modifications
+  // as scheduling boundaries so the scheduler can't reorder other
+  // instructions across the frame register save/restore.
+  if (MF.getFunction().hasFnAttribute(Attribute::SanitizeAddress) ||
+      MF.getFunction().hasFnAttribute(Attribute::SanitizeThread) ||
+      MF.getFunction().hasFnAttribute(Attribute::SanitizeMemory) ||
+      MF.getFunction().hasFnAttribute(Attribute::SanitizeType) ||
+      MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress) ||
+      MF.getFunction().hasFnAttribute(Attribute::SanitizeMemTag)) {
+    Register FrameReg = TRI.getFrameRegister(MF);
+    if (MI.modifiesRegister(FrameReg, &TRI))
+      return true;
+  }
+
   // Don't attempt to schedule around any instruction that defines
   // a stack-oriented pointer, as it's unlikely to be profitable. This
   // saves compile time, because it doesn't require every single
diff --git a/llvm/test/CodeGen/LoongArch/postra-sched-sanitize.ll b/llvm/test/CodeGen/LoongArch/postra-sched-sanitize.ll
new file mode 100644
index 0000000000000..3b24985e1a19e
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/postra-sched-sanitize.ll
@@ -0,0 +1,15 @@
+; RUN: llc --mtriple=loongarch32 --frame-pointer=all < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --frame-pointer=all < %s | FileCheck %s
+
+; CHECK-LABEL: foo:
+; CHECK: addi.{{w|d}}	[[REG1:\$[a-z0-9]+]], [[REG1]], 1
+; CHECK: st.w	[[REG1]], {{\$[a-z0-9]+}}, {{[0-9]+}}
+; CHECK: ld.{{w|d}}	$fp, $sp, {{[0-9]+}}
+define void @foo() nounwind sanitize_address {
+entry:
+  %1 = load ptr, ptr inttoptr (i32 64 to ptr), align 64
+  %2 = load i32, ptr %1, align 8
+  %3 = add nsw i32 %2, 1
+  store i32 %3, ptr %1, align 8
+  ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/postra-sched-sanitize.ll b/llvm/test/CodeGen/RISCV/postra-sched-sanitize.ll
new file mode 100644
index 0000000000000..e4eff62099b0c
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/postra-sched-sanitize.ll
@@ -0,0 +1,15 @@
+; RUN: llc --mtriple=riscv32 --mattr=+use-postra-scheduler --frame-pointer=all < %s | FileCheck %s
+; RUN: llc --mtriple=riscv64 --mattr=+use-postra-scheduler --frame-pointer=all < %s | FileCheck %s
+
+; CHECK-LABEL: foo:
+; CHECK: addi	[[REG1:[a-z0-9]+]], [[REG1]], 1
+; CHECK: sw	[[REG1]], {{[0-9]+}}({{[a-z0-9]+}})
+; CHECK: {{lw|ld}}	s0, {{[0-9]+}}(sp)
+define void @foo() nounwind sanitize_address {
+entry:
+  %1 = load ptr, ptr inttoptr (i32 64 to ptr), align 64
+  %2 = load i32, ptr %1, align 8
+  %3 = add nsw i32 %2, 1
+  store i32 %3, ptr %1, align 8
+  ret void
+}

``````````

</details>


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


More information about the llvm-commits mailing list