Skip to content
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

[ARM] Add a method to clear registers #69659

Closed
wants to merge 6 commits into from

Conversation

bwendling
Copy link
Collaborator

This allows us to clear registers in target-independent code. The first
use will be for clearing the stack protector from registers before
returning.

This allows us to clear registers in target-independent code. The first
use will be for clearing the stack protector from registers before
returning.
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 19, 2023

@llvm/pr-subscribers-backend-arm

Author: Bill Wendling (bwendling)

Changes

This allows us to clear registers in target-independent code. The first
use will be for clearing the stack protector from registers before
returning.


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

2 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp (+10)
  • (modified) llvm/lib/Target/ARM/ARMBaseInstrInfo.h (+5)
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 1ffdde0360cf623..a07504aaedbc4da 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -6735,6 +6735,16 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
   return CallPt;
 }
 
+void ARMBaseInstrInfo::buildClearRegister(Register DstReg,
+                                          MachineBasicBlock &MBB,
+                                          MachineBasicBlock::iterator Iter,
+                                          DebugLoc &DL,
+                                          bool AllowSideEffects) const {
+  unsigned Opc = Subtarget.isThumb2() ? ARM::t2MOVi32imm : ARM::MOVi32imm;
+  BuildMI(MBB, Iter, DL, get(Opc), DstReg)
+      .addImm(0);
+}
+
 bool ARMBaseInstrInfo::shouldOutlineFromFunctionByDefault(
     MachineFunction &MF) const {
   return Subtarget.isMClass() && MF.getFunction().hasMinSize();
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
index 5efcc1a0d9fc073..44b3e528c0c242e 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -363,6 +363,11 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
                      MachineBasicBlock::iterator &It, MachineFunction &MF,
                      outliner::Candidate &C) const override;
 
+  void buildClearRegister(Register Reg, MachineBasicBlock &MBB,
+                          MachineBasicBlock::iterator Iter,
+                          DebugLoc &DL,
+                          bool AllowSideEffects = true) const override;
+
   /// Enable outlining by default at -Oz.
   bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
 

@github-actions
Copy link

github-actions bot commented Oct 19, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

MachineBasicBlock::iterator Iter,
DebugLoc &DL,
bool AllowSideEffects) const {
unsigned Opc = Subtarget.isThumb2() ? ARM::t2MOVi32imm : ARM::MOVi32imm;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should floating-point registers also be covered by this method?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, do we care about Thumb1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should floating-point registers also be covered by this method?

Yes. I forgot about them. :-(

Also, do we care about Thumb1?

I can change this to isThumb(), but I want to avoid using tMOVi32imm, because it modifies CPSR (I want to avoid side effects even if AllowSideEffects is true).

Copy link
Member

Choose a reason for hiding this comment

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

(I want to avoid side effects even if AllowSideEffects is true).

huh? Why?

I suspect you'll need to check:
if arm:
...
elif thumb2:
...
else: # is thumb1
...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Avoiding side effects should always be desirable / safe. The only reason to allow them is if an alternative instruction (e.g. xor on x86) is smaller or more efficient or whatever. In the case of ARM / AArch64, the size of the instruction doesn't matter of course. However, ARM does produce code like this when exiting the function with stack protectors:

	cmp	r1, r0
	addeq	sp, sp, #8
	addeq	sp, sp, #1024
	popeq	{r11, pc}

So shoving a side-effect after the cmp instruction won't be good. Yes, I will have AllowSideEffects == false in that case, but I don't see why we would allow side-effects at all unless it's clearly a win.

After looking at the documentation, it does appear that the Thumb1 version of MOV Rn, #imm won't modify the condition flags, unless we specify it to. I'll make that change.

Copy link
Member

@nickdesaulniers nickdesaulniers left a comment

Choose a reason for hiding this comment

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

If your intent is to next call this override from ARMFrameLowering, I think it would be best to include that change in this PR. As is, the lack of unit tests is ...

MachineBasicBlock::iterator Iter,
DebugLoc &DL,
bool AllowSideEffects) const {
unsigned Opc = Subtarget.isThumb2() ? ARM::t2MOVi32imm : ARM::MOVi32imm;
Copy link
Member

Choose a reason for hiding this comment

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

(I want to avoid side effects even if AllowSideEffects is true).

huh? Why?

I suspect you'll need to check:
if arm:
...
elif thumb2:
...
else: # is thumb1
...

@bwendling
Copy link
Collaborator Author

If you'd like, I could wait for the full "clear stack protector register" patch and submit this with it...

@bwendling
Copy link
Collaborator Author

@nickdesaulniers Thanks for the approval, but I've decided that I'll submit this with the other code I'm writing. That way I'll have testcases. :-)

@bwendling bwendling closed this Oct 25, 2023
@bwendling bwendling deleted the arm-clear-regs branch November 3, 2023 23:20
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.

None yet

5 participants