[llvm] SafeStack: Respect alloca addrspace (PR #112536)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 25 17:13:57 PDT 2024


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/112536

>From 1288feeade12374c9498d75a6ed7d5c25adc196a Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 16 Oct 2024 16:42:28 +0400
Subject: [PATCH 1/3] SafeStack: Respect alloca addrspace

Just insert addrspacecast in cases where the alloca uses a
different address space, since I don't know what else you
could possibly do.
---
 llvm/lib/CodeGen/SafeStack.cpp                |  5 ++--
 llvm/lib/CodeGen/TargetLoweringBase.cpp       |  5 +++-
 .../SafeStack/X86/alloca-addrspace.ll         | 27 +++++++++++++++++++
 3 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/Transforms/SafeStack/X86/alloca-addrspace.ll

diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index ad2037a2c20b55..fd48bc1aa7ac06 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -192,7 +192,7 @@ class SafeStack {
   SafeStack(Function &F, const TargetLoweringBase &TL, const DataLayout &DL,
             DomTreeUpdater *DTU, ScalarEvolution &SE)
       : F(F), TL(TL), DL(DL), DTU(DTU), SE(SE),
-        StackPtrTy(PointerType::getUnqual(F.getContext())),
+        StackPtrTy(DL.getAllocaPtrType(F.getContext())),
         IntPtrTy(DL.getIntPtrType(F.getContext())),
         Int32Ty(Type::getInt32Ty(F.getContext())) {}
 
@@ -616,7 +616,8 @@ Value *SafeStack::moveStaticAllocasToUnsafeStack(
       IRBuilder<> IRBUser(InsertBefore);
       Value *Off =
           IRBUser.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -Offset));
-      Value *Replacement = IRBUser.CreateBitCast(Off, AI->getType(), Name);
+      Value *Replacement =
+          IRBUser.CreateAddrSpaceCast(Off, AI->getType(), Name);
 
       if (auto *PHI = dyn_cast<PHINode>(User))
         // PHI nodes may have multiple incoming edges from the same BB (why??),
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 7a28f7892cbf31..0d4ea0dbeb64c4 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1849,7 +1849,8 @@ TargetLoweringBase::getDefaultSafeStackPointerLocation(IRBuilderBase &IRB,
   auto UnsafeStackPtr =
       dyn_cast_or_null<GlobalVariable>(M->getNamedValue(UnsafeStackPtrVar));
 
-  Type *StackPtrTy = PointerType::getUnqual(M->getContext());
+  const DataLayout &DL = M->getDataLayout();
+  PointerType *StackPtrTy = DL.getAllocaPtrType(M->getContext());
 
   if (!UnsafeStackPtr) {
     auto TLSModel = UseTLS ?
@@ -1863,6 +1864,8 @@ TargetLoweringBase::getDefaultSafeStackPointerLocation(IRBuilderBase &IRB,
         UnsafeStackPtrVar, nullptr, TLSModel);
   } else {
     // The variable exists, check its type and attributes.
+    //
+    // FIXME: Move to IR verifier.
     if (UnsafeStackPtr->getValueType() != StackPtrTy)
       report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type");
     if (UseTLS != UnsafeStackPtr->isThreadLocal())
diff --git a/llvm/test/Transforms/SafeStack/X86/alloca-addrspace.ll b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace.ll
new file mode 100644
index 00000000000000..efd6c64246102c
--- /dev/null
+++ b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=safe-stack -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s --check-prefix=TLS
+
+target datalayout = "A5"
+
+define void @correct_alloca_addrspace() nounwind uwtable safestack {
+; TLS-LABEL: define void @correct_alloca_addrspace(
+; TLS-SAME: ) #[[ATTR0:[0-9]+]] !annotation [[META0:![0-9]+]] {
+; TLS-NEXT:  [[ENTRY:.*:]]
+; TLS-NEXT:    [[UNSAFE_STACK_PTR:%.*]] = load ptr addrspace(5), ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    [[UNSAFE_STACK_STATIC_TOP:%.*]] = getelementptr i8, ptr addrspace(5) [[UNSAFE_STACK_PTR]], i32 -16
+; TLS-NEXT:    store ptr addrspace(5) [[UNSAFE_STACK_STATIC_TOP]], ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr addrspace(5) [[UNSAFE_STACK_PTR]], i32 -8
+; TLS-NEXT:    call void @Capture_as5(ptr addrspace(5) [[TMP0]])
+; TLS-NEXT:    store ptr addrspace(5) [[UNSAFE_STACK_PTR]], ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    ret void
+;
+entry:
+  %a = alloca i8, align 8, addrspace(5)
+  call void @Capture_as5(ptr addrspace(5) %a)
+  ret void
+}
+
+declare void @Capture_as5(ptr addrspace(5))
+;.
+; TLS: [[META0]] = !{!"unsafe-stack-size", i32 16}
+;.

>From 5a513a1d6a89448d8bf6c92f80c8d523454214b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 25 Oct 2024 17:08:25 -0700
Subject: [PATCH 2/3] Add test for wrong declaration type for
 __safestack_unsafe_stack_ptr

---
 .../alloca-addrspace-wrong-addrspace-error.ll   | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace-error.ll

diff --git a/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace-error.ll b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace-error.ll
new file mode 100644
index 00000000000000..2a9b242d04aad9
--- /dev/null
+++ b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace-error.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: not --crash opt -passes=safe-stack -mtriple=x86_64-pc-linux-gnu -disable-output %s 2>&1 | FileCheck %s
+
+target datalayout = "A5"
+
+; Declaration of __safestack_unsafe_stack_ptr already exists with wrong address space
+ at __safestack_unsafe_stack_ptr = external thread_local(initialexec) global ptr
+
+; CHECK: LLVM ERROR: __safestack_unsafe_stack_ptr must have void* type
+
+define void @alloca_addrspace() nounwind uwtable safestack {
+  %a = alloca i8, align 8, addrspace(5)
+  call void @Capture_as5(ptr addrspace(5) %a)
+  ret void
+}
+
+declare void @Capture_as5(ptr addrspace(5))

>From 7b14ed4dc701e56e3c9c75a8caa1bcb69c888073 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 25 Oct 2024 17:13:24 -0700
Subject: [PATCH 3/3] Add test where cast is inserted

---
 .../X86/alloca-addrspace-wrong-addrspace.ll   | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace.ll

diff --git a/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace.ll b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace.ll
new file mode 100644
index 00000000000000..4f780fa9695ff7
--- /dev/null
+++ b/llvm/test/Transforms/SafeStack/X86/alloca-addrspace-wrong-addrspace.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=safe-stack -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s --check-prefix=TLS
+
+target datalayout = "A5"
+
+; Use has wrong address space for the alloca, addrspacecast is inserted.
+define void @correct_alloca_addrspace() nounwind uwtable safestack {
+; TLS-LABEL: define void @correct_alloca_addrspace(
+; TLS-SAME: ) #[[ATTR0:[0-9]+]] !annotation [[META0:![0-9]+]] {
+; TLS-NEXT:  [[ENTRY:.*:]]
+; TLS-NEXT:    [[UNSAFE_STACK_PTR:%.*]] = load ptr addrspace(5), ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    [[UNSAFE_STACK_STATIC_TOP:%.*]] = getelementptr i8, ptr addrspace(5) [[UNSAFE_STACK_PTR]], i32 -16
+; TLS-NEXT:    store ptr addrspace(5) [[UNSAFE_STACK_STATIC_TOP]], ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr addrspace(5) [[UNSAFE_STACK_PTR]], i32 -8
+; TLS-NEXT:    [[A_UNSAFE:%.*]] = addrspacecast ptr addrspace(5) [[TMP0]] to ptr
+; TLS-NEXT:    call void @Capture(ptr [[A_UNSAFE]])
+; TLS-NEXT:    store ptr addrspace(5) [[UNSAFE_STACK_PTR]], ptr @__safestack_unsafe_stack_ptr, align 8
+; TLS-NEXT:    ret void
+;
+entry:
+  %a = alloca i8, align 8
+  call void @Capture(ptr %a)
+  ret void
+}
+
+declare void @Capture(ptr)
+;.
+; TLS: [[META0]] = !{!"unsafe-stack-size", i32 16}
+;.



More information about the llvm-commits mailing list