-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[TargetVerifier][AMDGPU] Add TargetVerifier. #123609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jofrn
wants to merge
35
commits into
llvm:main
Choose a base branch
from
jofrn:tgt-verifier
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+252
−0
Open
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
d9b0a5d
[TargetVerifier][AMDGPU] Add TargetVerifier.
jofrn 3b69ade
Add hook for target verifier in llc,opt
jofrn a89ff83
Run AMDGPUTargetVerifier within AMDGPU pipeline. Move IsValid from
jofrn df507f9
Remove cmd line options that aren't required. Make error message expl…
jofrn 942312d
Return Verifier none status through PreservedAnalyses on fail.
jofrn 6216a10
Rebase update.
jofrn 4b7068f
Add generic TargetVerifier.
jofrn 86e8066
Remove store to const check since it is in Lint already
jofrn 17fc5c6
Add chain followed by unreachable check
jofrn 46e662c
Remove mfma check
jofrn 7e471c9
Add registerVerifierPasses to PassBuilder and add the verifier passes…
jofrn 1538985
Remove leftovers. Add titles. Add call to registerVerifierCallbacks i…
jofrn 32b0c0d
Add pass to legacy PM.
jofrn 387b2d5
Add fam in other projects.
jofrn d2c9425
Avoid fatal errors in llc.
jofrn 31a79a5
Add tool to build/test.
jofrn b51b530
Cleanup of unrequired functions.
jofrn d41d5f9
Make virtual.
jofrn 7ece5e2
Remove from legacy PM. Add to target dependent pipeline.
jofrn 42b8982
Add back to legacy PM.
jofrn 230f33b
Remove reference to FAM in registerCallbacks and VerifyEach for Targe…
jofrn c680041
Remove references to registry
jofrn 3f5634a
Remove int check
jofrn 6007895
Remove modifications to Lint/Verifier.
jofrn 756c3eb
Remove llvm-tgt-verify tool.
jofrn 3f1d72f
Remove TargetVerifier.cpp
jofrn 1c721cf
clang-format
jofrn f59b0f2
Add VerifyTarget option
jofrn f0f12f5
Remove AMDGPUTargetVerifier.h
jofrn 88a6d6b
Remove analyses.
jofrn 0d99a65
function name style, TargetVerifier comment, option name generality
jofrn 79215be
Fix after rebase
jofrn f25ecf1
Add back int check. These are invalid for AMDGPU.
jofrn cab7d2e
Merge branch 'main' into tgt-verifier
jofrn d2aa0dc
Fixups: style, format, test removal
jofrn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| //===-- llvm/Target/TargetVerifier.h - LLVM IR Target Verifier --*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines target verifier interfaces that can be used for some | ||
| // validation of input to the system, and for checking that transformations | ||
| // haven't done something bad. In contrast to the Verifier or Lint, the | ||
| // TargetVerifier looks for constructions invalid to a particular target | ||
| // machine. | ||
| // | ||
| // To see what specifically is checked, look at an individual backend's | ||
| // TargetVerifier. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_TARGET_VERIFIER_H | ||
| #define LLVM_TARGET_VERIFIER_H | ||
|
|
||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/IR/PassManager.h" | ||
| #include "llvm/TargetParser/Triple.h" | ||
|
|
||
| namespace llvm { | ||
|
|
||
| class Function; | ||
|
|
||
| class TargetVerifierPass : public PassInfoMixin<TargetVerifierPass> { | ||
| public: | ||
| virtual PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) = 0; | ||
| }; | ||
|
|
||
| class TargetVerify { | ||
| protected: | ||
| void writeValues(ArrayRef<const Value *> Vs) { | ||
| for (const Value *V : Vs) { | ||
| if (!V) | ||
| continue; | ||
| if (isa<Instruction>(V)) { | ||
| MessagesStr << *V << '\n'; | ||
| } else { | ||
| V->printAsOperand(MessagesStr, true, Mod); | ||
| MessagesStr << '\n'; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A check failed, so printout out the condition and the message. | ||
| /// | ||
| /// This provides a nice place to put a breakpoint if you want to see why | ||
| /// something is not correct. | ||
| void checkFailed(const Twine &Message) { MessagesStr << Message << '\n'; } | ||
|
|
||
| /// A check failed (with values to print). | ||
| /// | ||
| /// This calls the Message-only version so that the above is easier to set | ||
| /// a breakpoint on. | ||
| template <typename T1, typename... Ts> | ||
| void checkFailed(const Twine &Message, const T1 &V1, const Ts &...Vs) { | ||
| checkFailed(Message); | ||
| writeValues({V1, Vs...}); | ||
| } | ||
|
|
||
| public: | ||
| Module *Mod; | ||
| Triple TT; | ||
|
|
||
| std::string Messages; | ||
| raw_string_ostream MessagesStr; | ||
|
|
||
| bool IsValid = true; | ||
|
|
||
| TargetVerify(Module *Mod) | ||
| : Mod(Mod), TT(Mod->getTargetTriple()), MessagesStr(Messages) {} | ||
|
|
||
| virtual bool run(Function &F) = 0; | ||
| }; | ||
|
|
||
| } // namespace llvm | ||
|
|
||
| #endif // LLVM_TARGET_VERIFIER_H | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| //===-- AMDGPUTargetVerifier.cpp - AMDGPU -----------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file defines target verifier interfaces that can be used for some | ||
| // validation of input to the system, and for checking that transformations | ||
| // haven't done something bad. In contrast to the Verifier or Lint, the | ||
| // TargetVerifier looks for constructions invalid to a particular target | ||
| // machine. | ||
| // | ||
| // To see what specifically is checked, look at an individual backend's | ||
| // TargetVerifier. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "AMDGPU.h" | ||
|
|
||
| #include "llvm/IR/Function.h" | ||
| #include "llvm/IR/IntrinsicInst.h" | ||
| #include "llvm/IR/IntrinsicsAMDGPU.h" | ||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/IR/Value.h" | ||
| #include "llvm/Support/Debug.h" | ||
|
|
||
| #include "llvm/Support/raw_ostream.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| // Check - We know that cond should be true, if not print an error message. | ||
| #define Check(C, ...) \ | ||
| do { \ | ||
| if (!(C)) { \ | ||
| TargetVerify::checkFailed(__VA_ARGS__); \ | ||
| } \ | ||
| } while (false) | ||
|
|
||
| namespace llvm { | ||
|
|
||
| class AMDGPUTargetVerify : public TargetVerify { | ||
| public: | ||
| AMDGPUTargetVerify(Module *Mod) : TargetVerify(Mod) {} | ||
| bool run(Function &F) override; | ||
| }; | ||
|
|
||
| static bool IsValidInt(const Type *Ty) { | ||
| return Ty->isIntegerTy(1) || Ty->isIntegerTy(8) || Ty->isIntegerTy(16) || | ||
| Ty->isIntegerTy(32) || Ty->isIntegerTy(64) || Ty->isIntegerTy(128); | ||
| } | ||
|
|
||
| bool AMDGPUTargetVerify::run(Function &F) { | ||
|
|
||
| for (auto &BB : F) { | ||
|
|
||
| for (auto &I : BB) { | ||
|
|
||
| // Ensure integral types are valid: i8, i16, i32, i64, i128 | ||
| if (I.getType()->isIntegerTy()) | ||
| Check(IsValidInt(I.getType()), "int type is invalid.", &I); | ||
| for (unsigned i = 0; i < I.getNumOperands(); ++i) | ||
| if (I.getOperand(i)->getType()->isIntegerTy()) | ||
| Check(IsValidInt(I.getOperand(i)->getType()), "int type is invalid.", | ||
| I.getOperand(i)); | ||
| } | ||
| } | ||
|
|
||
| dbgs() << MessagesStr.str(); | ||
| if (!MessagesStr.str().empty()) { | ||
| IsValid = false; | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| PreservedAnalyses AMDGPUTargetVerifierPass::run(Function &F, | ||
| FunctionAnalysisManager &AM) { | ||
| auto *Mod = F.getParent(); | ||
|
|
||
| AMDGPUTargetVerify TV(Mod); | ||
| TV.run(F); | ||
|
|
||
| dbgs() << TV.MessagesStr.str(); | ||
| if (!TV.MessagesStr.str().empty()) { | ||
| TV.IsValid = false; | ||
| return PreservedAnalyses::none(); | ||
| } | ||
| return PreservedAnalyses::all(); | ||
| } | ||
|
|
||
| struct AMDGPUTargetVerifierLegacyPass : public FunctionPass { | ||
| static char ID; | ||
|
|
||
| std::unique_ptr<AMDGPUTargetVerify> TV; | ||
| bool FatalErrors = false; | ||
|
|
||
| AMDGPUTargetVerifierLegacyPass(bool FatalErrors) | ||
| : FunctionPass(ID), FatalErrors(FatalErrors) { | ||
| initializeAMDGPUTargetVerifierLegacyPassPass( | ||
| *PassRegistry::getPassRegistry()); | ||
| } | ||
|
|
||
| bool doInitialization(Module &M) override { | ||
| TV = std::make_unique<AMDGPUTargetVerify>(&M); | ||
| return false; | ||
| } | ||
|
|
||
| bool runOnFunction(Function &F) override { | ||
| if (!TV->run(F)) { | ||
| errs() << "in function " << F.getName() << '\n'; | ||
| if (FatalErrors) | ||
| report_fatal_error("broken function found, compilation aborted!"); | ||
| else | ||
| errs() << "broken function found, compilation aborted!\n"; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool doFinalization(Module &M) override { | ||
| bool IsValid = true; | ||
| for (Function &F : M) | ||
| if (F.isDeclaration()) | ||
| IsValid &= TV->run(F); | ||
|
|
||
| if (!IsValid) { | ||
| if (FatalErrors) | ||
| report_fatal_error("broken module found, compilation aborted!"); | ||
| else | ||
| errs() << "broken module found, compilation aborted!\n"; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| void getAnalysisUsage(AnalysisUsage &AU) const override { | ||
| AU.setPreservesAll(); | ||
| } | ||
| }; | ||
| char AMDGPUTargetVerifierLegacyPass::ID = 0; | ||
| FunctionPass *createAMDGPUTargetVerifierLegacyPass(bool FatalErrors) { | ||
| return new AMDGPUTargetVerifierLegacyPass(FatalErrors); | ||
| } | ||
| } // namespace llvm | ||
| INITIALIZE_PASS(AMDGPUTargetVerifierLegacyPass, "amdgpu-tgtverifier", | ||
| "AMDGPU Target Verifier", false, false) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -amdgpu-verify-tgt -o - < %s 2>&1 | FileCheck %s | ||
|
|
||
| define amdgpu_cs i65 @invalid_int() { | ||
| ; CHECK: int type is invalid. | ||
| ret i65 0 | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rename this to something more accurate because currently I don't know where it writes to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be written to anywhere, but
MessagesStris currently being written todbgs().https://github.com/llvm/llvm-project/blob/de38b78d2bd598c6168c6235d408726c68251f4c/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp#L109