Skip to content

Commit 8f7d08c

Browse files
authored
[DeviceSanitizer] Move isUnsupportedSPIRAccess to SPIRVSanitizerCommonUtils.cpp. (intel#17597)
Both AddressSanitizer and MemorySanitizer ignore target extension type.
1 parent 7175536 commit 8f7d08c

File tree

7 files changed

+134
-57
lines changed

7 files changed

+134
-57
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,11 @@ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @intel/dpcpp-san
202202
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @intel/dpcpp-sanitizers-review
203203
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h @intel/dpcpp-sanitizers-review
204204
llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h @intel/dpcpp-sanitizers-review
205+
llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h @intel/dpcpp-sanitizers-review
205206
llvm/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h @intel/dpcpp-sanitizers-review
206207
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @intel/dpcpp-sanitizers-review
207208
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @intel/dpcpp-sanitizers-review
209+
llvm/lib/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.cpp @intel/dpcpp-sanitizers-review
208210
llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @intel/dpcpp-sanitizers-review
209211
llvm/test/Instrumentation/AddressSanitizer/ @intel/dpcpp-sanitizers-review
210212
llvm/test/Instrumentation/MemorySanitizer/ @intel/dpcpp-sanitizers-review
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===- SPIRVSanitizerCommonUtils.h - Commnon utils --------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares common infrastructure for SPIRV Sanitizer.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H
13+
#define LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H
14+
15+
#include "llvm/IR/DerivedTypes.h"
16+
#include "llvm/IR/Type.h"
17+
#include "llvm/IR/Value.h"
18+
19+
namespace llvm {
20+
// Spir memory address space
21+
constexpr unsigned kSpirOffloadPrivateAS = 0;
22+
constexpr unsigned kSpirOffloadGlobalAS = 1;
23+
constexpr unsigned kSpirOffloadConstantAS = 2;
24+
constexpr unsigned kSpirOffloadLocalAS = 3;
25+
constexpr unsigned kSpirOffloadGenericAS = 4;
26+
27+
TargetExtType *getTargetExtType(Type *Ty);
28+
bool isJointMatrixAccess(Value *V);
29+
} // namespace llvm
30+
31+
#endif // LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#include "llvm/TargetParser/Triple.h"
7575
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
7676
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
77+
#include "llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h"
7778
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
7879
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
7980
#include "llvm/Transforms/Utils/Instrumentation.h"
@@ -195,13 +196,6 @@ constexpr size_t kAccessSizeIndexMask = 0xf;
195196
constexpr size_t kIsWriteShift = 5;
196197
constexpr size_t kIsWriteMask = 0x1;
197198

198-
// Spir memory address space
199-
static constexpr unsigned kSpirOffloadPrivateAS = 0;
200-
static constexpr unsigned kSpirOffloadGlobalAS = 1;
201-
static constexpr unsigned kSpirOffloadConstantAS = 2;
202-
static constexpr unsigned kSpirOffloadLocalAS = 3;
203-
static constexpr unsigned kSpirOffloadGenericAS = 4;
204-
205199
// Command-line flags.
206200

207201
static cl::opt<bool> ClEnableKasan(
@@ -1653,49 +1647,6 @@ static bool isUnsupportedAMDGPUAddrspace(Value *Addr) {
16531647
return false;
16541648
}
16551649

1656-
static TargetExtType *getTargetExtType(Type *Ty) {
1657-
if (auto *TargetTy = dyn_cast<TargetExtType>(Ty))
1658-
return TargetTy;
1659-
1660-
if (Ty->isVectorTy())
1661-
return getTargetExtType(Ty->getScalarType());
1662-
1663-
if (Ty->isArrayTy())
1664-
return getTargetExtType(Ty->getArrayElementType());
1665-
1666-
if (auto *STy = dyn_cast<StructType>(Ty)) {
1667-
for (unsigned int i = 0; i < STy->getNumElements(); i++)
1668-
if (auto *TargetTy = getTargetExtType(STy->getElementType(i)))
1669-
return TargetTy;
1670-
return nullptr;
1671-
}
1672-
1673-
return nullptr;
1674-
}
1675-
1676-
// Skip pointer operand that is sycl joint matrix access since it isn't from
1677-
// user code, e.g. %call:
1678-
// clang-format off
1679-
// %a = alloca %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", align 8
1680-
// %0 = getelementptr inbounds %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", ptr %a, i64 0, i32 0
1681-
// %call = call spir_func ptr
1682-
// @_Z19__spirv_AccessChainIfN4sycl3_V13ext6oneapi12experimental6matrix9precision4tf32ELm8ELm8ELN5__spv9MatrixUseE0ELNS8_5Scope4FlagE3EEPT_PPNS8_28__spirv_CooperativeMatrixKHRIT0_XT4_EXT1_EXT2_EXT3_EEEm(ptr %0, i64 0)
1683-
// %1 = load float, ptr %call, align 4
1684-
// store float %1, ptr %call, align 4
1685-
// clang-format on
1686-
static bool isJointMatrixAccess(Value *V) {
1687-
auto *ActualV = V->stripInBoundsOffsets();
1688-
if (auto *CI = dyn_cast<CallInst>(ActualV)) {
1689-
for (Value *Op : CI->args()) {
1690-
if (auto *AI = dyn_cast<AllocaInst>(Op->stripInBoundsOffsets()))
1691-
if (auto *TargetTy = getTargetExtType(AI->getAllocatedType()))
1692-
return TargetTy->getName().starts_with("spirv.") &&
1693-
TargetTy->getName().contains("Matrix");
1694-
}
1695-
}
1696-
return false;
1697-
}
1698-
16991650
static bool isUnsupportedDeviceGlobal(GlobalVariable *G) {
17001651
// Non image scope device globals are implemented by device USM, and the
17011652
// out-of-bounds check for them will be done by sanitizer USM part. So we

llvm/lib/Transforms/Instrumentation/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_llvm_component_library(LLVMInstrumentation
2626
TypeSanitizer.cpp
2727
HWAddressSanitizer.cpp
2828
RealtimeSanitizer.cpp
29+
SPIRVSanitizerCommonUtils.cpp
2930

3031
ADDITIONAL_HEADER_DIRS
3132
${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
#include "llvm/Support/Path.h"
201201
#include "llvm/Support/raw_ostream.h"
202202
#include "llvm/TargetParser/Triple.h"
203+
#include "llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h"
203204
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
204205
#include "llvm/Transforms/Utils/Instrumentation.h"
205206
#include "llvm/Transforms/Utils/Local.h"
@@ -588,13 +589,6 @@ static const PlatformMemoryMapParams Intel_SPIR_MemoryMapParams = {
588589
&Intel_SPIR64_MemoryMapParams,
589590
};
590591

591-
// Spir memory address space
592-
static constexpr unsigned kSpirOffloadPrivateAS = 0;
593-
static constexpr unsigned kSpirOffloadGlobalAS = 1;
594-
static constexpr unsigned kSpirOffloadConstantAS = 2;
595-
static constexpr unsigned kSpirOffloadLocalAS = 3;
596-
static constexpr unsigned kSpirOffloadGenericAS = 4;
597-
598592
namespace {
599593

600594
class MemorySanitizerOnSpirv;
@@ -1746,6 +1740,18 @@ static bool isUnsupportedSPIRAccess(const Value *Addr, Instruction *I) {
17461740
if (OrigValue->getName().starts_with("__spirv_BuiltIn"))
17471741
return true;
17481742

1743+
// Ignore load/store for target ext type since we can't know exactly what size
1744+
// it is.
1745+
if (auto *SI = dyn_cast<StoreInst>(I))
1746+
if (getTargetExtType(SI->getValueOperand()->getType()) ||
1747+
isJointMatrixAccess(SI->getPointerOperand()))
1748+
return true;
1749+
1750+
if (auto *LI = dyn_cast<LoadInst>(I))
1751+
if (getTargetExtType(I->getType()) ||
1752+
isJointMatrixAccess(LI->getPointerOperand()))
1753+
return true;
1754+
17491755
Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
17501756
switch (PtrTy->getPointerAddressSpace()) {
17511757
case kSpirOffloadPrivateAS:
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===- SPIRVSanitizerCommonUtils.cpp- SPIRV Sanitizer commnon utils ------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines common infrastructure for SPIRV Sanitizer.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h"
14+
#include "llvm/IR/Instructions.h"
15+
16+
using namespace llvm;
17+
18+
namespace llvm {
19+
TargetExtType *getTargetExtType(Type *Ty) {
20+
if (auto *TargetTy = dyn_cast<TargetExtType>(Ty))
21+
return TargetTy;
22+
23+
if (Ty->isVectorTy())
24+
return getTargetExtType(Ty->getScalarType());
25+
26+
if (Ty->isArrayTy())
27+
return getTargetExtType(Ty->getArrayElementType());
28+
29+
if (auto *STy = dyn_cast<StructType>(Ty)) {
30+
for (unsigned int i = 0; i < STy->getNumElements(); i++)
31+
if (auto *TargetTy = getTargetExtType(STy->getElementType(i)))
32+
return TargetTy;
33+
return nullptr;
34+
}
35+
36+
return nullptr;
37+
}
38+
39+
// Skip pointer operand that is sycl joint matrix access since it isn't from
40+
// user code, e.g. %call:
41+
// clang-format off
42+
// %a = alloca %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", align 8
43+
// %0 = getelementptr inbounds %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", ptr %a, i64 0, i32 0
44+
// %call = call spir_func ptr
45+
// @_Z19__spirv_AccessChainIfN4sycl3_V13ext6oneapi12experimental6matrix9precision4tf32ELm8ELm8ELN5__spv9MatrixUseE0ELNS8_5Scope4FlagE3EEPT_PPNS8_28__spirv_CooperativeMatrixKHRIT0_XT4_EXT1_EXT2_EXT3_EEEm(ptr %0, i64 0)
46+
// %1 = load float, ptr %call, align 4
47+
// store float %1, ptr %call, align 4
48+
// clang-format on
49+
bool isJointMatrixAccess(Value *V) {
50+
auto *ActualV = V->stripInBoundsOffsets();
51+
if (auto *CI = dyn_cast<CallInst>(ActualV)) {
52+
for (Value *Op : CI->args()) {
53+
if (auto *AI = dyn_cast<AllocaInst>(Op->stripInBoundsOffsets()))
54+
if (auto *TargetTy = getTargetExtType(AI->getAllocatedType()))
55+
return TargetTy->getName().starts_with("spirv.") &&
56+
TargetTy->getName().contains("Matrix");
57+
}
58+
}
59+
return false;
60+
}
61+
} // namespace llvm
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: opt < %s -passes=msan -msan-instrumentation-with-call-threshold=0 -msan-eager-checks=1 -msan-spir-privates=0 -S | FileCheck %s
2+
3+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
4+
target triple = "spir64-unknown-unknown"
5+
6+
%"class.sycl::_V1::ext::oneapi::bfloat16" = type { i16 }
7+
%"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix" = type { target("spirv.CooperativeMatrixKHR", i16, 3, 16, 32, 0) }
8+
9+
; CHECK-LABEL: @test
10+
; CHECK-NOT: call i64 @__msan_get_shadow
11+
declare dso_local spir_func noundef ptr addrspace(4) @_Z19__spirv_AccessChainIN4sycl3_V13ext6oneapi8bfloat16ES4_Lm16ELm32ELN5__spv9MatrixUseE0ELNS5_5Scope4FlagE3EEPT_PPNS5_28__spirv_CooperativeMatrixKHRIT0_XT4_EXT1_EXT2_EXT3_EEEm(ptr addrspace(4) noundef, i64 noundef)
12+
13+
define weak_odr dso_local spir_kernel void @test() {
14+
entry:
15+
%sub_a.i = alloca %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", align 8
16+
%element.i = alloca %"class.sycl::_V1::ext::oneapi::bfloat16", align 2
17+
%0 = getelementptr inbounds { i16 }, ptr %element.i, i64 0, i32 0
18+
%spvm.i = getelementptr inbounds %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix", ptr %sub_a.i, i64 0, i32 0
19+
%addrcast = addrspacecast ptr %spvm.i to ptr addrspace(4)
20+
%call.i67 = call spir_func noundef ptr addrspace(4) @_Z19__spirv_AccessChainIN4sycl3_V13ext6oneapi8bfloat16ES4_Lm16ELm32ELN5__spv9MatrixUseE0ELNS5_5Scope4FlagE3EEPT_PPNS5_28__spirv_CooperativeMatrixKHRIT0_XT4_EXT1_EXT2_EXT3_EEEm(ptr addrspace(4) noundef %addrcast, i64 1)
21+
%gep = getelementptr inbounds nuw { i16 }, ptr addrspace(4) %call.i67, i64 0, i32 0
22+
%val = load i16, ptr %0, align 2
23+
store i16 %val, ptr addrspace(4) %gep, align 2
24+
ret void
25+
}

0 commit comments

Comments
 (0)