diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -174,6 +174,9 @@ 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 @@ 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 @@ 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 @@ Value *LocalDynamicShadow = nullptr; const GlobalsMetadata &GlobalsMD; DenseMap ProcessedAllocas; + + FunctionCallee AMDGPUAddressShared; + FunctionCallee AMDGPUAddressPrivate; }; class AddressSanitizerLegacyPass : public FunctionPass { @@ -933,15 +948,19 @@ 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 @@ return false; } +static bool isUnsupportedAMDGPUAddrspace(Value *Addr) { + Type *PtrTy = cast(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::ignoreAccess(Value *Ptr) { - // Do not instrument acesses from different address spaces; we cannot deal - // with them. + // Instrument acesses from different address spaces only for AMDGPU. Type *PtrTy = cast(Ptr->getType()->getScalarType()); - if (PtrTy->getPointerAddressSpace() != 0) + if (PtrTy->getPointerAddressSpace() != 0 && + !(TargetTriple.isAMDGPU() && !isUnsupportedAMDGPUAddrspace(Ptr))) return true; // Ignore swifterror addresses. @@ -1665,6 +1692,29 @@ 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(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(AddrSpaceZeroLanding); + return InsertBefore; +} + void AddressSanitizer::instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, uint32_t TypeSize, bool IsWrite, @@ -1672,6 +1722,13 @@ 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 @@ 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 @@ 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 --- /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. + +@G10 = addrspace(4) global [10 x i8] zeroinitializer, align 1 +; CHECK: @G10 = addrspace(4) global { [10 x i8], [54 x i8] } + +@G31 = addrspace(4) global [31 x i8] zeroinitializer, align 1 +@G32 = addrspace(4) global [32 x i8] zeroinitializer, align 1 +@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] } + +@G63 = addrspace(4) global [63 x i8] zeroinitializer, align 1 +@G64 = addrspace(4) global [64 x i8] zeroinitializer, align 1 +@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] } + +@G127 = addrspace(4) global [127 x i8] zeroinitializer, align 1 +@G128 = addrspace(4) global [128 x i8] zeroinitializer, align 1 +@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] } + +@G255 = addrspace(4) global [255 x i8] zeroinitializer, align 1 +@G256 = addrspace(4) global [256 x i8] zeroinitializer, align 1 +@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] } + +@G511 = addrspace(4) global [511 x i8] zeroinitializer, align 1 +@G512 = addrspace(4) global [512 x i8] zeroinitializer, align 1 +@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] } + +@G1023 = addrspace(4) global [1023 x i8] zeroinitializer, align 1 +@G1024 = addrspace(4) global [1024 x i8] zeroinitializer, align 1 +@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] } + +@G1000000 = addrspace(4) global [1000000 x i8] zeroinitializer, align 1 +@G10000000 = addrspace(4) global [10000000 x i8] zeroinitializer, align 1 +@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 --- /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. + +@G10 = addrspace(1) global [10 x i8] zeroinitializer, align 1 +; CHECK: @G10 = addrspace(1) global { [10 x i8], [54 x i8] } + +@G31 = addrspace(1) global [31 x i8] zeroinitializer, align 1 +@G32 = addrspace(1) global [32 x i8] zeroinitializer, align 1 +@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] } + +@G63 = addrspace(1) global [63 x i8] zeroinitializer, align 1 +@G64 = addrspace(1) global [64 x i8] zeroinitializer, align 1 +@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] } + +@G127 = addrspace(1) global [127 x i8] zeroinitializer, align 1 +@G128 = addrspace(1) global [128 x i8] zeroinitializer, align 1 +@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] } + +@G255 = addrspace(1) global [255 x i8] zeroinitializer, align 1 +@G256 = addrspace(1) global [256 x i8] zeroinitializer, align 1 +@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] } + +@G511 = addrspace(1) global [511 x i8] zeroinitializer, align 1 +@G512 = addrspace(1) global [512 x i8] zeroinitializer, align 1 +@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] } + +@G1023 = addrspace(1) global [1023 x i8] zeroinitializer, align 1 +@G1024 = addrspace(1) global [1024 x i8] zeroinitializer, align 1 +@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] } + +@G1000000 = addrspace(1) global [1000000 x i8] zeroinitializer, align 1 +@G10000000 = addrspace(1) global [10000000 x i8] zeroinitializer, align 1 +@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 --- /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 + +@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 --- /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 --- /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" + +@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 --- /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 --- /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 --- /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" + +@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 --- /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 --- /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" + +@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 --- /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" + +@G10 = addrspace(5) global [10 x i8] zeroinitializer, align 1 +; CHECK-NOT: @G10 = addrspace(5) global { [10 x i8], [* x i8] }