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

Merged

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks! Since this patch is focused on fixing the crash, it doesn't seem appropriate to make AArch64TargetLowering::getRegisterByName() more restrictive here. However, I added checks for w?? registers in AArch64TargetInfo::validateGlobalRegisterVariable() and corresponding tests.

Copy link
Member

@kawashima-fj kawashima-fj left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@igorkudrin igorkudrin merged commit 8fc6fca into llvm:main Dec 6, 2024
7 checks passed
@igorkudrin igorkudrin deleted the fix-clang-crash-aarch64-non-reserved-register branch December 6, 2024 22:58
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 6, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-ubuntu-fast running on sie-linux-worker while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/13353

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang :: CodeGen/AArch64/fixed-register-global.c' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 4: /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang -c --target=aarch64-none-gnu -ffixed-x15 /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/AArch64/fixed-register-global.c 2>&1 | /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/count 0
+ /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang -c --target=aarch64-none-gnu -ffixed-x15 /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/AArch64/fixed-register-global.c
+ /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/count 0
Expected 0 lines, got 2.

--

********************


igorkudrin added a commit that referenced this pull request Dec 6, 2024
igorkudrin added a commit that referenced this pull request Dec 7, 2024
…s used (#117419)

Relanding the patch with a fix for a test failure on build bots that do
not build LLVM for AArch64.

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.
broxigarchen pushed a commit to broxigarchen/llvm-project that referenced this pull request Dec 10, 2024
…lvm#117419)

Fixes llvm#76426, llvm#109778 (for AArch64)

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 reserved.
broxigarchen pushed a commit to broxigarchen/llvm-project that referenced this pull request Dec 10, 2024
broxigarchen pushed a commit to broxigarchen/llvm-project that referenced this pull request Dec 10, 2024
…s used (llvm#117419)

Relanding the patch with a fix for a test failure on build bots that do
not build LLVM for AArch64.

Fixes llvm#76426, llvm#109778 (for AArch64)

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 reserved.
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
6 participants