Skip to content

[llvm][RISCV] Set ScalableVector stack id in proper place #117862

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

enoskova-sc
Copy link
Contributor

@enoskova-sc enoskova-sc commented Nov 27, 2024

Without this patch ScalableVector frame index property is used before assignment. More precisely, let's take a look at RISCVFrameLowering::assignCalleeSavedSpillSlots. In this function we divide callee saved registers on scalar and vector ones, based on ScalableVector property of their frame indexes:

  ...
  const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
  const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
  ...

But we assign ScalableVector property several lines below:

  ...
  auto storeRegToStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
    for (auto &CS : CSInfo) {
      // Insert the spill to the stack frame.
      Register Reg = CS.getReg();
      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
      TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg),
                              CS.getFrameIdx(), RC, TRI, Register());
    }
  };
  storeRegToStackSlot(UnmanagedCSI);
  ...

Due to it, list of RVV callee saved registers will always be empty. Currently this problem doesn't appear, but if you slightly change the code and, for example, put some instructions between scalar and vector spills, the resulting code will be ill formed.

Shrink-Wrap points split Part 1.
RFC: https://discourse.llvm.org/t/shrink-wrap-save-restore-points-splitting/83581

Part 2: #119355
Part 3: #119357
Part 4: #119358
Part 5: #119359

@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Elizaveta Noskova (enoskova-sc)

Changes

Without this patch ScalableVector frame index property is used before assignment. More precisely, let's take a look at RISCVFrameLowering::assignCalleeSavedSpillSlots. In this function we divide callee saved registers on scalar and vector ones, based on ScalableVector property of their frame indexes:

  ...
  const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
  const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
  ...

But we assign ScalableVector property several lines below:

  ...
  auto storeRegToStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
    for (auto &CS : CSInfo) {
      // Insert the spill to the stack frame.
      Register Reg = CS.getReg();
      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
      TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg),
                              CS.getFrameIdx(), RC, TRI, Register());
    }
  };
  storeRegToStackSlot(UnmanagedCSI);
  ...

Due to it, list of RVV callee saved registers will always be empty. Currently this problem doesn't appear, but if you slightly change the code and, for example, put some instructions between scalar and vector spills, the resulting code will be ill formed.


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

1 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+4)
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 2da32fece061bb..950916d98df285 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1610,6 +1610,8 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
         int FrameIdx = MFI.CreateFixedSpillStackObject(Size, Offset);
         assert(FrameIdx < 0);
         CS.setFrameIdx(FrameIdx);
+        if (RISCVRegisterInfo::isRVVRegClass(RC))
+          MFI.setStackID(FrameIdx, TargetStackID::ScalableVector);
         continue;
       }
     }
@@ -1626,6 +1628,8 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
     if ((unsigned)FrameIdx > MaxCSFrameIndex)
       MaxCSFrameIndex = FrameIdx;
     CS.setFrameIdx(FrameIdx);
+    if (RISCVRegisterInfo::isRVVRegClass(RC))
+      MFI.setStackID(FrameIdx, TargetStackID::ScalableVector);
   }
 
   // Allocate a fixed object that covers the full push or libcall size.

@enoskova-sc
Copy link
Contributor Author

@4vtomat, please, review.

@4vtomat
Copy link
Member

4vtomat commented Nov 28, 2024

Umm could you provide a test case, I don't quite understand what situation could break this lol

@topperc topperc changed the title [llvm] Set ScalableVector stack id in proper place [llvm][RISCV] Set ScalableVector stack id in proper place Nov 30, 2024
Without this patch ScalableVector frame index property is used before assignment.
More precisely, let's take a look at RISCVFrameLowering::assignCalleeSavedSpillSlots.
In this function we divide callee saved registers on scalar and vector ones,
based on ScalableVector property of their frame indexes:
```
  ...
  const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
  const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
  ...
```
But we assign ScalableVector property several lines below:
```
  ...
  auto storeRegToStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
    for (auto &CS : CSInfo) {
      // Insert the spill to the stack frame.
      Register Reg = CS.getReg();
      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
      TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg),
                              CS.getFrameIdx(), RC, TRI, Register());
    }
  };
  storeRegToStackSlot(UnmanagedCSI);
  ...
```
Due to it, list of RVV callee saved registers will always be empty.
Currently this problem doesn't appear, but if you slightly change the code and,
for example, put some instructions between scalar and vector spills,
the resulting code will be ill formed.
@enoskova-sc
Copy link
Contributor Author

enoskova-sc commented Dec 10, 2024

Umm could you provide a test case, I don't quite understand what situation could break this lol

@4vtomat, unfortunately, I can't write any test, which can be broken in current llvm code base.

But I have faced a problem while preparing this series of patches. More precisely, Part 4, test.

All in all, I think, error can reveal in any other context while code base is developing.

@@ -1610,6 +1610,8 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
int FrameIdx = MFI.CreateFixedSpillStackObject(Size, Offset);
assert(FrameIdx < 0);
CS.setFrameIdx(FrameIdx);
if (RISCVRegisterInfo::isRVVRegClass(RC))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't any vector registers in FixedCSRFIMap so I don't think this can happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

@enoskova-sc enoskova-sc force-pushed the users/enoskova-sc/fix-vcsr-spill-placement branch from 7931bae to aed8c91 Compare December 11, 2024 09:52
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -1623,6 +1623,8 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
if ((unsigned)FrameIdx > MaxCSFrameIndex)
MaxCSFrameIndex = FrameIdx;
CS.setFrameIdx(FrameIdx);
if (RISCVRegisterInfo::isRVVRegClass(RC))
MFI.setStackID(FrameIdx, TargetStackID::ScalableVector);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spill size is still an unsigned, and not a TypeSize. How do scalable types still have fixed spill sizes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Do you want me to investigate this issue and may be create a fix in current PR?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely should not be fixed in this PR. It requires tablegen changes, TargetRegisterInfo.h interface changes. Probably individual changes other targets.

@enoskova-sc
Copy link
Contributor Author

@arsenm, @4vtomat, can I merge this PR?

Copy link
Member

@4vtomat 4vtomat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank!

@asi-sc asi-sc merged commit 5fc8062 into llvm:main Dec 18, 2024
8 checks passed
asi-sc pushed a commit that referenced this pull request Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants