Skip to content

Commit fbf1aa9

Browse files
lsatanovigcbot
authored andcommitted
[IGC VC] GenXVerify pass, initial.
The aim of this pass to provide with genx-specific IR checks ensuring that IR can be considered semantically correct from the standpoint of VC BE backend. In VC BE backend different stages of compilation require different subsets of correctness invariants to be satisfied. This aspect is accommodated by GenXVerifyInvariantSet-based parametrization of the pass. At this point the pass includes a subset of checks upon genx regioning. Checks to be added are marked with TODO. Places marked with "TODO:spec review: demark a situation when a non-conforming real-world workload IRs have been found and it still needs to be revealed whether we need to update the spec or correct the IRs/optimizations. In the future the pass will be populated with more checks. The pass is being run by default in Debug build, but can also be used being built in Release* builds as a standalone or an auxiliary tool within LIT testing or while reducing testcases with llvm-reduce.
1 parent 8d12a0f commit fbf1aa9

File tree

8 files changed

+588
-6
lines changed

8 files changed

+588
-6
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ set(CODEGEN_SOURCES
4848
GenXGlobalValueLowering.cpp
4949
GenXGotoJoin.cpp
5050
GenXGVClobberChecker.cpp
51+
GenXVerify.cpp
52+
GenXVerify_Regioning.cpp
5153
GenXIMadPostLegalization.cpp
5254
GenXInitBiFConstants.cpp
5355
GenXInlineAsmLowering.cpp

IGC/VectorCompiler/lib/GenXCodeGen/GenX.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ enum class BuiltinFunctionKind {
6565
PostLegalization,
6666
};
6767

68+
// GenX IR may have different sets of validity invariants for different stages
69+
// in pipeline.
70+
enum class GenXVerifyInvariantSet {
71+
PreIrAdaptors,
72+
PreGenXLegalization,
73+
All,
74+
};
75+
6876
FunctionPass *createGenXPrinterPass(raw_ostream &O, const std::string &Banner);
6977
ModulePass *createGenXGroupPrinterPass(raw_ostream &O,
7078
const std::string &Banner);
@@ -119,6 +127,8 @@ ModulePass *createGenXLiveRangesWrapperPass();
119127
ModulePass *createGenXRematerializationWrapperPass();
120128
ModulePass *createGenXCoalescingWrapperPass();
121129
ModulePass *createGenXGVClobberCheckerPass();
130+
ModulePass *createGenXVerifyPass(
131+
GenXVerifyInvariantSet PipelineStage = GenXVerifyInvariantSet::All);
122132
ModulePass *createGenXAddressCommoningWrapperPass();
123133
ModulePass *createGenXArgIndirectionWrapperPass();
124134
FunctionPass *createGenXTidyControlFlowPass();

IGC/VectorCompiler/lib/GenXCodeGen/GenXTargetMachine.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void initializeGenXPasses(PassRegistry &registry) {
9898
initializeGenXCisaBuilderPass(registry);
9999
initializeGenXCoalescingWrapperPass(registry);
100100
initializeGenXGVClobberCheckerPass(registry);
101+
initializeGenXVerifyPass(registry);
101102
initializeGenXDeadVectorRemovalPass(registry);
102103
initializeGenXDepressurizerWrapperPass(registry);
103104
initializeGenXEarlySimdCFConformancePass(registry);
@@ -357,8 +358,13 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
357358
vc::addPass(PM, createPromoteMemoryToRegisterPass());
358359
// All passes which modify the LLVM IR are now complete; run the verifier
359360
// to ensure that the IR is valid.
360-
if (!DisableVerify)
361+
362+
if (!DisableVerify) {
361363
vc::addPass(PM, createVerifierPass());
364+
vc::addPass(
365+
PM, createGenXVerifyPass(GenXVerifyInvariantSet::PreGenXLegalization));
366+
}
367+
362368
// Run passes to generate vISA.
363369

364370
/// BasicAliasAnalysis
@@ -477,8 +483,13 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
477483

478484
/// .. include:: GenXLowering.cpp
479485
vc::addPass(PM, createGenXLoweringPass());
480-
if (!DisableVerify)
486+
487+
if (!DisableVerify) {
481488
vc::addPass(PM, createVerifierPass());
489+
vc::addPass(
490+
PM, createGenXVerifyPass(GenXVerifyInvariantSet::PreGenXLegalization));
491+
}
492+
482493
/// .. include:: GenXRegionCollapsing.cpp
483494
vc::addPass(PM, createGenXRegionCollapsingPass());
484495
/// EarlyCSE
@@ -490,8 +501,13 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
490501
vc::addPass(PM, createEarlyCSEPass());
491502
/// .. include:: GenXPatternMatch.cpp
492503
vc::addPass(PM, createGenXPatternMatchPass(PatternMatchKind::PreLegalization));
493-
if (!DisableVerify)
504+
505+
if (!DisableVerify) {
494506
vc::addPass(PM, createVerifierPass());
507+
vc::addPass(
508+
PM, createGenXVerifyPass(GenXVerifyInvariantSet::PreGenXLegalization));
509+
}
510+
495511
/// .. include:: GenXExtractVectorizer.cpp
496512
vc::addPass(PM, createGenXExtractVectorizerPass());
497513
/// .. include:: GenXVectorCombiner.cpp
@@ -535,8 +551,12 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
535551
/// .. include:: GenXConstants.cpp
536552
/// .. include:: GenXVectorDecomposer.h
537553
vc::addPass(PM, createGenXPostLegalizationPass());
538-
if (!DisableVerify)
554+
555+
if (!DisableVerify) {
539556
vc::addPass(PM, createVerifierPass());
557+
vc::addPass(PM, createGenXVerifyPass());
558+
}
559+
540560
/// EarlyCSE
541561
/// --------
542562
/// This is a standard LLVM pass, run at this point in the GenX backend.
@@ -546,8 +566,12 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
546566
vc::addPass(PM, createEarlyCSEPass());
547567
/// .. include:: GenXPatternMatch.cpp
548568
vc::addPass(PM, createGenXPatternMatchPass(PatternMatchKind::PostLegalization));
549-
if (!DisableVerify)
569+
570+
if (!DisableVerify) {
550571
vc::addPass(PM, createVerifierPass());
572+
vc::addPass(PM, createGenXVerifyPass());
573+
}
574+
551575
/// LICM
552576
/// ----
553577
/// This is a standard LLVM pass to hoist/sink the loop invariant code after
@@ -634,8 +658,10 @@ bool GenXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
634658
if (BackendConfig.enableRegAllocDump())
635659
vc::addPass(PM, createGenXModuleAnalysisDumperPass(RegAlloc, FGDumpsPrefix,
636660
".regalloc"));
637-
if (!DisableVerify)
661+
if (!DisableVerify) {
638662
vc::addPass(PM, createVerifierPass());
663+
vc::addPass(PM, createGenXVerifyPass());
664+
}
639665

640666
/// .. include:: GenXCisaBuilder.cpp
641667
vc::addPass(PM, createGenXCisaBuilderPass());
@@ -672,6 +698,9 @@ void GenXTargetMachine::adjustPassManager(PassManagerBuilder &PMBuilder) {
672698
// Packetize.
673699
auto AddPacketize = [](const PassManagerBuilder &Builder,
674700
PassManagerBase &PM) {
701+
#ifndef NDEBUG
702+
PM.add(createGenXVerifyPass(GenXVerifyInvariantSet::PreIrAdaptors));
703+
#endif
675704
PM.add(createGenXTranslateIntrinsicsPass());
676705
PM.add(createGenXTranslateSPIRVBuiltinsPass());
677706
PM.add(createAlwaysInlinerLegacyPass());

IGC/VectorCompiler/lib/GenXCodeGen/GenXTargetMachine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ void initializeGenXCFSimplificationPass(PassRegistry &);
219219
void initializeGenXCisaBuilderPass(PassRegistry &);
220220
void initializeGenXCoalescingWrapperPass(PassRegistry &);
221221
void initializeGenXGVClobberCheckerPass(PassRegistry &);
222+
void initializeGenXVerifyPass(PassRegistry &);
222223
void initializeGenXDeadVectorRemovalPass(PassRegistry &);
223224
void initializeGenXDepressurizerWrapperPass(PassRegistry &);
224225
void initializeGenXEarlySimdCFConformancePass(PassRegistry &);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*========================== begin_copyright_notice ============================
2+
3+
Copyright (C) 2023 Intel Corporation
4+
5+
SPDX-License-Identifier: MIT
6+
7+
============================= end_copyright_notice ===========================*/
8+
9+
//===----------------------------------------------------------------------===//
10+
// GenXVerify
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This pass contains GenX-specific IR validity checks.
14+
//
15+
#include "GenXVerify.h"
16+
17+
bool GenXVerify::doInitialization(Module &M) {
18+
Ctx = &M.getContext();
19+
return false;
20+
}
21+
22+
StringRef GenXVerify::getPassName() const {
23+
return "GenX IR verification pass.";
24+
}
25+
26+
void GenXVerify::getAnalysisUsage(AnalysisUsage &AU) const {
27+
AU.setPreservesAll();
28+
}
29+
30+
bool GenXVerify::ensure(const bool Cond, const Twine &Msg, const Instruction &I,
31+
const IsFatal IsFatal_) {
32+
if (LLVM_LIKELY(Cond))
33+
return true;
34+
vc::diagnose(I.getContext(),
35+
DbgPrefix + (IsFatal_ == IsFatal::No
36+
? " (non-fatal, spec review required)"
37+
: ""),
38+
Msg, DS_Warning, vc::WarningName::Generic, &I);
39+
if ((LLVM_LIKELY(!OptAllFatal) && IsFatal_ == IsFatal::Yes) ||
40+
LLVM_UNLIKELY(OptAllFatal)) {
41+
IsBroken = true;
42+
if (OptTerminateOnFirstError)
43+
terminate();
44+
}
45+
return false;
46+
}
47+
48+
[[noreturn]] void GenXVerify::terminate() {
49+
llvm::report_fatal_error(DbgPrefix + "failed, check log for details.");
50+
}
51+
52+
bool GenXVerify::runOnModule(Module &M) {
53+
visit(M);
54+
if (OptTerminate && IsBroken)
55+
terminate();
56+
return false;
57+
}
58+
59+
void GenXVerify::visitGlobalVariable(const GlobalVariable &GV){
60+
// TODO: add genx_volatile-attributed values check here.
61+
// please make sure to run this check under a proper InvariantsSet to
62+
// trigger it only at appropriate pipeline stage(s).
63+
};
64+
65+
void GenXVerify::visitCallInst(const CallInst &CI) {
66+
const unsigned IntrinsicId = vc::getAnyIntrinsicID(&CI);
67+
switch (IntrinsicId) {
68+
case GenXIntrinsic::genx_rdregionf:
69+
case GenXIntrinsic::genx_rdregioni:
70+
case GenXIntrinsic::genx_rdpredregion:
71+
case GenXIntrinsic::genx_wrregionf:
72+
case GenXIntrinsic::genx_wrregioni:
73+
case GenXIntrinsic::genx_wrpredregion:
74+
case GenXIntrinsic::genx_wrconstregion:
75+
case GenXIntrinsic::genx_wrpredpredregion:
76+
verifyRegioning(CI, IntrinsicId);
77+
break;
78+
};
79+
}
80+
81+
namespace llvm {
82+
void initializeGenXVerifyPass(PassRegistry &);
83+
} // namespace llvm
84+
85+
INITIALIZE_PASS_BEGIN(GenXVerify, "GenXVerify", "GenX IR verification", false,
86+
false)
87+
INITIALIZE_PASS_END(GenXVerify, "GenXVerify", "GenX IR verification", false,
88+
false)
89+
90+
ModulePass *
91+
llvm::createGenXVerifyPass(GenXVerifyInvariantSet ValidityInvariantsSet) {
92+
initializeGenXVerifyPass(*PassRegistry::getPassRegistry());
93+
return new GenXVerify(ValidityInvariantsSet);
94+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*========================== begin_copyright_notice ============================
2+
3+
Copyright (C) 2023 Intel Corporation
4+
5+
SPDX-License-Identifier: MIT
6+
7+
============================= end_copyright_notice ===========================*/
8+
9+
//===----------------------------------------------------------------------===//
10+
// GenXVerify
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This pass contains GenX-specific IR validity checks.
14+
//
15+
16+
#include "GenXIntrinsics.h"
17+
#include "GenXTargetMachine.h"
18+
#include "GenXUtil.h"
19+
20+
#include "vc/Support/GenXDiagnostic.h"
21+
22+
#include <llvm/IR/InstVisitor.h>
23+
#include <llvm/IR/Verifier.h>
24+
25+
#define DEBUG_TYPE "GENX_VERIFY"
26+
27+
using namespace llvm;
28+
using namespace genx;
29+
30+
class GenXVerify : public ModulePass,
31+
public IDMixin<GenXVerify>,
32+
public InstVisitor<GenXVerify> {
33+
private:
34+
static inline cl::opt<bool> OptTerminateOnFirstError{
35+
"genx-verify-terminate-on-first-error", cl::init(false), cl::Hidden,
36+
cl::desc("Terminate execution on first error found.")};
37+
38+
static inline cl::opt<bool> OptTerminate{
39+
"genx-verify-terminate", cl::init(true), cl::Hidden,
40+
cl::desc(
41+
"Terminate execution after pass completion if any errors found.")};
42+
43+
static inline cl::opt<bool> OptAllFatal{
44+
"genx-verify-all-fatal", cl::init(false), cl::Hidden,
45+
cl::desc("Ignore IsFatal::No flag used for assetions requiring spec "
46+
"clarification, making all of the checks fatal on failure.")};
47+
48+
static inline const StringRef DbgPrefix = "GenXVerify";
49+
LLVMContext *Ctx;
50+
bool IsBroken = false;
51+
GenXVerifyInvariantSet InvariantSet;
52+
enum class IsFatal { No = 0, Yes = 1 };
53+
54+
void verifyRegioning(const CallInst &, const unsigned);
55+
bool ensure(const bool Cond, const Twine &Msg, const Instruction &I,
56+
const IsFatal IsFatal_ = IsFatal::Yes);
57+
[[noreturn]] static void terminate();
58+
59+
public:
60+
explicit GenXVerify(GenXVerifyInvariantSet IS = GenXVerifyInvariantSet::All)
61+
: InvariantSet(IS), ModulePass(ID) {}
62+
StringRef getPassName() const override;
63+
void getAnalysisUsage(AnalysisUsage &) const override;
64+
bool runOnModule(Module &) override;
65+
bool doInitialization(Module &);
66+
void visitCallInst(const CallInst &);
67+
void visitGlobalVariable(const GlobalVariable &);
68+
};

0 commit comments

Comments
 (0)