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

[clang][AArch64] Avoid a crash when a non-reserved register is used #117419

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

igorkudrin
Copy link
Collaborator

@igorkudrin igorkudrin commented Nov 23, 2024

Fixes #76426, #109778 (for AArch64)

The previous patch for this issue, #94271, generated an error message if a register and a global variable did not have the same size. This patch checks if the register is reserved.

Fixes llvm#76426

The previous patch for this issue, llvm#94271, generated an error message if
a register and a global variable did not have the same size. This patch
checks if the register is actually reserved.
@igorkudrin igorkudrin added backend:AArch64 clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 23, 2024
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Nov 23, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 23, 2024

@llvm/pr-subscribers-clang-driver
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-clang

Author: Igor Kudrin (igorkudrin)

Changes

Fixes #76426

The previous patch for this issue, #94271, generated an error message if a register and a global variable did not have the same size. This patch checks if the register is actually reserved.


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

2 Files Affected:

  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+14-4)
  • (modified) clang/test/Sema/aarch64-fixed-global-register.c (+3-1)
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index eb8a3ada034482..7500c7bb045e54 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -232,13 +232,23 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
 
 bool AArch64TargetInfo::validateGlobalRegisterVariable(
     StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
-  if ((RegName == "sp") || RegName.starts_with("x")) {
-    HasSizeMismatch = RegSize != 64;
-    return true;
-  } else if (RegName.starts_with("w")) {
+  if (RegName.starts_with("w")) {
     HasSizeMismatch = RegSize != 32;
     return true;
   }
+  if (RegName == "sp") {
+    HasSizeMismatch = RegSize != 64;
+    return true;
+  }
+  if (RegName.starts_with("x")) {
+    HasSizeMismatch = RegSize != 64;
+    // Check if the register is reserved. See also
+    // AArch64TargetLowering::getRegisterByName().
+    return RegName == "x0" ||
+           (RegName == "x18" &&
+            llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
+           getTargetOpts().FeatureMap.lookup(("reserve-" + RegName).str());
+  }
   return false;
 }
 
diff --git a/clang/test/Sema/aarch64-fixed-global-register.c b/clang/test/Sema/aarch64-fixed-global-register.c
index 9b4a422d8c1b2c..2b7d39dbcdd6f8 100644
--- a/clang/test/Sema/aarch64-fixed-global-register.c
+++ b/clang/test/Sema/aarch64-fixed-global-register.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -verify -fsyntax-only
+// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -fsyntax-only
 
 register char i1 __asm__ ("x15"); // expected-error {{size of register 'x15' does not match variable size}}
 register long long l2 __asm__ ("w14"); // expected-error {{size of register 'w14' does not match variable size}}
+register long x3 __asm__ ("x3"); // expected-error {{register 'x3' unsuitable for global register variables on this target}}
+register long x4 __asm__ ("x4");

@DavidSpickett
Copy link
Collaborator

Please check if this fixes #109778 too. Seems very similar.

@llvmbot llvmbot added the clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' label Nov 26, 2024
@igorkudrin
Copy link
Collaborator Author

Please check if this fixes #109778 too. Seems very similar.

This patch fixes #109778, but only for AArch64.

@DavidSpickett
Copy link
Collaborator

Thanks, I'll leave it open then, this PR is a welcome improvement regardless.

return RegName == "x0" ||
(RegName == "x18" &&
llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
getTargetOpts().FeatureMap.lookup(("reserve-" + RegName).str());
Copy link
Member

Choose a reason for hiding this comment

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

To avoid the fatal error: error in backend: Invalid register name "x??" error in #109778, this check is sufficient.

I think the original purpose of rejecting a global register variable associated with a non-reserved register is to avoid unintended register use. w?? registers are lower half bits of the corresponding x?? registers. So when x?? register is not reserved, should we reject a global register variable associated with the corresponding w???

For this purpose, maybe the backend should also check w?? registers. Actually, old backend code checked w?? regsters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[AArch64] Crash when compiling global register variable __asm__("x15") without -ffixed-x15
5 participants