Skip to content

Commit

Permalink
Add restrictions for volatile variables
Browse files Browse the repository at this point in the history
.
  • Loading branch information
KorovinVlad authored and igcbot committed Apr 9, 2024
1 parent 5fb44b9 commit 4f6d330
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 9 deletions.
28 changes: 21 additions & 7 deletions IGC/VectorCompiler/lib/GenXCodeGen/GenXVerify.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*========================== begin_copyright_notice ============================
Copyright (C) 2023 Intel Corporation
Copyright (C) 2023-2024 Intel Corporation
SPDX-License-Identifier: MIT
Expand All @@ -27,20 +27,20 @@ void GenXVerify::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}

bool GenXVerify::ensure(const bool Cond, const Twine &Msg, const Instruction &I,
bool GenXVerify::ensure(const bool Cond, const Twine &Msg, const Value &V,
const IsFatal IsFatal_) {
if (LLVM_LIKELY(Cond))
return true;
if (IsFatal_ == IsFatal::Yes || OptAllFatal || !OptQuietNonFatal)
vc::diagnose(I.getContext(),
vc::diagnose(V.getContext(),
DbgPrefix + "[stage:" +
OptStage.getParser().getOption(
static_cast<int>(OptStage.getValue())) +
"]" +
(IsFatal_ == IsFatal::No
? " (non-fatal, spec review required)"
: ""),
Msg, DS_Warning, vc::WarningName::Generic, &I);
Msg, DS_Warning, vc::WarningName::Generic, &V);
if (IsFatal_ == IsFatal::Yes || OptAllFatal) {
IsBroken = true;
if (OptTerminationPolicy == Terminate::OnFirstError)
Expand All @@ -55,15 +55,29 @@ bool GenXVerify::ensure(const bool Cond, const Twine &Msg, const Instruction &I,

bool GenXVerify::runOnModule(Module &M) {
visit(M);
if (Stage == GenXVerifyStage::PostIrAdaptors)
for (const auto &GV : M.globals())
visitGlobalVariable(GV);
if (OptTerminationPolicy != Terminate::No && IsBroken)
terminate();
return false;
}

void GenXVerify::visitGlobalVariable(const GlobalVariable &GV){
// TODO: add genx_volatile-attributed values check here.
// please make sure to run this check under a proper InvariantsSet to
// trigger it only at appropriate pipeline stage(s).
if (!GV.hasAttribute(genx::FunctionMD::GenXVolatile))
return;
ensure(GV.getAddressSpace() == vc::AddrSpace::Private,
"a volatile variable must reside in private address space", GV);
auto InvalidUser = llvm::find_if(GV.users(), [](const User *U) {
const auto *I = dyn_cast<Instruction>(U);
return !I || !(genx::isAVStore(I) || genx::isAVLoad(I));
});
if (InvalidUser == GV.user_end())
return;
ensure(false,
"a volatile variable may only be used in genx.vload/genx.vstore "
"intrinsics and volatile loads/stores instructions",
**InvalidUser);
};

void GenXVerify::visitCallInst(const CallInst &CI) {
Expand Down
4 changes: 2 additions & 2 deletions IGC/VectorCompiler/lib/GenXCodeGen/GenXVerify.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*========================== begin_copyright_notice ============================
Copyright (C) 2023 Intel Corporation
Copyright (C) 2023-2024 Intel Corporation
SPDX-License-Identifier: MIT
Expand Down Expand Up @@ -73,7 +73,7 @@ class GenXVerify : public ModulePass,
enum class IsFatal { No = 0, Yes = 1 };

void verifyRegioning(const CallInst &, const unsigned);
bool ensure(const bool Cond, const Twine &Msg, const Instruction &I,
bool ensure(const bool Cond, const Twine &Msg, const Value &V,
const IsFatal IsFatal_ = IsFatal::Yes);
[[noreturn]] static void terminate();

Expand Down
45 changes: 45 additions & 0 deletions IGC/VectorCompiler/test/GenXVerify/volatile.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2024 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================

; RUN: %opt %use_old_pass_manager% -GenXVerify -genx-verify-terminate=no \
; RUN: -genx-verify-all-fatal=1 -march=genx64 -mtriple=spir64-unknown-unknown \
; RUN: -mcpu=Gen9 -genx-verify-stage=post-ir-adaptors -S < %s 2>&1 | FileCheck \
; RUN: --check-prefixes=CHECK %s

target datalayout = "e-p:64:64-p6:32:32-i64:64-n8:16:32:64"
target triple = "genx64-unknown-unknown"

; CHECK: warning: {{.+}} <@SLMGV = addrspace(3) {{.+}}>: a volatile variable must reside in private address space
@SLMGV = addrspace(3) global <2 x i8> undef #0

; CHECK: warning: {{.+}} @GV {{.+}} a volatile variable may only be used in genx.vload/genx.vstore intrinsics and volatile loads/stores instructions
@GV = global <16 x i32> zeroinitializer, align 64 #1
@ALIAS = global <16 x i32> addrspace(1)* addrspacecast (<16 x i32>* @GV to <16 x i32> addrspace(1)*)

@INVALID = global <16 x float> zeroinitializer, align 64 #2
@VALID = global <16 x float> zeroinitializer, align 64 #3

define internal spir_func void @foo() {
; CHECK: warning: {{.+}} %cst = {{.+}} a volatile variable may only be used in genx.vload/genx.vstore intrinsics and volatile loads/stores instructions
%cst = addrspacecast <16 x float>* @INVALID to <16 x float> addrspace(4)*

; CHECK-NOT: warning
%ld.ic = tail call <16 x float> @llvm.genx.vload.v16f32.p0v16f32(<16 x float>* @VALID)
call void @llvm.genx.vstore.v16f32.p0v16f32(<16 x float> %ld.ic, <16 x float>* @VALID)
%ld.inst = load volatile <16 x float>, <16 x float>* @VALID
store volatile <16 x float> %ld.inst, <16 x float>* @VALID
ret void
}

declare <16 x float> @llvm.genx.vload.v16f32.p0v16f32(<16 x float>*)
declare void @llvm.genx.vstore.v16f32.p0v16f32(<16 x float>, <16 x float>*)

attributes #0 = { "VCByteOffset"="0" "VCGlobalVariable" "VCVolatile" "genx_byte_offset"="0" "genx_volatile" }
attributes #1 = { "VCByteOffset"="256" "VCGlobalVariable" "VCVolatile" "genx_byte_offset"="256" "genx_volatile" }
attributes #2 = { "VCByteOffset"="512" "VCGlobalVariable" "VCVolatile" "genx_byte_offset"="512" "genx_volatile" }
attributes #3 = { "VCByteOffset"="1024" "VCGlobalVariable" "VCVolatile" "genx_byte_offset"="1024" "genx_volatile" }

0 comments on commit 4f6d330

Please sign in to comment.