[llvm] clang crash assigning to a global named register variable #109778 (PR #113105)

Akshay Kumar via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 9 13:27:05 PST 2024


https://github.com/akshaykumars614 updated https://github.com/llvm/llvm-project/pull/113105

>From ecbf43e8e73c31d4a2730e685b410bc507d0815d Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Sun, 20 Oct 2024 16:54:10 -0400
Subject: [PATCH 1/7] clang crash assigning to a global named register variable
 #109778

fixed crash
---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 7448416c682abc..98703d8368813a 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11522,8 +11522,8 @@ getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const
   if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
     const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
     unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
-    if (!Subtarget->isXRegisterReserved(DwarfRegNum) &&
-        !MRI->isReservedReg(MF, Reg))
+    if (Subtarget->isXRegisterReserved(DwarfRegNum) ||
+        MRI->isReservedReg(MF, Reg))
       Reg = 0;
   }
   if (Reg)

>From b8cd6f224348650f88d9ac59113444a96cfd70ce Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Thu, 31 Oct 2024 19:27:28 -0400
Subject: [PATCH 2/7] fixes #109778

checks whether the register in question is reserved at either the subtarget level or the machine function level.
Modified the existing testcase for correct functionality.
---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp    | 1 +
 llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll | 3 ++-
 llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 98703d8368813a..b981f2d58977f3 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11522,6 +11522,7 @@ getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const
   if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
     const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
     unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
+// check if X Register is reserved.
     if (Subtarget->isXRegisterReserved(DwarfRegNum) ||
         MRI->isReservedReg(MF, Reg))
       Reg = 0;
diff --git a/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll b/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
index 9074f2c108af33..8f639943ea92b6 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
@@ -1,8 +1,9 @@
-; RUN: llc -mtriple=aarch64-fuchsia -o - %s
+; RUN: not --crash llc < %s -mtriple=aarch64-fuchsia 2>&1 | FileCheck %s
 
 define void @set_x18(i64 %x) {
 entry:
 ; FIXME: Include an allocatable-specific error message
+; CHECK: Invalid register name "x18".
   tail call void @llvm.write_register.i64(metadata !0, i64 %x)
   ret void
 }
diff --git a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
index bd14ec61b55cc4..f2b38aba655361 100644
--- a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
@@ -4,7 +4,7 @@
 define i32 @get_stack() nounwind {
 entry:
 ; FIXME: Include an allocatable-specific error message
-; CHECK: Invalid register name "x5".
+; CHECK: Couldn't find the register class
 	%sp = call i32 @llvm.read_register.i32(metadata !0)
   ret i32 %sp
 }

>From 24822dcb4ce91bb87ab00bd1fdf0564c91f7c791 Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Thu, 31 Oct 2024 19:43:07 -0400
Subject: [PATCH 3/7] fixes 109778

corrected the format
---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b981f2d58977f3..8696ffe14e81fe 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11522,7 +11522,8 @@ getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const
   if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
     const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
     unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
-// check if X Register is reserved.
+// check if X Register is reserved at either subtarget level or the 
+// machine function level.
     if (Subtarget->isXRegisterReserved(DwarfRegNum) ||
         MRI->isReservedReg(MF, Reg))
       Reg = 0;

>From 649917640c5c155fdb536be6843211afb111ac97 Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Thu, 31 Oct 2024 19:44:50 -0400
Subject: [PATCH 4/7] corrected the format. fixes 109778

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 8696ffe14e81fe..0c54ab17d816ce 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11522,8 +11522,8 @@ getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const
   if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
     const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
     unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
-// check if X Register is reserved at either subtarget level or the 
-// machine function level.
+    // check if X Register is reserved at either subtarget level or the
+    // machine function level.
     if (Subtarget->isXRegisterReserved(DwarfRegNum) ||
         MRI->isReservedReg(MF, Reg))
       Reg = 0;

>From 8446c63d240b3a3a5ded1f9533285927881b0447 Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Sat, 9 Nov 2024 12:15:41 -0500
Subject: [PATCH 5/7] fixes #109778

designed nicer error reporting for selecting global named register variable.
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 25 ++++++++-----------
 llvm/lib/Target/AArch64/AArch64Subtarget.h    |  6 +++++
 .../CodeGen/AArch64/arm64-named-reg-alloc.ll  |  4 +++
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 0c54ab17d816ce..a042e02e1fedb0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11518,20 +11518,17 @@ SDValue AArch64TargetLowering::LowerSPONENTRY(SDValue Op,
 // this table could be generated automatically from RegInfo.
 Register AArch64TargetLowering::
 getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const {
-  Register Reg = MatchRegisterName(RegName);
-  if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
-    const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
-    unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
-    // check if X Register is reserved at either subtarget level or the
-    // machine function level.
-    if (Subtarget->isXRegisterReserved(DwarfRegNum) ||
-        MRI->isReservedReg(MF, Reg))
-      Reg = 0;
-  }
-  if (Reg)
-    return Reg;
-  report_fatal_error(Twine("Invalid register name \""
-                              + StringRef(RegName)  + "\"."));
+  Register Reg = MatchRegisterAltName(RegName);
+  if (Reg == AArch64::NoRegister)
+    Reg = MatchRegisterName(RegName);
+  if (Reg == AArch64::NoRegister)
+    report_fatal_error(
+        Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
+  BitVector ReservedRegs = Subtarget->getRegisterInfo()->getReservedRegs(MF);
+  if (!ReservedRegs.test(Reg) && !Subtarget->isRegisterReservedByUser(Reg))
+    report_fatal_error(Twine("Trying to obtain non-reserved register \"" +
+                             StringRef(RegName) + "\"."));
+  return Reg;
 }
 
 SDValue AArch64TargetLowering::LowerADDROFRETURNADDR(SDValue Op,
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 9856415361e50d..f9f43b0464a765 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -71,6 +71,8 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
   unsigned MinimumJumpTableEntries = 4;
   unsigned MaxJumpTableSize = 0;
 
+  std::bitset<AArch64::NUM_TARGET_REGS> UserReservedRegister;
+
   // ReserveXRegister[i] - X#i is not available as a general purpose register.
   BitVector ReserveXRegister;
 
@@ -208,6 +210,10 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
     return MinVectorRegisterBitWidth;
   }
 
+  bool isRegisterReservedByUser(Register i) const {
+    assert(i < AArch64::NUM_TARGET_REGS && "Register out of range");
+    return UserReservedRegister[i];
+  }
   bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
   bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
   unsigned getNumXRegisterReserved() const {
diff --git a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
index f2b38aba655361..709a2f538e2b5f 100644
--- a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
@@ -4,7 +4,11 @@
 define i32 @get_stack() nounwind {
 entry:
 ; FIXME: Include an allocatable-specific error message
+<<<<<<< Updated upstream
 ; CHECK: Couldn't find the register class
+=======
+; CHECK: Trying to obtain non-reserved register "x5".
+>>>>>>> Stashed changes
 	%sp = call i32 @llvm.read_register.i32(metadata !0)
   ret i32 %sp
 }

>From 8e5983954fe22eb259e027f0e9e029b3b5f7bb8d Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Sat, 9 Nov 2024 14:11:38 -0500
Subject: [PATCH 6/7] fixes #109778

modified code for build failure
---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index a042e02e1fedb0..829fe2202bfd06 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11518,9 +11518,7 @@ SDValue AArch64TargetLowering::LowerSPONENTRY(SDValue Op,
 // this table could be generated automatically from RegInfo.
 Register AArch64TargetLowering::
 getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const {
-  Register Reg = MatchRegisterAltName(RegName);
-  if (Reg == AArch64::NoRegister)
-    Reg = MatchRegisterName(RegName);
+  Register Reg = MatchRegisterName(RegName);
   if (Reg == AArch64::NoRegister)
     report_fatal_error(
         Twine("Invalid register name \"" + StringRef(RegName) + "\"."));

>From 99d202ee6ea6224b12995a8533419ae51ab49cd3 Mon Sep 17 00:00:00 2001
From: akshaykumars614 <akshaykumars614 at gmail.com>
Date: Sat, 9 Nov 2024 16:26:11 -0500
Subject: [PATCH 7/7] fixes #109778

fixed the testcase failures
---
 llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll | 3 +--
 llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll | 4 ----
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll b/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
index 8f639943ea92b6..9074f2c108af33 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-named-reg-x18.ll
@@ -1,9 +1,8 @@
-; RUN: not --crash llc < %s -mtriple=aarch64-fuchsia 2>&1 | FileCheck %s
+; RUN: llc -mtriple=aarch64-fuchsia -o - %s
 
 define void @set_x18(i64 %x) {
 entry:
 ; FIXME: Include an allocatable-specific error message
-; CHECK: Invalid register name "x18".
   tail call void @llvm.write_register.i64(metadata !0, i64 %x)
   ret void
 }
diff --git a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
index 709a2f538e2b5f..dc1a6416453f5f 100644
--- a/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-named-reg-alloc.ll
@@ -4,11 +4,7 @@
 define i32 @get_stack() nounwind {
 entry:
 ; FIXME: Include an allocatable-specific error message
-<<<<<<< Updated upstream
-; CHECK: Couldn't find the register class
-=======
 ; CHECK: Trying to obtain non-reserved register "x5".
->>>>>>> Stashed changes
 	%sp = call i32 @llvm.read_register.i32(metadata !0)
   ret i32 %sp
 }



More information about the llvm-commits mailing list