[llvm] 9f51f1b - [ASAN][AMDGPU] Add support for accesses to global and constant addrspaces

Reshabh Sharma via llvm-commits llvm-commits at lists.llvm.org
Sun May 2 20:36:10 PDT 2021


Author: Reshabh Sharma
Date: 2021-05-03T09:01:15+05:30
New Revision: 9f51f1b927b15dae4f4226c379c7abd13cd5de2f

URL: https://github.com/llvm/llvm-project/commit/9f51f1b927b15dae4f4226c379c7abd13cd5de2f
DIFF: https://github.com/llvm/llvm-project/commit/9f51f1b927b15dae4f4226c379c7abd13cd5de2f.diff

LOG: [ASAN][AMDGPU] Add support for accesses to global and constant addrspaces

Add address sanitizer instrumentation support for accesses to global
and constant address spaces in AMDGPU. It strictly avoids instrumenting
the stack and assumes x86 as the host.

Reviewed by: vitalybuka

Differential Revision: https://reviews.llvm.org/D99071

Added: 
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_constant_global_redzones.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_global_redzones.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_lds.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_scratch.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_constant_address_space.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_generic_address_space.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_global_address_space.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/global_metadata_addrspacecasts.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/instrument-stack.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_lds_globals.ll
    llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_scratch_globals.ll

Modified: 
    llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 1b327f651badc..365b03bf4699e 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -174,6 +174,9 @@ const char kAsanShadowMemoryDynamicAddress[] =
 const char kAsanAllocaPoison[] = "__asan_alloca_poison";
 const char kAsanAllocasUnpoison[] = "__asan_allocas_unpoison";
 
+const char kAMDGPUAddressSharedName[] = "llvm.amdgcn.is.shared";
+const char kAMDGPUAddressPrivateName[] = "llvm.amdgcn.is.private";
+
 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
 static const size_t kNumberOfAccessSizes = 5;
 
@@ -455,6 +458,11 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
   bool IsFuchsia = TargetTriple.isOSFuchsia();
   bool IsMyriad = TargetTriple.getVendor() == llvm::Triple::Myriad;
   bool IsEmscripten = TargetTriple.isOSEmscripten();
+  bool IsAMDGPU = TargetTriple.isAMDGPU();
+
+  // Asan support for AMDGPU assumes X86 as the host right now.
+  if (IsAMDGPU)
+    IsX86_64 = true;
 
   ShadowMapping Mapping;
 
@@ -643,6 +651,10 @@ struct AddressSanitizer {
   void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
                          Value *Addr, uint32_t TypeSize, bool IsWrite,
                          Value *SizeArgument, bool UseCalls, uint32_t Exp);
+  Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
+                                       Instruction *InsertBefore, Value *Addr,
+                                       uint32_t TypeSize, bool IsWrite,
+                                       Value *SizeArgument);
   void instrumentUnusualSizeOrAlignment(Instruction *I,
                                         Instruction *InsertBefore, Value *Addr,
                                         uint32_t TypeSize, bool IsWrite,
@@ -711,6 +723,9 @@ struct AddressSanitizer {
   Value *LocalDynamicShadow = nullptr;
   const GlobalsMetadata &GlobalsMD;
   DenseMap<const AllocaInst *, bool> ProcessedAllocas;
+
+  FunctionCallee AMDGPUAddressShared;
+  FunctionCallee AMDGPUAddressPrivate;
 };
 
 class AddressSanitizerLegacyPass : public FunctionPass {
@@ -933,15 +948,19 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
 
   bool HasInlineAsm = false;
   bool HasReturnsTwiceCall = false;
+  bool PoisonStack;
 
   FunctionStackPoisoner(Function &F, AddressSanitizer &ASan)
       : F(F), ASan(ASan), DIB(*F.getParent(), /*AllowUnresolved*/ false),
         C(ASan.C), IntptrTy(ASan.IntptrTy),
         IntptrPtrTy(PointerType::get(IntptrTy, 0)), Mapping(ASan.Mapping),
-        StackAlignment(1 << Mapping.Scale) {}
+        StackAlignment(1 << Mapping.Scale),
+        PoisonStack(ClStack &&
+                    !Triple(F.getParent()->getTargetTriple()).isAMDGPU()) {}
 
   bool runOnFunction() {
-    if (!ClStack) return false;
+    if (!PoisonStack)
+      return false;
 
     if (ClRedzoneByvalArgs)
       copyArgsPassedByValToAllocas();
@@ -1308,6 +1327,14 @@ static bool GlobalWasGeneratedByCompiler(GlobalVariable *G) {
   return false;
 }
 
+static bool isUnsupportedAMDGPUAddrspace(Value *Addr) {
+  Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
+  unsigned int AddrSpace = PtrTy->getPointerAddressSpace();
+  if (AddrSpace == 3 || AddrSpace == 5)
+    return true;
+  return false;
+}
+
 Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
   // Shadow >> scale
   Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
@@ -1368,10 +1395,10 @@ bool AddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
 }
 
 bool AddressSanitizer::ignoreAccess(Value *Ptr) {
-  // Do not instrument acesses from 
diff erent address spaces; we cannot deal
-  // with them.
+  // Instrument acesses from 
diff erent address spaces only for AMDGPU.
   Type *PtrTy = cast<PointerType>(Ptr->getType()->getScalarType());
-  if (PtrTy->getPointerAddressSpace() != 0)
+  if (PtrTy->getPointerAddressSpace() != 0 &&
+      !(TargetTriple.isAMDGPU() && !isUnsupportedAMDGPUAddrspace(Ptr)))
     return true;
 
   // Ignore swifterror addresses.
@@ -1665,6 +1692,29 @@ Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
   return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue);
 }
 
+Instruction *AddressSanitizer::instrumentAMDGPUAddress(
+    Instruction *OrigIns, Instruction *InsertBefore, Value *Addr,
+    uint32_t TypeSize, bool IsWrite, Value *SizeArgument) {
+  // Do not instrument unsupported addrspaces.
+  if (isUnsupportedAMDGPUAddrspace(Addr))
+    return nullptr;
+  Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
+  // Follow host instrumentation for global and constant addresses.
+  if (PtrTy->getPointerAddressSpace() != 0)
+    return InsertBefore;
+  // Instrument generic addresses in supported addressspaces.
+  IRBuilder<> IRB(InsertBefore);
+  Value *AddrLong = IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy());
+  Value *IsShared = IRB.CreateCall(AMDGPUAddressShared, {AddrLong});
+  Value *IsPrivate = IRB.CreateCall(AMDGPUAddressPrivate, {AddrLong});
+  Value *IsSharedOrPrivate = IRB.CreateOr(IsShared, IsPrivate);
+  Value *Cmp = IRB.CreateICmpNE(IRB.getTrue(), IsSharedOrPrivate);
+  Value *AddrSpaceZeroLanding =
+      SplitBlockAndInsertIfThen(Cmp, InsertBefore, false);
+  InsertBefore = cast<Instruction>(AddrSpaceZeroLanding);
+  return InsertBefore;
+}
+
 void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
                                          Instruction *InsertBefore, Value *Addr,
                                          uint32_t TypeSize, bool IsWrite,
@@ -1672,6 +1722,13 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
                                          uint32_t Exp) {
   bool IsMyriad = TargetTriple.getVendor() == llvm::Triple::Myriad;
 
+  if (TargetTriple.isAMDGPU()) {
+    InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
+                                           TypeSize, IsWrite, SizeArgument);
+    if (!InsertBefore)
+      return;
+  }
+
   IRBuilder<> IRB(InsertBefore);
   Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
   size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
@@ -1838,8 +1895,10 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
   if (GlobalsMD.get(G).IsExcluded) return false;
   if (!Ty->isSized()) return false;
   if (!G->hasInitializer()) return false;
-  // Only instrument globals of default address spaces
-  if (G->getAddressSpace()) return false;
+  // Globals in address space 1 and 4 are supported for AMDGPU.
+  if (G->getAddressSpace() &&
+      !(TargetTriple.isAMDGPU() && !isUnsupportedAMDGPUAddrspace(G)))
+    return false;
   if (GlobalWasGeneratedByCompiler(G)) return false; // Our own globals.
   // Two problems with thread-locals:
   //   - The address of the main thread's copy can't be computed at link-time.
@@ -2624,6 +2683,11 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
   if (Mapping.InGlobal)
     AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow",
                                            ArrayType::get(IRB.getInt8Ty(), 0));
+
+  AMDGPUAddressShared = M.getOrInsertFunction(
+      kAMDGPUAddressSharedName, IRB.getInt1Ty(), IRB.getInt8PtrTy());
+  AMDGPUAddressPrivate = M.getOrInsertFunction(
+      kAMDGPUAddressPrivateName, IRB.getInt1Ty(), IRB.getInt8PtrTy());
 }
 
 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_constant_global_redzones.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_constant_global_redzones.ll
new file mode 100644
index 0000000000000..312fae2758dc2
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_constant_global_redzones.ll
@@ -0,0 +1,59 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+; Here we check that the global redzone sizes grow with the object size
+; for objects in constant address space.
+
+ at G10 = addrspace(4) global [10 x i8] zeroinitializer, align 1
+; CHECK: @G10 = addrspace(4) global { [10 x i8], [54 x i8] }
+
+ at G31 = addrspace(4) global [31 x i8] zeroinitializer, align 1
+ at G32 = addrspace(4) global [32 x i8] zeroinitializer, align 1
+ at G33 = addrspace(4) global [33 x i8] zeroinitializer, align 1
+; CHECK: @G31 = addrspace(4) global { [31 x i8], [33 x i8] }
+; CHECK: @G32 = addrspace(4) global { [32 x i8], [32 x i8] }
+; CHECK: @G33 = addrspace(4) global { [33 x i8], [63 x i8] }
+
+ at G63 = addrspace(4) global [63 x i8] zeroinitializer, align 1
+ at G64 = addrspace(4) global [64 x i8] zeroinitializer, align 1
+ at G65 = addrspace(4) global [65 x i8] zeroinitializer, align 1
+; CHECK: @G63 = addrspace(4) global { [63 x i8], [33 x i8] }
+; CHECK: @G64 = addrspace(4) global { [64 x i8], [32 x i8] }
+; CHECK: @G65 = addrspace(4) global { [65 x i8], [63 x i8] }
+
+ at G127 = addrspace(4) global [127 x i8] zeroinitializer, align 1
+ at G128 = addrspace(4) global [128 x i8] zeroinitializer, align 1
+ at G129 = addrspace(4) global [129 x i8] zeroinitializer, align 1
+; CHECK: @G127 = addrspace(4) global { [127 x i8], [33 x i8] }
+; CHECK: @G128 = addrspace(4) global { [128 x i8], [32 x i8] }
+; CHECK: @G129 = addrspace(4) global { [129 x i8], [63 x i8] }
+
+ at G255 = addrspace(4) global [255 x i8] zeroinitializer, align 1
+ at G256 = addrspace(4) global [256 x i8] zeroinitializer, align 1
+ at G257 = addrspace(4) global [257 x i8] zeroinitializer, align 1
+; CHECK: @G255 = addrspace(4) global { [255 x i8], [33 x i8] }
+; CHECK: @G256 = addrspace(4) global { [256 x i8], [64 x i8] }
+; CHECK: @G257 = addrspace(4) global { [257 x i8], [95 x i8] }
+
+ at G511 = addrspace(4) global [511 x i8] zeroinitializer, align 1
+ at G512 = addrspace(4) global [512 x i8] zeroinitializer, align 1
+ at G513 = addrspace(4) global [513 x i8] zeroinitializer, align 1
+; CHECK: @G511 = addrspace(4) global { [511 x i8], [97 x i8] }
+; CHECK: @G512 = addrspace(4) global { [512 x i8], [128 x i8] }
+; CHECK: @G513 = addrspace(4) global { [513 x i8], [159 x i8] }
+
+ at G1023 = addrspace(4) global [1023 x i8] zeroinitializer, align 1
+ at G1024 = addrspace(4) global [1024 x i8] zeroinitializer, align 1
+ at G1025 = addrspace(4) global [1025 x i8] zeroinitializer, align 1
+; CHECK: @G1023 = addrspace(4) global { [1023 x i8], [225 x i8] }
+; CHECK: @G1024 = addrspace(4) global { [1024 x i8], [256 x i8] }
+; CHECK: @G1025 = addrspace(4) global { [1025 x i8], [287 x i8] }
+
+ at G1000000 = addrspace(4) global [1000000 x i8] zeroinitializer, align 1
+ at G10000000 = addrspace(4) global [10000000 x i8] zeroinitializer, align 1
+ at G100000000 = addrspace(4) global [100000000 x i8] zeroinitializer, align 1
+; CHECK: @G1000000 = addrspace(4) global { [1000000 x i8], [249984 x i8] }
+; CHECK: @G10000000 = addrspace(4) global { [10000000 x i8], [262144 x i8] }
+; CHECK: @G100000000 = addrspace(4) global { [100000000 x i8], [262144 x i8] }

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_global_redzones.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_global_redzones.ll
new file mode 100644
index 0000000000000..3f3e094018757
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/adaptive_global_redzones.ll
@@ -0,0 +1,59 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+; Here we check that the global redzone sizes grow with the object size
+; for objects in global address space.
+
+ at G10 = addrspace(1) global [10 x i8] zeroinitializer, align 1
+; CHECK: @G10 = addrspace(1) global { [10 x i8], [54 x i8] }
+
+ at G31 = addrspace(1) global [31 x i8] zeroinitializer, align 1
+ at G32 = addrspace(1) global [32 x i8] zeroinitializer, align 1
+ at G33 = addrspace(1) global [33 x i8] zeroinitializer, align 1
+; CHECK: @G31 = addrspace(1) global { [31 x i8], [33 x i8] }
+; CHECK: @G32 = addrspace(1) global { [32 x i8], [32 x i8] }
+; CHECK: @G33 = addrspace(1) global { [33 x i8], [63 x i8] }
+
+ at G63 = addrspace(1) global [63 x i8] zeroinitializer, align 1
+ at G64 = addrspace(1) global [64 x i8] zeroinitializer, align 1
+ at G65 = addrspace(1) global [65 x i8] zeroinitializer, align 1
+; CHECK: @G63 = addrspace(1) global { [63 x i8], [33 x i8] }
+; CHECK: @G64 = addrspace(1) global { [64 x i8], [32 x i8] }
+; CHECK: @G65 = addrspace(1) global { [65 x i8], [63 x i8] }
+
+ at G127 = addrspace(1) global [127 x i8] zeroinitializer, align 1
+ at G128 = addrspace(1) global [128 x i8] zeroinitializer, align 1
+ at G129 = addrspace(1) global [129 x i8] zeroinitializer, align 1
+; CHECK: @G127 = addrspace(1) global { [127 x i8], [33 x i8] }
+; CHECK: @G128 = addrspace(1) global { [128 x i8], [32 x i8] }
+; CHECK: @G129 = addrspace(1) global { [129 x i8], [63 x i8] }
+
+ at G255 = addrspace(1) global [255 x i8] zeroinitializer, align 1
+ at G256 = addrspace(1) global [256 x i8] zeroinitializer, align 1
+ at G257 = addrspace(1) global [257 x i8] zeroinitializer, align 1
+; CHECK: @G255 = addrspace(1) global { [255 x i8], [33 x i8] }
+; CHECK: @G256 = addrspace(1) global { [256 x i8], [64 x i8] }
+; CHECK: @G257 = addrspace(1) global { [257 x i8], [95 x i8] }
+
+ at G511 = addrspace(1) global [511 x i8] zeroinitializer, align 1
+ at G512 = addrspace(1) global [512 x i8] zeroinitializer, align 1
+ at G513 = addrspace(1) global [513 x i8] zeroinitializer, align 1
+; CHECK: @G511 = addrspace(1) global { [511 x i8], [97 x i8] }
+; CHECK: @G512 = addrspace(1) global { [512 x i8], [128 x i8] }
+; CHECK: @G513 = addrspace(1) global { [513 x i8], [159 x i8] }
+
+ at G1023 = addrspace(1) global [1023 x i8] zeroinitializer, align 1
+ at G1024 = addrspace(1) global [1024 x i8] zeroinitializer, align 1
+ at G1025 = addrspace(1) global [1025 x i8] zeroinitializer, align 1
+; CHECK: @G1023 = addrspace(1) global { [1023 x i8], [225 x i8] }
+; CHECK: @G1024 = addrspace(1) global { [1024 x i8], [256 x i8] }
+; CHECK: @G1025 = addrspace(1) global { [1025 x i8], [287 x i8] }
+
+ at G1000000 = addrspace(1) global [1000000 x i8] zeroinitializer, align 1
+ at G10000000 = addrspace(1) global [10000000 x i8] zeroinitializer, align 1
+ at G100000000 = addrspace(1) global [100000000 x i8] zeroinitializer, align 1
+; CHECK: @G1000000 = addrspace(1) global { [1000000 x i8], [249984 x i8] }
+; CHECK: @G10000000 = addrspace(1) global { [10000000 x i8], [262144 x i8] }
+; CHECK: @G100000000 = addrspace(1) global { [100000000 x i8], [262144 x i8] }

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_lds.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_lds.ll
new file mode 100644
index 0000000000000..5342a7e3b24f6
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_lds.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+; Memory access to lds are not instrumented
+
+ at count = addrspace(3) global [100 x i32] undef, align 16
+
+define protected amdgpu_kernel void @lds_store(i32 %i) sanitize_address {
+entry:
+  ; CHECK-NOT: call * __asan_report
+  %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32] addrspace(3)* @count, i32 0, i32 %i
+  store i32 0, i32 addrspace(3)* %arrayidx1, align 4
+  ret void
+}
+
+define protected amdgpu_kernel void @lds_load(i32 %i) sanitize_address {
+entry:
+  ; CHECK-NOT: call * __asan_report
+  %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32] addrspace(3)* @count, i32 0, i32 %i
+  %0 = load i32, i32 addrspace(3)* %arrayidx1, align 4
+  ret void
+}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_scratch.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_scratch.ll
new file mode 100644
index 0000000000000..6152e84d56f19
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_do_not_instrument_scratch.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+; Memory access to scratch are not instrumented
+
+define protected amdgpu_kernel void @scratch_store(i32 %i) sanitize_address {
+entry:
+  ; CHECK-NOT: call * __asan_report
+  %c = alloca i32, align 4, addrspace(5)
+  store i32 0, i32 addrspace(5)* %c, align 4
+  ret void
+}
+
+define protected amdgpu_kernel void @scratch_load(i32 %i) sanitize_address {
+entry:
+  ; CHECK-NOT: call * __asan_report
+  %c = alloca i32, align 4, addrspace(5)
+  %0 = load i32, i32 addrspace(5)* %c, align 4
+  ret void
+}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_constant_address_space.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_constant_address_space.ll
new file mode 100644
index 0000000000000..d9e1e3364f708
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_constant_address_space.ll
@@ -0,0 +1,37 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+ at x = addrspace(4) global [2 x i32] zeroinitializer, align 4
+
+define protected amdgpu_kernel void @constant_load(i64 %i) sanitize_address {
+entry:
+; CHECK-LABEL: @constant_load
+; CHECK-NOT: load
+;
+; CHECK:   %[[LOAD_ADDR:[^ ]*]] = ptrtoint i32 addrspace(4)* %a to i64
+; CHECK:   lshr i64 %[[LOAD_ADDR]], 3
+; CHECK:   {{or|add}}
+; CHECK:   %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr
+; CHECK:   %[[LOAD_SHADOW:[^ ]*]] = load i8, i8* %[[LOAD_SHADOW_PTR]]
+; CHECK:   icmp ne i8
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   add i64 %{{.*}}, 3
+; CHECK:   trunc i64 %{{.*}} to i8
+; CHECK:   icmp sge i8 %{{.*}}, %[[LOAD_SHADOW]]
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; The crash block reports the error.
+; CHECK:   call void @__asan_report_load4(i64 %[[LOAD_ADDR]])
+; CHECK:   unreachable
+;
+; The actual load.
+; CHECK:   load i32, i32 addrspace(4)* %a
+; CHECK:   ret void
+
+  %a = getelementptr inbounds [2 x i32], [2 x i32]  addrspace(4)* @x, i64 0, i64 %i
+  %q = load i32, i32 addrspace(4)* %a, align 4
+  ret void
+}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_generic_address_space.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_generic_address_space.ll
new file mode 100644
index 0000000000000..313c25232983a
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_generic_address_space.ll
@@ -0,0 +1,78 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+define protected amdgpu_kernel void @generic_store(i32 addrspace(1)* %p, i32 %i) sanitize_address {
+entry:
+; CHECK-LABEL: @generic_store
+; CHECK-NOT: store
+; CHECK:   %[[GENERIC_ADDR:[^ ]*]] = bitcast i32* %q to i8*
+; CHECK:   call i1 @llvm.amdgcn.is.shared(i8* %[[GENERIC_ADDR]])
+; CHECK:   call i1 @llvm.amdgcn.is.private(i8* %[[GENERIC_ADDR]])
+; CHECK:   or
+; CHECK:   icmp ne i1 
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   %[[STORE_ADDR:[^ ]*]] = ptrtoint i32* %q to i64
+; CHECK:   lshr i64 %[[STORE_ADDR]], 3
+; CHECK:   {{or|add}}
+; CHECK:   %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr
+; CHECK:   %[[STORE_SHADOW:[^ ]*]] = load i8, i8* %[[STORE_SHADOW_PTR]]
+; CHECK:   icmp ne i8
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   add i64 %{{.*}}, 3
+; CHECK:   trunc i64 %{{.*}} to i8
+; CHECK:   icmp sge i8 %{{.*}}, %[[STORE_SHADOW]]
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; The crash block reports the error.
+; CHECK:   call void @__asan_report_store4(i64 %[[STORE_ADDR]])
+; CHECK:   unreachable
+;
+; The actual store.
+; CHECK:   store i32 0, i32* %q
+; CHECK:   ret void
+
+  %q = addrspacecast i32 addrspace(1)* %p to i32*
+  store i32 0, i32* %q, align 4
+  ret void
+}
+
+define protected amdgpu_kernel void @generic_load(i32 addrspace(1)* %p, i32 %i) sanitize_address {
+entry:
+; CHECK-LABEL: @generic_load
+; CHECK-NOT: load
+; CHECK:   %[[GENERIC_ADDR:[^ ]*]] = bitcast i32* %q to i8*
+; CHECK:   call i1 @llvm.amdgcn.is.shared(i8* %[[GENERIC_ADDR]])
+; CHECK:   call i1 @llvm.amdgcn.is.private(i8* %[[GENERIC_ADDR]])
+; CHECK:   or
+; CHECK:   icmp ne i1 
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   %[[STORE_ADDR:[^ ]*]] = ptrtoint i32* %q to i64
+; CHECK:   lshr i64 %[[STORE_ADDR]], 3
+; CHECK:   {{or|add}}
+; CHECK:   %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr
+; CHECK:   %[[STORE_SHADOW:[^ ]*]] = load i8, i8* %[[STORE_SHADOW_PTR]]
+; CHECK:   icmp ne i8
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   add i64 %{{.*}}, 3
+; CHECK:   trunc i64 %{{.*}} to i8
+; CHECK:   icmp sge i8 %{{.*}}, %[[STORE_SHADOW]]
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; The crash block reports the error.
+; CHECK:   call void @__asan_report_load4(i64 %[[STORE_ADDR]])
+; CHECK:   unreachable
+;
+; The actual store.
+; CHECK:   load i32, i32* %q
+; CHECK:   ret void
+
+  %q = addrspacecast i32 addrspace(1)* %p to i32*
+  %r = load i32, i32* %q, align 4
+  ret void
+}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_global_address_space.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_global_address_space.ll
new file mode 100644
index 0000000000000..3f6d25185da50
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/asan_instrument_global_address_space.ll
@@ -0,0 +1,64 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+define protected amdgpu_kernel void @global_store(i32 addrspace(1)* %p, i32 %i) sanitize_address {
+entry:
+; CHECK-LABEL: @global_store
+; CHECK-NOT: store
+;
+; CHECK:   %[[STORE_ADDR:[^ ]*]] = ptrtoint i32 addrspace(1)* %p to i64
+; CHECK:   lshr i64 %[[STORE_ADDR]], 3
+; CHECK:   or
+; CHECK:   %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr
+; CHECK:   %[[STORE_SHADOW:[^ ]*]] = load i8, i8* %[[STORE_SHADOW_PTR]]
+; CHECK:   icmp ne i8
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   add i64 %{{.*}}, 3
+; CHECK:   trunc i64 %{{.*}} to i8
+; CHECK:   icmp sge i8 %{{.*}}, %[[STORE_SHADOW]]
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; The crash block reports the error.
+; CHECK:   call void @__asan_report_store4(i64 %[[STORE_ADDR]])
+; CHECK:   unreachable
+;
+; The actual store.
+; CHECK:   store i32 0, i32 addrspace(1)* %p
+; CHECK:   ret void
+
+  store i32 0, i32 addrspace(1)* %p, align 4
+  ret void
+}
+
+define protected amdgpu_kernel void @global_load(i32 addrspace(1)* %p, i32 %i) sanitize_address {
+entry:
+; CHECK-LABEL: @global_load
+; CHECK-NOT: load
+;
+; CHECK:   %[[LOAD_ADDR:[^ ]*]] = ptrtoint i32 addrspace(1)* %p to i64
+; CHECK:   lshr i64 %[[LOAD_ADDR]], 3
+; CHECK:   {{add|or}}
+; CHECK:   %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr
+; CHECK:   %[[LOAD_SHADOW:[^ ]*]] = load i8, i8* %[[LOAD_SHADOW_PTR]]
+; CHECK:   icmp ne i8
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; CHECK:   add i64 %{{.*}}, 3
+; CHECK:   trunc i64 %{{.*}} to i8
+; CHECK:   icmp sge i8 %{{.*}}, %[[LOAD_SHADOW]]
+; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+;
+; The crash block reports the error.
+; CHECK:   call void @__asan_report_load4(i64 %[[LOAD_ADDR]])
+; CHECK:   unreachable
+;
+; The actual load.
+; CHECK:   load i32, i32 addrspace(1)* %p
+; CHECK:   ret void
+
+  %q = load i32, i32 addrspace(1)* %p, align 4
+  ret void
+}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/global_metadata_addrspacecasts.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/global_metadata_addrspacecasts.ll
new file mode 100644
index 0000000000000..35cca79261629
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/global_metadata_addrspacecasts.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+ at g = addrspace(1) global [1 x i32] zeroinitializer, align 4
+
+;CHECK: llvm.asan.globals
+
+!llvm.asan.globals = !{!0, !1}
+!0 = !{[1 x i32] addrspace(1)* @g, null, !"name", i1 false, i1 false}
+!1 = !{i8* addrspacecast (i8 addrspace(1)* bitcast ( [1 x i32] addrspace(1)* @g to i8 addrspace(1)*) to  i8*), null, !"name", i1 false, i1 false}

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/instrument-stack.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/instrument-stack.ll
new file mode 100644
index 0000000000000..e563f702749b8
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/instrument-stack.ll
@@ -0,0 +1,51 @@
+; This test checks that we are not instrumenting direct inbound stack accesses.
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-opt-stack -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -asan-opt-stack -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-opt-stack -asan-mapping-scale=5 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -asan-opt-stack -asan-mapping-scale=5 -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+;@sink = global i32* null, align 4
+
+; Ignore direct inbounds stack access.
+define void @foo() uwtable sanitize_address {
+entry:
+  %a = alloca i32, align 4
+  store i32 42, i32* %a, align 4
+  ret void
+; CHECK-LABEL: define void @foo
+; CHECK-NOT: __asan_report
+; CHECK: ret void
+}
+
+; Don't ignore dynamic indexing.
+define void @baz(i64 %i) sanitize_address {
+entry:
+  %a = alloca [10 x i32], align 4
+  %e = getelementptr inbounds [10 x i32], [10 x i32]* %a, i32 0, i64 %i
+  store i32 42, i32* %e, align 4
+  ret void
+; CHECK-LABEL: define void @baz
+; CHECK: __asan_report
+; CHECK: ret void
+}
+
+define void @bar() sanitize_address {
+entry:
+  %a = alloca [10 x i32], align 4
+  %e = getelementptr inbounds [10 x i32], [10 x i32]* %a, i32 0, i64 12
+  store i32 42, i32* %e, align 4
+  ret void
+; CHECK-LABEL: define void @bar
+; CHECK: __asan_report
+; CHECK: ret void
+}
+
+define void @endoftests() sanitize_address {
+entry:
+  ret void
+; CHECK-LABEL: define void @endoftests
+}
+

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_lds_globals.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_lds_globals.ll
new file mode 100644
index 0000000000000..e69384e219578
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_lds_globals.ll
@@ -0,0 +1,7 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+ at G10 = addrspace(3) global [10 x i8] zeroinitializer, align 1
+; CHECK-NOT: @G10 = addrspace(3) global { [10 x i8], [* x i8] }

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_scratch_globals.ll b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_scratch_globals.ll
new file mode 100644
index 0000000000000..537c3c773ac5c
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/AMDGPU/no_redzones_in_scratch_globals.ll
@@ -0,0 +1,7 @@
+; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -S | FileCheck %s
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
+target triple = "amdgcn-amd-amdhsa"
+
+ at G10 = addrspace(5) global [10 x i8] zeroinitializer, align 1
+; CHECK-NOT: @G10 = addrspace(5) global { [10 x i8], [* x i8] }


        


More information about the llvm-commits mailing list