Skip to content

Commit

Permalink
[Reland][clang][AArch64] Avoid a crash when a non-reserved register i…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
igorkudrin committed Dec 7, 2024
1 parent 60380cd commit afa2fbf
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 19 deletions.
19 changes: 14 additions & 5 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +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")) {
if (RegName == "sp") {
HasSizeMismatch = RegSize != 64;
return true;
} else if (RegName.starts_with("w")) {
HasSizeMismatch = RegSize != 32;
return true;
}
return false;
if (RegName.starts_with("w"))
HasSizeMismatch = RegSize != 32;
else if (RegName.starts_with("x"))
HasSizeMismatch = RegSize != 64;
else
return false;
StringRef RegNum = RegName.drop_front();
// Check if the register is reserved. See also
// AArch64TargetLowering::getRegisterByName().
return RegNum == "0" ||
(RegNum == "18" &&
llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str());
}

bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CodeGen/AArch64/fixed-register-global.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// Check that -ffixed register handled for globals.
/// Regression test for #76426, #109778
// REQUIRES: aarch64-registered-target

// RUN: %clang -c --target=aarch64-none-gnu -ffixed-x15 %s 2>&1 | count 0

// RUN: not %clang -c --target=aarch64-none-gnu %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR_INVREG
// ERR_INVREG: error: register 'x15' unsuitable for global register variables on this target

// RUN: not %clang -c --target=aarch64-none-gnu -ffixed-x15 -DTYPE=short %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR_SIZE
// ERR_SIZE: error: size of register 'x15' does not match variable size

#ifndef TYPE
#define TYPE long
#endif

register TYPE x15 __asm__("x15");

TYPE foo() {
return x15;
}
12 changes: 0 additions & 12 deletions clang/test/Driver/aarch64-fixed-register-global.c

This file was deleted.

13 changes: 11 additions & 2 deletions clang/test/Sema/aarch64-fixed-global-register.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
// 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 -verify=no_x18 -fsyntax-only
// RUN: %clang_cc1 -triple aarch64-unknown-android %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -fsyntax-only

register int w0 __asm__ ("w0");
register long x0 __asm__ ("x0");
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 long l2 __asm__ ("w15"); // expected-error {{size of register 'w15' does not match variable size}}
register int w3 __asm__ ("w3"); // expected-error {{register 'w3' unsuitable for global register variables on this target}}
register long x3 __asm__ ("x3"); // expected-error {{register 'x3' unsuitable for global register variables on this target}}
register int w4 __asm__ ("w4");
register long x4 __asm__ ("x4");
register int w18 __asm__ ("w18"); // no_x18-error {{register 'w18' unsuitable for global register variables on this target}}
register long x18 __asm__ ("x18"); // no_x18-error {{register 'x18' unsuitable for global register variables on this target}}

0 comments on commit afa2fbf

Please sign in to comment.