[llvm] Negative frame indicies as register. (PR #164459)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 21 10:13:41 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-regalloc

Author: Mikhail Gudim (mgudim)

<details>
<summary>Changes</summary>

This is used by reaching definitions analysis in order to track stores / loads from negative frame indices.

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


2 Files Affected:

- (modified) llvm/include/llvm/CodeGen/Register.h (+7-4) 
- (modified) llvm/lib/CodeGen/ReachingDefAnalysis.cpp (-3) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/Register.h b/llvm/include/llvm/CodeGen/Register.h
index e462a814562dc..961d6fe744b15 100644
--- a/llvm/include/llvm/CodeGen/Register.h
+++ b/llvm/include/llvm/CodeGen/Register.h
@@ -10,6 +10,7 @@
 #define LLVM_CODEGEN_REGISTER_H
 
 #include "llvm/MC/MCRegister.h"
+#include "llvm/Support/MathExtras.h"
 #include <cassert>
 
 namespace llvm {
@@ -35,7 +36,9 @@ class Register {
   // DenseMapInfo<unsigned> uses -1u and -2u.
   static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF,
                 "Reg isn't large enough to hold full range.");
-  static constexpr unsigned FirstStackSlot = 1u << 30;
+  static constexpr unsigned MaxFrameIndexBitwidth = 30;
+  static constexpr unsigned FirstStackSlot = 1u << MaxFrameIndexBitwidth;
+  static const unsigned StackSlotMask = (unsigned)(-1) >> (CHAR_BIT * sizeof(unsigned) - MaxFrameIndexBitwidth);
   static_assert(FirstStackSlot >= MCRegister::LastPhysicalReg);
   static constexpr unsigned VirtualRegFlag = 1u << 31;
 
@@ -46,8 +49,8 @@ class Register {
 
   /// Convert a non-negative frame index to a stack slot register value.
   static Register index2StackSlot(int FI) {
-    assert(FI >= 0 && "Cannot hold a negative frame index.");
-    return Register(FI + Register::FirstStackSlot);
+    assert(isInt<30>(FI) && "Frame index must be at most 30 bit integer");
+    return Register((FI & Register::StackSlotMask) | Register::FirstStackSlot);
   }
 
   /// Return true if the specified register number is in
@@ -87,7 +90,7 @@ class Register {
   /// Compute the frame index from a register value representing a stack slot.
   int stackSlotIndex() const {
     assert(isStack() && "Not a stack slot");
-    return static_cast<int>(Reg - Register::FirstStackSlot);
+    return static_cast<int>(SignExtend64(Reg & Register::StackSlotMask, 30));
   }
 
   constexpr operator unsigned() const { return Reg; }
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 40a89078bcf59..61706e13b8e91 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -193,7 +193,6 @@ void ReachingDefInfo::processDefs(MachineInstr *MI) {
   for (auto &MO : MI->operands()) {
     if (MO.isFI()) {
       int FrameIndex = MO.getIndex();
-      assert(FrameIndex >= 0 && "Can't handle negative frame indicies yet!");
       if (!isFIDef(*MI, FrameIndex, TII))
         continue;
       MBBFrameObjsReachingDefs[{MBBNumber, FrameIndex}].push_back(CurInstr);
@@ -302,8 +301,6 @@ void ReachingDefInfo::print(raw_ostream &OS) {
         Register Reg;
         if (MO.isFI()) {
           int FrameIndex = MO.getIndex();
-          assert(FrameIndex >= 0 &&
-                 "Can't handle negative frame indicies yet!");
           Reg = Register::index2StackSlot(FrameIndex);
         } else if (MO.isReg()) {
           if (MO.isDef())

``````````

</details>


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


More information about the llvm-commits mailing list