[llvm] 739b69e - [LLVM][AArch64] Explain that X19 is used as the frame base pointer register

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 12 02:18:19 PDT 2022


Author: David Spickett
Date: 2022-09-12T09:18:09Z
New Revision: 739b69e655fe66674982cffc8b8166306355e7d3

URL: https://github.com/llvm/llvm-project/commit/739b69e655fe66674982cffc8b8166306355e7d3
DIFF: https://github.com/llvm/llvm-project/commit/739b69e655fe66674982cffc8b8166306355e7d3.diff

LOG: [LLVM][AArch64] Explain that X19 is used as the frame base pointer register

Fixes #50098

LLVM uses X19 as the frame base pointer, if it needs to. Meaning you
can get warnings if you clobber that with inline asm.

However, it doesn't explain why. The frame base register is not part
of the ABI so it's pretty confusing why you get that warning out of the blue.

This adds a method to explain a reserved register with X19 as the first one.
The logic is the same as getReservedRegs.

I could have added a return parameter to isASMClobberable and friends
but found that there's a lot of things that call isReservedReg in various
ways.

So while one more method on the pile isn't great design, it is simpler
right now to do it this way and only pay the cost if you are actually using
a reserved register.

Reviewed By: lenary

Differential Revision: https://reviews.llvm.org/D133213

Added: 
    llvm/test/CodeGen/AArch64/inline-asm-clobber-base-frame-pointer.ll

Modified: 
    llvm/include/llvm/CodeGen/TargetRegisterInfo.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
    llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
    llvm/lib/Target/AArch64/AArch64RegisterInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 04369a5bfe0d5..ab3ec53909b39 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -16,6 +16,7 @@
 #define LLVM_CODEGEN_TARGETREGISTERINFO_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator_range.h"
@@ -523,6 +524,16 @@ class TargetRegisterInfo : public MCRegisterInfo {
   /// markSuperRegs() and checkAllSuperRegsMarked() in this case.
   virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
 
+  /// Returns either a string explaining why the given register is reserved for
+  /// this function, or an empty optional if no explanation has been written.
+  /// The absence of an explanation does not mean that the register is not
+  /// reserved (meaning, you should check that PhysReg is in fact reserved
+  /// before calling this).
+  virtual llvm::Optional<std::string>
+  explainReservedReg(const MachineFunction &MF, MCRegister PhysReg) const {
+    return {};
+  }
+
   /// Returns false if we can't guarantee that Physreg, specified as an IR asm
   /// clobber constraint, will be preserved across the statement.
   virtual bool isAsmClobberable(const MachineFunction &MF,

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 57c7a0d2ba53b..842948008f59d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -411,6 +411,14 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
         LocCookie, Msg, DiagnosticSeverity::DS_Warning));
     MMI->getModule()->getContext().diagnose(
         DiagnosticInfoInlineAsm(LocCookie, Note, DiagnosticSeverity::DS_Note));
+
+    for (const Register RR : RestrRegs) {
+      if (llvm::Optional<std::string> reason =
+              TRI->explainReservedReg(*MF, RR)) {
+        MMI->getModule()->getContext().diagnose(DiagnosticInfoInlineAsm(
+            LocCookie, *reason, DiagnosticSeverity::DS_Note));
+      }
+    }
   }
 
   emitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index c50471b61738c..209e7670f93be 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -308,6 +308,16 @@ const uint32_t *AArch64RegisterInfo::getWindowsStackProbePreservedMask() const {
   return CSR_AArch64_StackProbe_Windows_RegMask;
 }
 
+llvm::Optional<std::string>
+AArch64RegisterInfo::explainReservedReg(const MachineFunction &MF,
+                                        MCRegister PhysReg) const {
+  if (hasBasePointer(MF) &&
+      (PhysReg == AArch64::X19 || PhysReg == AArch64::W19))
+    return std::string("X19 is used as the frame base pointer register.");
+
+  return {};
+}
+
 BitVector
 AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
   const AArch64FrameLowering *TFI = getFrameLowering(MF);

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
index 9c27c34369282..3ec4a5d8cb351 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -91,6 +91,9 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
 
   BitVector getStrictlyReservedRegs(const MachineFunction &MF) const;
   BitVector getReservedRegs(const MachineFunction &MF) const override;
+  llvm::Optional<std::string>
+  explainReservedReg(const MachineFunction &MF,
+                     MCRegister PhysReg) const override;
   bool isAsmClobberable(const MachineFunction &MF,
                        MCRegister PhysReg) const override;
   const TargetRegisterClass *

diff  --git a/llvm/test/CodeGen/AArch64/inline-asm-clobber-base-frame-pointer.ll b/llvm/test/CodeGen/AArch64/inline-asm-clobber-base-frame-pointer.ll
new file mode 100644
index 0000000000000..9d2e55deb7e5e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/inline-asm-clobber-base-frame-pointer.ll
@@ -0,0 +1,15 @@
+; Check that not only do we warn about clobbering x19 we also say
+; what it is used for.
+
+; RUN: llc <%s -mtriple=aarch64-none-eabi 2>&1 | FileCheck %s
+
+; CHECK: warning: inline asm clobber list contains reserved registers: X19
+; CHECK: note: X19 is used as the frame base pointer register.
+
+define void @alloca(i64 %size) {
+entry:
+  %a = alloca i128, i64 %size, align 64
+  call void asm sideeffect "nop", "~{x19}"()
+  ret void
+}
+


        


More information about the llvm-commits mailing list