Skip to content

Commit afa2fbf

Browse files
committed
[Reland][clang][AArch64] Avoid a crash when a non-reserved register is 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.
1 parent 60380cd commit afa2fbf

File tree

4 files changed

+48
-19
lines changed

4 files changed

+48
-19
lines changed

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,23 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
232232

233233
bool AArch64TargetInfo::validateGlobalRegisterVariable(
234234
StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
235-
if ((RegName == "sp") || RegName.starts_with("x")) {
235+
if (RegName == "sp") {
236236
HasSizeMismatch = RegSize != 64;
237237
return true;
238-
} else if (RegName.starts_with("w")) {
239-
HasSizeMismatch = RegSize != 32;
240-
return true;
241238
}
242-
return false;
239+
if (RegName.starts_with("w"))
240+
HasSizeMismatch = RegSize != 32;
241+
else if (RegName.starts_with("x"))
242+
HasSizeMismatch = RegSize != 64;
243+
else
244+
return false;
245+
StringRef RegNum = RegName.drop_front();
246+
// Check if the register is reserved. See also
247+
// AArch64TargetLowering::getRegisterByName().
248+
return RegNum == "0" ||
249+
(RegNum == "18" &&
250+
llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
251+
getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str());
243252
}
244253

245254
bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/// Check that -ffixed register handled for globals.
2+
/// Regression test for #76426, #109778
3+
// REQUIRES: aarch64-registered-target
4+
5+
// RUN: %clang -c --target=aarch64-none-gnu -ffixed-x15 %s 2>&1 | count 0
6+
7+
// RUN: not %clang -c --target=aarch64-none-gnu %s 2>&1 | \
8+
// RUN: FileCheck %s --check-prefix=ERR_INVREG
9+
// ERR_INVREG: error: register 'x15' unsuitable for global register variables on this target
10+
11+
// RUN: not %clang -c --target=aarch64-none-gnu -ffixed-x15 -DTYPE=short %s 2>&1 | \
12+
// RUN: FileCheck %s --check-prefix=ERR_SIZE
13+
// ERR_SIZE: error: size of register 'x15' does not match variable size
14+
15+
#ifndef TYPE
16+
#define TYPE long
17+
#endif
18+
19+
register TYPE x15 __asm__("x15");
20+
21+
TYPE foo() {
22+
return x15;
23+
}

clang/test/Driver/aarch64-fixed-register-global.c

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -verify -fsyntax-only
1+
// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -verify=no_x18 -fsyntax-only
2+
// RUN: %clang_cc1 -triple aarch64-unknown-android %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -fsyntax-only
23

4+
register int w0 __asm__ ("w0");
5+
register long x0 __asm__ ("x0");
36
register char i1 __asm__ ("x15"); // expected-error {{size of register 'x15' does not match variable size}}
4-
register long long l2 __asm__ ("w14"); // expected-error {{size of register 'w14' does not match variable size}}
7+
register long long l2 __asm__ ("w15"); // expected-error {{size of register 'w15' does not match variable size}}
8+
register int w3 __asm__ ("w3"); // expected-error {{register 'w3' unsuitable for global register variables on this target}}
9+
register long x3 __asm__ ("x3"); // expected-error {{register 'x3' unsuitable for global register variables on this target}}
10+
register int w4 __asm__ ("w4");
11+
register long x4 __asm__ ("x4");
12+
register int w18 __asm__ ("w18"); // no_x18-error {{register 'w18' unsuitable for global register variables on this target}}
13+
register long x18 __asm__ ("x18"); // no_x18-error {{register 'x18' unsuitable for global register variables on this target}}

0 commit comments

Comments
 (0)