[clang] [llvm] [TargetVerifier][AMDGPU] Add TargetVerifier. (PR #123609)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 22 12:00:43 PDT 2025
https://github.com/jofrn updated https://github.com/llvm/llvm-project/pull/123609
>From 210b6d80bcfbbcd216f98199df386280724561e2 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Mon, 20 Jan 2025 04:51:26 -0800
Subject: [PATCH 01/12] [TargetVerifier][AMDGPU] Add TargetVerifier.
This pass verifies the IR for an individual backend. This is
different than Lint because it consolidates all checks for a
given backend in a single pass. A check for Lint may be
undefined behavior across all targets, whereas a check in
TargetVerifier would only pertain to the specified target
but can check more than just undefined behavior such are IR
validity. A use case of this would be to reject programs
with invalid IR while fuzzing.
---
llvm/include/llvm/IR/Module.h | 4 +
llvm/include/llvm/Target/TargetVerifier.h | 82 +++++++
.../TargetVerify/AMDGPUTargetVerifier.h | 36 +++
llvm/lib/IR/Verifier.cpp | 18 +-
.../Target/AMDGPU/AMDGPUTargetVerifier.cpp | 213 ++++++++++++++++++
llvm/lib/Target/AMDGPU/CMakeLists.txt | 1 +
llvm/test/CodeGen/AMDGPU/tgt-verify.ll | 62 +++++
llvm/tools/llvm-tgt-verify/CMakeLists.txt | 34 +++
.../tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 172 ++++++++++++++
9 files changed, 618 insertions(+), 4 deletions(-)
create mode 100644 llvm/include/llvm/Target/TargetVerifier.h
create mode 100644 llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
create mode 100644 llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
create mode 100644 llvm/test/CodeGen/AMDGPU/tgt-verify.ll
create mode 100644 llvm/tools/llvm-tgt-verify/CMakeLists.txt
create mode 100644 llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 91ccd76c41e07..03c0cf1cf0924 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -214,6 +214,10 @@ class LLVM_ABI Module {
/// @name Constructors
/// @{
public:
+ /// Is this Module valid as determined by one of the verification passes
+ /// i.e. Lint, Verifier, TargetVerifier.
+ bool IsValid = true;
+
/// Is this Module using intrinsics to record the position of debugging
/// information, or non-intrinsic records? See IsNewDbgInfoFormat in
/// \ref BasicBlock.
diff --git a/llvm/include/llvm/Target/TargetVerifier.h b/llvm/include/llvm/Target/TargetVerifier.h
new file mode 100644
index 0000000000000..e00c6a7b260c9
--- /dev/null
+++ b/llvm/include/llvm/Target/TargetVerifier.h
@@ -0,0 +1,82 @@
+//===-- 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 TargetVerifier.cpp or an
+// individual backend's TargetVerifier.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_VERIFIER_H
+#define LLVM_TARGET_VERIFIER_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm {
+
+class Function;
+
+class TargetVerifierPass : public PassInfoMixin<TargetVerifierPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {}
+};
+
+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;
+
+ TargetVerify(Module *Mod)
+ : Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())),
+ MessagesStr(Messages) {}
+
+ void run(Function &F) {};
+};
+
+} // namespace llvm
+
+#endif // LLVM_TARGET_VERIFIER_H
diff --git a/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
new file mode 100644
index 0000000000000..e6ff57629b141
--- /dev/null
+++ b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
@@ -0,0 +1,36 @@
+//===-- llvm/Target/TargetVerify/AMDGPUTargetVerifier.h - 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.
+////
+////===----------------------------------------------------------------------===//
+
+#ifndef LLVM_AMDGPU_TARGET_VERIFIER_H
+#define LLVM_AMDGPU_TARGET_VERIFIER_H
+
+#include "llvm/Target/TargetVerifier.h"
+
+namespace llvm {
+
+class Function;
+
+class AMDGPUTargetVerifierPass : public TargetVerifierPass {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_AMDGPU_TARGET_VERIFIER_H
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 8afe360d088bc..9d21ca182ca13 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -135,6 +135,10 @@ static cl::opt<bool> VerifyNoAliasScopeDomination(
cl::desc("Ensure that llvm.experimental.noalias.scope.decl for identical "
"scopes are not dominating"));
+static cl::opt<bool>
+ VerifyAbortOnError("verifier-abort-on-error", cl::init(false),
+ cl::desc("In the Verifier pass, abort on errors."));
+
namespace llvm {
struct VerifierSupport {
@@ -7796,16 +7800,22 @@ VerifierAnalysis::Result VerifierAnalysis::run(Function &F,
PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
auto Res = AM.getResult<VerifierAnalysis>(M);
- if (FatalErrors && (Res.IRBroken || Res.DebugInfoBroken))
- report_fatal_error("Broken module found, compilation aborted!");
+ if (Res.IRBroken || Res.DebugInfoBroken) {
+ M.IsValid = false;
+ if (VerifyAbortOnError && FatalErrors)
+ report_fatal_error("Broken module found, compilation aborted!");
+ }
return PreservedAnalyses::all();
}
PreservedAnalyses VerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
auto res = AM.getResult<VerifierAnalysis>(F);
- if (res.IRBroken && FatalErrors)
- report_fatal_error("Broken function found, compilation aborted!");
+ if (res.IRBroken) {
+ F.getParent()->IsValid = false;
+ if (VerifyAbortOnError && FatalErrors)
+ report_fatal_error("Broken function found, compilation aborted!");
+ }
return PreservedAnalyses::all();
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
new file mode 100644
index 0000000000000..585b19065c142
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -0,0 +1,213 @@
+#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
+
+#include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/IR/Dominators.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/raw_ostream.h"
+
+using namespace llvm;
+
+static cl::opt<bool>
+MarkUniform("mark-uniform", cl::desc("Mark instructions as uniform"), cl::init(false));
+
+// Check - We know that cond should be true, if not print an error message.
+#define Check(C, ...) \
+ do { \
+ if (!(C)) { \
+ TargetVerify::CheckFailed(__VA_ARGS__); \
+ return; \
+ } \
+ } while (false)
+
+static bool isMFMA(unsigned IID) {
+ switch (IID) {
+ case Intrinsic::amdgcn_mfma_f32_4x4x1f32:
+ case Intrinsic::amdgcn_mfma_f32_4x4x4f16:
+ case Intrinsic::amdgcn_mfma_i32_4x4x4i8:
+ case Intrinsic::amdgcn_mfma_f32_4x4x2bf16:
+
+ case Intrinsic::amdgcn_mfma_f32_16x16x1f32:
+ case Intrinsic::amdgcn_mfma_f32_16x16x4f32:
+ case Intrinsic::amdgcn_mfma_f32_16x16x4f16:
+ case Intrinsic::amdgcn_mfma_f32_16x16x16f16:
+ case Intrinsic::amdgcn_mfma_i32_16x16x4i8:
+ case Intrinsic::amdgcn_mfma_i32_16x16x16i8:
+ case Intrinsic::amdgcn_mfma_f32_16x16x2bf16:
+ case Intrinsic::amdgcn_mfma_f32_16x16x8bf16:
+
+ case Intrinsic::amdgcn_mfma_f32_32x32x1f32:
+ case Intrinsic::amdgcn_mfma_f32_32x32x2f32:
+ case Intrinsic::amdgcn_mfma_f32_32x32x4f16:
+ case Intrinsic::amdgcn_mfma_f32_32x32x8f16:
+ case Intrinsic::amdgcn_mfma_i32_32x32x4i8:
+ case Intrinsic::amdgcn_mfma_i32_32x32x8i8:
+ case Intrinsic::amdgcn_mfma_f32_32x32x2bf16:
+ case Intrinsic::amdgcn_mfma_f32_32x32x4bf16:
+
+ case Intrinsic::amdgcn_mfma_f32_4x4x4bf16_1k:
+ case Intrinsic::amdgcn_mfma_f32_16x16x4bf16_1k:
+ case Intrinsic::amdgcn_mfma_f32_16x16x16bf16_1k:
+ case Intrinsic::amdgcn_mfma_f32_32x32x4bf16_1k:
+ case Intrinsic::amdgcn_mfma_f32_32x32x8bf16_1k:
+
+ case Intrinsic::amdgcn_mfma_f64_16x16x4f64:
+ case Intrinsic::amdgcn_mfma_f64_4x4x4f64:
+
+ case Intrinsic::amdgcn_mfma_i32_16x16x32_i8:
+ case Intrinsic::amdgcn_mfma_i32_32x32x16_i8:
+ case Intrinsic::amdgcn_mfma_f32_16x16x8_xf32:
+ case Intrinsic::amdgcn_mfma_f32_32x32x4_xf32:
+
+ case Intrinsic::amdgcn_mfma_f32_16x16x32_bf8_bf8:
+ case Intrinsic::amdgcn_mfma_f32_16x16x32_bf8_fp8:
+ case Intrinsic::amdgcn_mfma_f32_16x16x32_fp8_bf8:
+ case Intrinsic::amdgcn_mfma_f32_16x16x32_fp8_fp8:
+
+ case Intrinsic::amdgcn_mfma_f32_32x32x16_bf8_bf8:
+ case Intrinsic::amdgcn_mfma_f32_32x32x16_bf8_fp8:
+ case Intrinsic::amdgcn_mfma_f32_32x32x16_fp8_bf8:
+ case Intrinsic::amdgcn_mfma_f32_32x32x16_fp8_fp8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+namespace llvm {
+class AMDGPUTargetVerify : public TargetVerify {
+public:
+ Module *Mod;
+
+ DominatorTree *DT;
+ PostDominatorTree *PDT;
+ UniformityInfo *UA;
+
+ AMDGPUTargetVerify(Module *Mod, DominatorTree *DT, PostDominatorTree *PDT, UniformityInfo *UA)
+ : TargetVerify(Mod), Mod(Mod), DT(DT), PDT(PDT), UA(UA) {}
+
+ void run(Function &F);
+};
+
+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);
+}
+
+static bool isShader(CallingConv::ID CC) {
+ switch(CC) {
+ case CallingConv::AMDGPU_VS:
+ case CallingConv::AMDGPU_LS:
+ case CallingConv::AMDGPU_HS:
+ case CallingConv::AMDGPU_ES:
+ case CallingConv::AMDGPU_GS:
+ case CallingConv::AMDGPU_PS:
+ case CallingConv::AMDGPU_CS_Chain:
+ case CallingConv::AMDGPU_CS_ChainPreserve:
+ case CallingConv::AMDGPU_CS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void AMDGPUTargetVerify::run(Function &F) {
+ // Ensure shader calling convention returns void
+ if (isShader(F.getCallingConv()))
+ Check(F.getReturnType() == Type::getVoidTy(F.getContext()), "Shaders must return void");
+
+ for (auto &BB : F) {
+
+ for (auto &I : BB) {
+ if (MarkUniform)
+ outs() << UA->isUniform(&I) << ' ' << I << '\n';
+
+ // 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));
+
+ // Ensure no store to const memory
+ if (auto *SI = dyn_cast<StoreInst>(&I))
+ {
+ unsigned AS = SI->getPointerAddressSpace();
+ Check(AS != 4, "Write to const memory", SI);
+ }
+
+ // Ensure no kernel to kernel calls.
+ if (auto *CI = dyn_cast<CallInst>(&I))
+ {
+ CallingConv::ID CalleeCC = CI->getCallingConv();
+ if (CalleeCC == CallingConv::AMDGPU_KERNEL)
+ {
+ CallingConv::ID CallerCC = CI->getParent()->getParent()->getCallingConv();
+ Check(CallerCC != CallingConv::AMDGPU_KERNEL,
+ "A kernel may not call a kernel", CI->getParent()->getParent());
+ }
+ }
+
+ // Ensure MFMA is not in control flow with diverging operands
+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ if (isMFMA(II->getIntrinsicID())) {
+ bool InControlFlow = false;
+ for (const auto &P : predecessors(&BB))
+ if (!PDT->dominates(&BB, P)) {
+ InControlFlow = true;
+ break;
+ }
+ for (const auto &S : successors(&BB))
+ if (!DT->dominates(&BB, S)) {
+ InControlFlow = true;
+ break;
+ }
+ if (InControlFlow) {
+ // If operands to MFMA are not uniform, MFMA cannot be in control flow
+ bool hasUniformOperands = true;
+ for (unsigned i = 0; i < II->getNumOperands(); i++) {
+ if (!UA->isUniform(II->getOperand(i))) {
+ dbgs() << "Not uniform: " << *II->getOperand(i) << '\n';
+ hasUniformOperands = false;
+ }
+ }
+ if (!hasUniformOperands) Check(false, "MFMA in control flow", II);
+ //else Check(false, "MFMA in control flow (uniform operands)", II);
+ }
+ //else Check(false, "MFMA not in control flow", II);
+ }
+ }
+ }
+ }
+}
+
+PreservedAnalyses AMDGPUTargetVerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
+
+ auto *Mod = F.getParent();
+
+ auto UA = &AM.getResult<UniformityInfoAnalysis>(F);
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
+
+ AMDGPUTargetVerify TV(Mod, DT, PDT, UA);
+ TV.run(F);
+
+ dbgs() << TV.MessagesStr.str();
+ if (!TV.MessagesStr.str().empty()) {
+ F.getParent()->IsValid = false;
+ }
+
+ return PreservedAnalyses::all();
+}
+} // namespace llvm
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index 09a3096602fc3..bcfea0bf8ac94 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -110,6 +110,7 @@ add_llvm_target(AMDGPUCodeGen
AMDGPUTargetMachine.cpp
AMDGPUTargetObjectFile.cpp
AMDGPUTargetTransformInfo.cpp
+ AMDGPUTargetVerifier.cpp
AMDGPUWaitSGPRHazards.cpp
AMDGPUUnifyDivergentExitNodes.cpp
AMDGPUUnifyMetadata.cpp
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
new file mode 100644
index 0000000000000..f56ff992a56c2
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
@@ -0,0 +1,62 @@
+; RUN: not llvm-tgt-verify %s -mtriple=amdgcn |& FileCheck %s
+
+define amdgpu_kernel void @test_mfma_f32_32x32x1f32_vecarg(ptr addrspace(1) %arg) #0 {
+; CHECK: Not uniform: %in.f32 = load <32 x float>, ptr addrspace(1) %gep, align 128
+; CHECK-NEXT: MFMA in control flow
+; CHECK-NEXT: %mfma = tail call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float 1.000000e+00, float 2.000000e+00, <32 x float> %in.f32, i32 1, i32 2, i32 3)
+s:
+ %tid = call i32 @llvm.amdgcn.workitem.id.x()
+ %gep = getelementptr inbounds <32 x float>, ptr addrspace(1) %arg, i32 %tid
+ %in.i32 = load <32 x i32>, ptr addrspace(1) %gep
+ %in.f32 = load <32 x float>, ptr addrspace(1) %gep
+
+ %0 = icmp eq <32 x i32> %in.i32, zeroinitializer
+ %div.br = extractelement <32 x i1> %0, i32 0
+ br i1 %div.br, label %if.3, label %else.0
+
+if.3:
+ br label %join
+
+else.0:
+ %mfma = tail call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float 1.000000e+00, float 2.000000e+00, <32 x float> %in.f32, i32 1, i32 2, i32 3)
+ br label %join
+
+join:
+ ret void
+}
+
+define amdgpu_cs i32 @shader() {
+; CHECK: Shaders must return void
+ ret i32 0
+}
+
+define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {
+; CHECK: Undefined behavior: Write to memory in const addrspace
+; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out, align 4
+; CHECK-NEXT: Write to const memory
+; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out, align 4
+ %r = add i32 %a, %b
+ store i32 %r, ptr addrspace(4) %out
+ ret void
+}
+
+define amdgpu_kernel void @kernel_callee(ptr %x) {
+ ret void
+}
+
+define amdgpu_kernel void @kernel_caller(ptr %x) {
+; CHECK: A kernel may not call a kernel
+; CHECK-NEXT: ptr @kernel_caller
+ call amdgpu_kernel void @kernel_callee(ptr %x)
+ ret void
+}
+
+
+; Function Attrs: nounwind
+define i65 @invalid_type(i65 %x) #0 {
+; CHECK: Int type is invalid.
+; CHECK-NEXT: %tmp2 = ashr i65 %x, 64
+entry:
+ %tmp2 = ashr i65 %x, 64
+ ret i65 %tmp2
+}
diff --git a/llvm/tools/llvm-tgt-verify/CMakeLists.txt b/llvm/tools/llvm-tgt-verify/CMakeLists.txt
new file mode 100644
index 0000000000000..fe47c85e6cdce
--- /dev/null
+++ b/llvm/tools/llvm-tgt-verify/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(LLVM_LINK_COMPONENTS
+ AllTargetsAsmParsers
+ AllTargetsCodeGens
+ AllTargetsDescs
+ AllTargetsInfos
+ Analysis
+ AsmPrinter
+ CodeGen
+ CodeGenTypes
+ Core
+ IRPrinter
+ IRReader
+ MC
+ MIRParser
+ Passes
+ Remarks
+ ScalarOpts
+ SelectionDAG
+ Support
+ Target
+ TargetParser
+ TransformUtils
+ Vectorize
+ )
+
+add_llvm_tool(llvm-tgt-verify
+ llvm-tgt-verify.cpp
+
+ DEPENDS
+ intrinsics_gen
+ SUPPORT_PLUGINS
+ )
+
+export_executable_symbols_for_plugins(llc)
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
new file mode 100644
index 0000000000000..68422abd6f4cc
--- /dev/null
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -0,0 +1,172 @@
+//===--- llvm-isel-fuzzer.cpp - Fuzzer for instruction selection ----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Tool to fuzz instruction selection using libFuzzer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/InitializePasses.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/Lint.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/StandardInstrumentations.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetVerifier.h"
+
+#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
+
+#define DEBUG_TYPE "isel-fuzzer"
+
+using namespace llvm;
+
+static codegen::RegisterCodeGenFlags CGF;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+
+static cl::opt<bool>
+ StacktraceAbort("stacktrace-abort",
+ cl::desc("Turn on stacktrace"), cl::init(false));
+
+static cl::opt<bool>
+ NoLint("no-lint",
+ cl::desc("Turn off Lint"), cl::init(false));
+
+static cl::opt<bool>
+ NoVerify("no-verifier",
+ cl::desc("Turn off Verifier"), cl::init(false));
+
+static cl::opt<char>
+ OptLevel("O",
+ cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+ "(default = '-O2')"),
+ cl::Prefix, cl::init('2'));
+
+static cl::opt<std::string>
+ TargetTriple("mtriple", cl::desc("Override target triple for module"));
+
+static std::unique_ptr<TargetMachine> TM;
+
+static void handleLLVMFatalError(void *, const char *Message, bool) {
+ if (StacktraceAbort) {
+ dbgs() << "LLVM ERROR: " << Message << "\n"
+ << "Aborting.\n";
+ abort();
+ }
+}
+
+int main(int argc, char **argv) {
+ StringRef ExecName = argv[0];
+ InitLLVM X(argc, argv);
+
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmPrinters();
+ InitializeAllAsmParsers();
+
+ PassRegistry *Registry = PassRegistry::getPassRegistry();
+ initializeCore(*Registry);
+ initializeCodeGen(*Registry);
+ initializeAnalysis(*Registry);
+ initializeTarget(*Registry);
+
+ cl::ParseCommandLineOptions(argc, argv);
+
+ if (TargetTriple.empty()) {
+ errs() << ExecName << ": -mtriple must be specified\n";
+ exit(1);
+ }
+
+ CodeGenOptLevel OLvl;
+ if (auto Level = CodeGenOpt::parseLevel(OptLevel)) {
+ OLvl = *Level;
+ } else {
+ errs() << ExecName << ": invalid optimization level.\n";
+ return 1;
+ }
+ ExitOnError ExitOnErr(std::string(ExecName) + ": error:");
+ TM = ExitOnErr(codegen::createTargetMachineForTriple(
+ Triple::normalize(TargetTriple), OLvl));
+ assert(TM && "Could not allocate target machine!");
+
+ // Make sure we print the summary and the current unit when LLVM errors out.
+ install_fatal_error_handler(handleLLVMFatalError, nullptr);
+
+ LLVMContext Context;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
+ if (!M) {
+ errs() << "Invalid mod\n";
+ return 1;
+ }
+ auto S = Triple::normalize(TargetTriple);
+ M->setTargetTriple(S);
+
+ PassInstrumentationCallbacks PIC;
+ StandardInstrumentations SI(Context, false/*debug PM*/,
+ false);
+ registerCodeGenCallback(PIC, *TM);
+
+ ModulePassManager MPM;
+ FunctionPassManager FPM;
+ //TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
+
+ MachineFunctionAnalysisManager MFAM;
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+ PassBuilder PB(TM.get(), PipelineTuningOptions(), std::nullopt, &PIC);
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.registerMachineFunctionAnalyses(MFAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
+
+ SI.registerCallbacks(PIC, &MAM);
+
+ //FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
+
+ Triple TT(M->getTargetTriple());
+ if (!NoLint)
+ FPM.addPass(LintPass());
+ if (!NoVerify)
+ MPM.addPass(VerifierPass());
+ if (TT.isAMDGPU())
+ FPM.addPass(AMDGPUTargetVerifierPass());
+ else if (false) {} // ...
+ else
+ FPM.addPass(TargetVerifierPass());
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+
+ MPM.run(*M, MAM);
+
+ if (!M->IsValid)
+ return 1;
+
+ return 0;
+}
>From a808efce8d90524845a44ffa5b90adb6741e488d Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Mon, 3 Feb 2025 07:15:12 -0800
Subject: [PATCH 02/12] Add hook for target verifier in llc,opt
---
.../llvm/Passes/StandardInstrumentations.h | 6 ++++--
llvm/include/llvm/Target/TargetVerifier.h | 1 +
.../TargetVerify/AMDGPUTargetVerifier.h | 18 ++++++++++++++++++
llvm/lib/LTO/LTOBackend.cpp | 2 +-
llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 2 +-
llvm/lib/Passes/CMakeLists.txt | 1 +
llvm/lib/Passes/PassBuilderBindings.cpp | 2 +-
llvm/lib/Passes/StandardInstrumentations.cpp | 19 +++++++++++++++----
.../Target/AMDGPU/AMDGPUTargetVerifier.cpp | 12 ++++++------
llvm/lib/Target/CMakeLists.txt | 2 ++
.../CodeGen/AMDGPU/tgt-verify-llc-fail.ll | 6 ++++++
.../CodeGen/AMDGPU/tgt-verify-llc-pass.ll | 6 ++++++
llvm/tools/llc/NewPMDriver.cpp | 2 +-
.../tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 2 +-
llvm/tools/opt/NewPMDriver.cpp | 2 +-
llvm/unittests/IR/PassManagerTest.cpp | 6 +++---
16 files changed, 68 insertions(+), 21 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
create mode 100644 llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index f7a65a88ecf5b..988fcb93b2357 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -476,7 +476,8 @@ class VerifyInstrumentation {
public:
VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
void registerCallbacks(PassInstrumentationCallbacks &PIC,
- ModuleAnalysisManager *MAM);
+ ModuleAnalysisManager *MAM,
+ FunctionAnalysisManager *FAM);
};
/// This class implements --time-trace functionality for new pass manager.
@@ -621,7 +622,8 @@ class StandardInstrumentations {
// Register all the standard instrumentation callbacks. If \p FAM is nullptr
// then PreservedCFGChecker is not enabled.
void registerCallbacks(PassInstrumentationCallbacks &PIC,
- ModuleAnalysisManager *MAM = nullptr);
+ ModuleAnalysisManager *MAM,
+ FunctionAnalysisManager *FAM);
TimePassesHandler &getTimePasses() { return TimePasses; }
};
diff --git a/llvm/include/llvm/Target/TargetVerifier.h b/llvm/include/llvm/Target/TargetVerifier.h
index e00c6a7b260c9..ad5aeb895953d 100644
--- a/llvm/include/llvm/Target/TargetVerifier.h
+++ b/llvm/include/llvm/Target/TargetVerifier.h
@@ -75,6 +75,7 @@ class TargetVerify {
MessagesStr(Messages) {}
void run(Function &F) {};
+ void run(Function &F, FunctionAnalysisManager &AM);
};
} // namespace llvm
diff --git a/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
index e6ff57629b141..d8a3fda4f87dc 100644
--- a/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
+++ b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
@@ -22,6 +22,10 @@
#include "llvm/Target/TargetVerifier.h"
+#include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/IR/Dominators.h"
+
namespace llvm {
class Function;
@@ -31,6 +35,20 @@ class AMDGPUTargetVerifierPass : public TargetVerifierPass {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+class AMDGPUTargetVerify : public TargetVerify {
+public:
+ Module *Mod;
+
+ DominatorTree *DT;
+ PostDominatorTree *PDT;
+ UniformityInfo *UA;
+
+ AMDGPUTargetVerify(Module *Mod, DominatorTree *DT, PostDominatorTree *PDT, UniformityInfo *UA)
+ : TargetVerify(Mod), Mod(Mod), DT(DT), PDT(PDT), UA(UA) {}
+
+ void run(Function &F);
+};
+
} // namespace llvm
#endif // LLVM_AMDGPU_TARGET_VERIFIER_H
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 1c764a0188eda..475e7cf45371b 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -275,7 +275,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager,
Conf.VerifyEach);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);
RegisterPassPlugins(Conf.PassPlugins, PB);
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 9e7f8187fe49c..369b003df1364 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -245,7 +245,7 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM,
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(TheModule.getContext(), DebugPassManager);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
PipelineTuningOptions PTO;
PTO.LoopVectorization = true;
PTO.SLPVectorization = true;
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index 6425f4934b210..f171377a8b270 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -29,6 +29,7 @@ add_llvm_component_library(LLVMPasses
Scalar
Support
Target
+ TargetParser
TransformUtils
Vectorize
Instrumentation
diff --git a/llvm/lib/Passes/PassBuilderBindings.cpp b/llvm/lib/Passes/PassBuilderBindings.cpp
index 933fe89e53a94..f0e1abb8cebc4 100644
--- a/llvm/lib/Passes/PassBuilderBindings.cpp
+++ b/llvm/lib/Passes/PassBuilderBindings.cpp
@@ -76,7 +76,7 @@ static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes,
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
// Run the pipeline.
if (Fun) {
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index dc1dd5d9c7f4c..7b15f89e361b8 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -45,6 +45,7 @@
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/xxhash.h"
+#include "llvm/Target/TargetVerifier.h"
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -1454,9 +1455,10 @@ void PreservedCFGCheckerInstrumentation::registerCallbacks(
}
void VerifyInstrumentation::registerCallbacks(PassInstrumentationCallbacks &PIC,
- ModuleAnalysisManager *MAM) {
+ ModuleAnalysisManager *MAM,
+ FunctionAnalysisManager *FAM) {
PIC.registerAfterPassCallback(
- [this, MAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
+ [this, MAM, FAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
if (isIgnored(P) || P == "VerifierPass")
return;
const auto *F = unwrapIR<Function>(IR);
@@ -1473,6 +1475,15 @@ void VerifyInstrumentation::registerCallbacks(PassInstrumentationCallbacks &PIC,
report_fatal_error(formatv("Broken function found after pass "
"\"{0}\", compilation aborted!",
P));
+
+ if (FAM) {
+ TargetVerify TV(const_cast<Module*>(F->getParent()));
+ TV.run(*const_cast<Function*>(F), *FAM);
+ if (!F->getParent()->IsValid)
+ report_fatal_error(formatv("Broken function found after pass "
+ "\"{0}\", compilation aborted!",
+ P));
+ }
} else {
const auto *M = unwrapIR<Module>(IR);
if (!M) {
@@ -2512,7 +2523,7 @@ void PrintCrashIRInstrumentation::registerCallbacks(
}
void StandardInstrumentations::registerCallbacks(
- PassInstrumentationCallbacks &PIC, ModuleAnalysisManager *MAM) {
+ PassInstrumentationCallbacks &PIC, ModuleAnalysisManager *MAM, FunctionAnalysisManager *FAM) {
PrintIR.registerCallbacks(PIC);
PrintPass.registerCallbacks(PIC);
TimePasses.registerCallbacks(PIC);
@@ -2521,7 +2532,7 @@ void StandardInstrumentations::registerCallbacks(
PrintChangedIR.registerCallbacks(PIC);
PseudoProbeVerification.registerCallbacks(PIC);
if (VerifyEach)
- Verify.registerCallbacks(PIC, MAM);
+ Verify.registerCallbacks(PIC, MAM, FAM);
PrintChangedDiff.registerCallbacks(PIC);
WebsiteChangeReporter.registerCallbacks(PIC);
ChangeTester.registerCallbacks(PIC);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index 585b19065c142..e6cdec7160229 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -14,8 +14,8 @@
using namespace llvm;
-static cl::opt<bool>
-MarkUniform("mark-uniform", cl::desc("Mark instructions as uniform"), cl::init(false));
+//static cl::opt<bool>
+//MarkUniform("mark-uniform", cl::desc("Mark instructions as uniform"), cl::init(false));
// Check - We know that cond should be true, if not print an error message.
#define Check(C, ...) \
@@ -81,7 +81,7 @@ static bool isMFMA(unsigned IID) {
}
namespace llvm {
-class AMDGPUTargetVerify : public TargetVerify {
+/*class AMDGPUTargetVerify : public TargetVerify {
public:
Module *Mod;
@@ -93,7 +93,7 @@ class AMDGPUTargetVerify : public TargetVerify {
: TargetVerify(Mod), Mod(Mod), DT(DT), PDT(PDT), UA(UA) {}
void run(Function &F);
-};
+};*/
static bool IsValidInt(const Type *Ty) {
return Ty->isIntegerTy(1) ||
@@ -129,8 +129,8 @@ void AMDGPUTargetVerify::run(Function &F) {
for (auto &BB : F) {
for (auto &I : BB) {
- if (MarkUniform)
- outs() << UA->isUniform(&I) << ' ' << I << '\n';
+ //if (MarkUniform)
+ //outs() << UA->isUniform(&I) << ' ' << I << '\n';
// Ensure integral types are valid: i8, i16, i32, i64, i128
if (I.getType()->isIntegerTy())
diff --git a/llvm/lib/Target/CMakeLists.txt b/llvm/lib/Target/CMakeLists.txt
index 9472288229cac..f2a5d545ce84f 100644
--- a/llvm/lib/Target/CMakeLists.txt
+++ b/llvm/lib/Target/CMakeLists.txt
@@ -7,6 +7,8 @@ add_llvm_component_library(LLVMTarget
TargetLoweringObjectFile.cpp
TargetMachine.cpp
TargetMachineC.cpp
+ TargetVerifier.cpp
+ AMDGPU/AMDGPUTargetVerifier.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Target
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
new file mode 100644
index 0000000000000..584097d7bc134
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
@@ -0,0 +1,6 @@
+; RUN: not not llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -enable-new-pm -verify-each -o - < %s 2>&1 | FileCheck %s
+
+define amdgpu_cs i32 @nonvoid_shader() {
+; CHECK: LLVM ERROR
+ ret i32 0
+}
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
new file mode 100644
index 0000000000000..0c3a5fe5ac4a5
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
@@ -0,0 +1,6 @@
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -enable-new-pm -verify-each %s -o - 2>&1 | FileCheck %s
+
+define amdgpu_cs void @void_shader() {
+; CHECK: ModuleToFunctionPassAdaptor
+ ret void
+}
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index fa82689ecf9ae..a060d16e74958 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -126,7 +126,7 @@ int llvm::compileModuleWithNewPM(
PB.registerLoopAnalyses(LAM);
PB.registerMachineFunctionAnalyses(MFAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index 68422abd6f4cc..3352d07deff2f 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -147,7 +147,7 @@ int main(int argc, char **argv) {
PB.registerMachineFunctionAnalyses(MFAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
//FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 7d168a6ceb17c..a8977d80bdf44 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -423,7 +423,7 @@ bool llvm::runPassPipeline(
PrintPassOpts.SkipAnalyses = DebugPM == DebugLogging::Quiet;
StandardInstrumentations SI(M.getContext(), DebugPM != DebugLogging::None,
VK == VerifierKind::EachPass, PrintPassOpts);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
DebugifyEachInstrumentation Debugify;
DebugifyStatsMap DIStatsMap;
DebugInfoPerPass DebugInfoBeforePass;
diff --git a/llvm/unittests/IR/PassManagerTest.cpp b/llvm/unittests/IR/PassManagerTest.cpp
index a6487169224c2..bb4db6120035f 100644
--- a/llvm/unittests/IR/PassManagerTest.cpp
+++ b/llvm/unittests/IR/PassManagerTest.cpp
@@ -828,7 +828,7 @@ TEST_F(PassManagerTest, FunctionPassCFGChecker) {
FunctionPassManager FPM;
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
@@ -877,7 +877,7 @@ TEST_F(PassManagerTest, FunctionPassCFGCheckerInvalidateAnalysis) {
FunctionPassManager FPM;
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
@@ -945,7 +945,7 @@ TEST_F(PassManagerTest, FunctionPassCFGCheckerWrapped) {
FunctionPassManager FPM;
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
>From 64d001858efc994e965071cd319d268b934a6eb3 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Wed, 16 Apr 2025 10:19:00 -0400
Subject: [PATCH 03/12] Run AMDGPUTargetVerifier within AMDGPU pipeline. Move
IsValid from Module to TargetVerify.
---
clang/lib/CodeGen/BackendUtil.cpp | 2 +-
llvm/include/llvm/IR/Module.h | 4 ----
llvm/include/llvm/Target/TargetVerifier.h | 2 ++
llvm/lib/IR/Verifier.cpp | 4 ++--
llvm/lib/Passes/StandardInstrumentations.cpp | 2 +-
llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 5 +++++
llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp | 3 ++-
llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 6 +++---
8 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index f7eb853beb23c..9a1c922f5ddef 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -922,7 +922,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
TheModule->getContext(),
(CodeGenOpts.DebugPassManager || DebugPassStructure),
CodeGenOpts.VerifyEach, PrintPassOpts);
- SI.registerCallbacks(PIC, &MAM);
+ SI.registerCallbacks(PIC, &MAM, &FAM);
PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
// Handle the assignment tracking feature options.
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 03c0cf1cf0924..91ccd76c41e07 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -214,10 +214,6 @@ class LLVM_ABI Module {
/// @name Constructors
/// @{
public:
- /// Is this Module valid as determined by one of the verification passes
- /// i.e. Lint, Verifier, TargetVerifier.
- bool IsValid = true;
-
/// Is this Module using intrinsics to record the position of debugging
/// information, or non-intrinsic records? See IsNewDbgInfoFormat in
/// \ref BasicBlock.
diff --git a/llvm/include/llvm/Target/TargetVerifier.h b/llvm/include/llvm/Target/TargetVerifier.h
index ad5aeb895953d..2d0c039132c35 100644
--- a/llvm/include/llvm/Target/TargetVerifier.h
+++ b/llvm/include/llvm/Target/TargetVerifier.h
@@ -70,6 +70,8 @@ class TargetVerify {
std::string Messages;
raw_string_ostream MessagesStr;
+ bool IsValid = true;
+
TargetVerify(Module *Mod)
: Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())),
MessagesStr(Messages) {}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 9d21ca182ca13..d7c514610b4ba 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -7801,7 +7801,7 @@ VerifierAnalysis::Result VerifierAnalysis::run(Function &F,
PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
auto Res = AM.getResult<VerifierAnalysis>(M);
if (Res.IRBroken || Res.DebugInfoBroken) {
- M.IsValid = false;
+ //M.IsValid = false;
if (VerifyAbortOnError && FatalErrors)
report_fatal_error("Broken module found, compilation aborted!");
}
@@ -7812,7 +7812,7 @@ PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
PreservedAnalyses VerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
auto res = AM.getResult<VerifierAnalysis>(F);
if (res.IRBroken) {
- F.getParent()->IsValid = false;
+ //F.getParent()->IsValid = false;
if (VerifyAbortOnError && FatalErrors)
report_fatal_error("Broken function found, compilation aborted!");
}
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 7b15f89e361b8..879d657c87695 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -1479,7 +1479,7 @@ void VerifyInstrumentation::registerCallbacks(PassInstrumentationCallbacks &PIC,
if (FAM) {
TargetVerify TV(const_cast<Module*>(F->getParent()));
TV.run(*const_cast<Function*>(F), *FAM);
- if (!F->getParent()->IsValid)
+ if (!TV.IsValid)
report_fatal_error(formatv("Broken function found after pass "
"\"{0}\", compilation aborted!",
P));
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 90e3489ced923..6ec34d6a0fdbf 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -90,6 +90,7 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
#include "llvm/Transforms/HipStdPar/HipStdPar.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
@@ -1298,6 +1299,8 @@ void AMDGPUPassConfig::addIRPasses() {
addPass(createLICMPass());
}
+ //addPass(AMDGPUTargetVerifierPass());
+
TargetPassConfig::addIRPasses();
// EarlyCSE is not always strong enough to clean up what LSR produces. For
@@ -2040,6 +2043,8 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(AddIRPass &addPass) const {
// but EarlyCSE can do neither of them.
if (isPassEnabled(EnableScalarIRPasses))
addEarlyCSEOrGVNPass(addPass);
+
+ addPass(AMDGPUTargetVerifierPass());
}
void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(AddIRPass &addPass) const {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index e6cdec7160229..c70a6d1b6fa66 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -205,7 +205,8 @@ PreservedAnalyses AMDGPUTargetVerifierPass::run(Function &F, FunctionAnalysisMan
dbgs() << TV.MessagesStr.str();
if (!TV.MessagesStr.str().empty()) {
- F.getParent()->IsValid = false;
+ TV.IsValid = false;
+ return PreservedAnalyses::none();
}
return PreservedAnalyses::all();
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index 3352d07deff2f..fbe7f6089ff18 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -163,9 +163,9 @@ int main(int argc, char **argv) {
FPM.addPass(TargetVerifierPass());
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- MPM.run(*M, MAM);
-
- if (!M->IsValid)
+ auto PA = MPM.run(*M, MAM);
+ auto PAC = PA.getChecker<VerifierAnalysis>();
+ if (!PAC.preserved())
return 1;
return 0;
>From fdae3025942584d0085deb3442f40471548defe5 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Wed, 16 Apr 2025 11:08:20 -0400
Subject: [PATCH 04/12] Remove cmd line options that aren't required. Make
error message explicit.
---
llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll | 4 ++--
llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
index 584097d7bc134..c5e59d4a2369e 100644
--- a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-fail.ll
@@ -1,6 +1,6 @@
-; RUN: not not llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -enable-new-pm -verify-each -o - < %s 2>&1 | FileCheck %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -o - < %s 2>&1 | FileCheck %s
define amdgpu_cs i32 @nonvoid_shader() {
-; CHECK: LLVM ERROR
+; CHECK: Shaders must return void
ret i32 0
}
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
index 0c3a5fe5ac4a5..8a503b7624a73 100644
--- a/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify-llc-pass.ll
@@ -1,6 +1,6 @@
-; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -enable-new-pm -verify-each %s -o - 2>&1 | FileCheck %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm %s -o - 2>&1 | FileCheck %s --allow-empty
define amdgpu_cs void @void_shader() {
-; CHECK: ModuleToFunctionPassAdaptor
+; CHECK-NOT: Shaders must return void
ret void
}
>From 5ceda58cc5b5d7372c6e43cbdf583f0dda87b956 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 19:36:34 -0400
Subject: [PATCH 05/12] Return Verifier none status through PreservedAnalyses
on fail.
---
llvm/lib/Analysis/Lint.cpp | 4 +++-
llvm/lib/IR/Verifier.cpp | 2 ++
llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 8 +++++---
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp
index f05e36e2025d4..c8e38963e5974 100644
--- a/llvm/lib/Analysis/Lint.cpp
+++ b/llvm/lib/Analysis/Lint.cpp
@@ -742,9 +742,11 @@ PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) {
Lint L(Mod, DL, AA, AC, DT, TLI);
L.visit(F);
dbgs() << L.MessagesStr.str();
- if (AbortOnError && !L.MessagesStr.str().empty())
+ if (AbortOnError && !L.MessagesStr.str().empty()) {
report_fatal_error(
"linter found errors, aborting. (enabled by abort-on-error)", false);
+ return PreservedAnalyses::none();
+ }
return PreservedAnalyses::all();
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index d7c514610b4ba..51f6dec53b70f 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -7804,6 +7804,7 @@ PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
//M.IsValid = false;
if (VerifyAbortOnError && FatalErrors)
report_fatal_error("Broken module found, compilation aborted!");
+ return PreservedAnalyses::none();
}
return PreservedAnalyses::all();
@@ -7815,6 +7816,7 @@ PreservedAnalyses VerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
//F.getParent()->IsValid = false;
if (VerifyAbortOnError && FatalErrors)
report_fatal_error("Broken function found, compilation aborted!");
+ return PreservedAnalyses::none();
}
return PreservedAnalyses::all();
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index fbe7f6089ff18..042824ac37fea 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -164,9 +164,11 @@ int main(int argc, char **argv) {
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
auto PA = MPM.run(*M, MAM);
- auto PAC = PA.getChecker<VerifierAnalysis>();
- if (!PAC.preserved())
- return 1;
+ {
+ auto PAC = PA.getChecker<VerifierAnalysis>();
+ if (!PAC.preserved())
+ return 1;
+ }
return 0;
}
>From 99c29069cdaf68c92ce7f25ca2f730bf738ca324 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 21:16:02 -0400
Subject: [PATCH 06/12] Rebase update.
---
llvm/include/llvm/Target/TargetVerifier.h | 2 +-
llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Target/TargetVerifier.h b/llvm/include/llvm/Target/TargetVerifier.h
index 2d0c039132c35..fe683311b901c 100644
--- a/llvm/include/llvm/Target/TargetVerifier.h
+++ b/llvm/include/llvm/Target/TargetVerifier.h
@@ -73,7 +73,7 @@ class TargetVerify {
bool IsValid = true;
TargetVerify(Module *Mod)
- : Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())),
+ : Mod(Mod), TT(Mod->getTargetTriple()),
MessagesStr(Messages) {}
void run(Function &F) {};
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index 042824ac37fea..627bc51ef3a43 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -123,7 +123,7 @@ int main(int argc, char **argv) {
return 1;
}
auto S = Triple::normalize(TargetTriple);
- M->setTargetTriple(S);
+ M->setTargetTriple(Triple(S));
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI(Context, false/*debug PM*/,
@@ -153,7 +153,7 @@ int main(int argc, char **argv) {
Triple TT(M->getTargetTriple());
if (!NoLint)
- FPM.addPass(LintPass());
+ FPM.addPass(LintPass(false));
if (!NoVerify)
MPM.addPass(VerifierPass());
if (TT.isAMDGPU())
>From 3ea7eae48a6addbf711716e7a819830dddc1b34a Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 22:49:52 -0400
Subject: [PATCH 07/12] Add generic TargetVerifier.
---
llvm/lib/Target/TargetVerifier.cpp | 32 ++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 llvm/lib/Target/TargetVerifier.cpp
diff --git a/llvm/lib/Target/TargetVerifier.cpp b/llvm/lib/Target/TargetVerifier.cpp
new file mode 100644
index 0000000000000..de3ff749e7c3c
--- /dev/null
+++ b/llvm/lib/Target/TargetVerifier.cpp
@@ -0,0 +1,32 @@
+#include "llvm/Target/TargetVerifier.h"
+#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
+
+#include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/IR/Dominators.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"
+
+namespace llvm {
+
+void TargetVerify::run(Function &F, FunctionAnalysisManager &AM) {
+ if (TT.isAMDGPU()) {
+ auto *UA = &AM.getResult<UniformityInfoAnalysis>(F);
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
+
+ AMDGPUTargetVerify TV(Mod, DT, PDT, UA);
+ TV.run(F);
+
+ dbgs() << TV.MessagesStr.str();
+ if (!TV.MessagesStr.str().empty()) {
+ TV.IsValid = false;
+ }
+ }
+}
+
+} // namespace llvm
>From f52c4dbc84952d97266f5f4158729e564de10240 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 23:13:14 -0400
Subject: [PATCH 08/12] Remove store to const check since it is in Lint already
---
llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp | 8 --------
llvm/test/CodeGen/AMDGPU/tgt-verify.ll | 2 --
2 files changed, 10 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index c70a6d1b6fa66..1cf2b277bee26 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -140,14 +140,6 @@ void AMDGPUTargetVerify::run(Function &F) {
Check(IsValidInt(I.getOperand(i)->getType()),
"Int type is invalid.", I.getOperand(i));
- // Ensure no store to const memory
- if (auto *SI = dyn_cast<StoreInst>(&I))
- {
- unsigned AS = SI->getPointerAddressSpace();
- Check(AS != 4, "Write to const memory", SI);
- }
-
- // Ensure no kernel to kernel calls.
if (auto *CI = dyn_cast<CallInst>(&I))
{
CallingConv::ID CalleeCC = CI->getCallingConv();
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
index f56ff992a56c2..c628abbde11d1 100644
--- a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
@@ -32,8 +32,6 @@ define amdgpu_cs i32 @shader() {
define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {
; CHECK: Undefined behavior: Write to memory in const addrspace
-; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out, align 4
-; CHECK-NEXT: Write to const memory
; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out, align 4
%r = add i32 %a, %b
store i32 %r, ptr addrspace(4) %out
>From 5c9a4ab3895d6939b12386d1db2081ca388df01a Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 23:14:38 -0400
Subject: [PATCH 09/12] Add chain followed by unreachable check
---
llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp | 6 ++++++
llvm/test/CodeGen/AMDGPU/tgt-verify.ll | 10 ++++++++++
2 files changed, 16 insertions(+)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index 1cf2b277bee26..8ea773bc0e66f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -142,6 +142,7 @@ void AMDGPUTargetVerify::run(Function &F) {
if (auto *CI = dyn_cast<CallInst>(&I))
{
+ // Ensure no kernel to kernel calls.
CallingConv::ID CalleeCC = CI->getCallingConv();
if (CalleeCC == CallingConv::AMDGPU_KERNEL)
{
@@ -149,6 +150,11 @@ void AMDGPUTargetVerify::run(Function &F) {
Check(CallerCC != CallingConv::AMDGPU_KERNEL,
"A kernel may not call a kernel", CI->getParent()->getParent());
}
+
+ // Ensure chain intrinsics are followed by unreachables.
+ if (CI->getIntrinsicID() == Intrinsic::amdgcn_cs_chain)
+ Check(isa_and_present<UnreachableInst>(CI->getNextNode()),
+ "llvm.amdgcn.cs.chain must be followed by unreachable", CI);
}
// Ensure MFMA is not in control flow with diverging operands
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
index c628abbde11d1..e620df94ccde4 100644
--- a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
@@ -58,3 +58,13 @@ entry:
%tmp2 = ashr i65 %x, 64
ret i65 %tmp2
}
+
+declare void @llvm.amdgcn.cs.chain.v3i32(ptr, i32, <3 x i32>, <3 x i32>, i32, ...)
+declare amdgpu_cs_chain void @chain_callee(<3 x i32> inreg, <3 x i32>)
+
+define amdgpu_cs void @no_unreachable(<3 x i32> inreg %a, <3 x i32> %b) {
+; CHECK: llvm.amdgcn.cs.chain must be followed by unreachable
+; CHECK-NEXT: call void (ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.v3i32.v3i32(ptr @chain_callee, i32 -1, <3 x i32> inreg %a, <3 x i32> %b, i32 0)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr @chain_callee, i32 -1, <3 x i32> inreg %a, <3 x i32> %b, i32 0)
+ ret void
+}
>From 0ff03f792c018e4fd0c11de9da4d3353617707f5 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Sat, 19 Apr 2025 23:26:19 -0400
Subject: [PATCH 10/12] Remove mfma check
---
.../Target/AMDGPU/AMDGPUTargetVerifier.cpp | 89 -------------------
llvm/test/CodeGen/AMDGPU/tgt-verify.ll | 25 ------
2 files changed, 114 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index 8ea773bc0e66f..684ced5bba574 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -14,9 +14,6 @@
using namespace llvm;
-//static cl::opt<bool>
-//MarkUniform("mark-uniform", cl::desc("Mark instructions as uniform"), cl::init(false));
-
// Check - We know that cond should be true, if not print an error message.
#define Check(C, ...) \
do { \
@@ -26,60 +23,6 @@ using namespace llvm;
} \
} while (false)
-static bool isMFMA(unsigned IID) {
- switch (IID) {
- case Intrinsic::amdgcn_mfma_f32_4x4x1f32:
- case Intrinsic::amdgcn_mfma_f32_4x4x4f16:
- case Intrinsic::amdgcn_mfma_i32_4x4x4i8:
- case Intrinsic::amdgcn_mfma_f32_4x4x2bf16:
-
- case Intrinsic::amdgcn_mfma_f32_16x16x1f32:
- case Intrinsic::amdgcn_mfma_f32_16x16x4f32:
- case Intrinsic::amdgcn_mfma_f32_16x16x4f16:
- case Intrinsic::amdgcn_mfma_f32_16x16x16f16:
- case Intrinsic::amdgcn_mfma_i32_16x16x4i8:
- case Intrinsic::amdgcn_mfma_i32_16x16x16i8:
- case Intrinsic::amdgcn_mfma_f32_16x16x2bf16:
- case Intrinsic::amdgcn_mfma_f32_16x16x8bf16:
-
- case Intrinsic::amdgcn_mfma_f32_32x32x1f32:
- case Intrinsic::amdgcn_mfma_f32_32x32x2f32:
- case Intrinsic::amdgcn_mfma_f32_32x32x4f16:
- case Intrinsic::amdgcn_mfma_f32_32x32x8f16:
- case Intrinsic::amdgcn_mfma_i32_32x32x4i8:
- case Intrinsic::amdgcn_mfma_i32_32x32x8i8:
- case Intrinsic::amdgcn_mfma_f32_32x32x2bf16:
- case Intrinsic::amdgcn_mfma_f32_32x32x4bf16:
-
- case Intrinsic::amdgcn_mfma_f32_4x4x4bf16_1k:
- case Intrinsic::amdgcn_mfma_f32_16x16x4bf16_1k:
- case Intrinsic::amdgcn_mfma_f32_16x16x16bf16_1k:
- case Intrinsic::amdgcn_mfma_f32_32x32x4bf16_1k:
- case Intrinsic::amdgcn_mfma_f32_32x32x8bf16_1k:
-
- case Intrinsic::amdgcn_mfma_f64_16x16x4f64:
- case Intrinsic::amdgcn_mfma_f64_4x4x4f64:
-
- case Intrinsic::amdgcn_mfma_i32_16x16x32_i8:
- case Intrinsic::amdgcn_mfma_i32_32x32x16_i8:
- case Intrinsic::amdgcn_mfma_f32_16x16x8_xf32:
- case Intrinsic::amdgcn_mfma_f32_32x32x4_xf32:
-
- case Intrinsic::amdgcn_mfma_f32_16x16x32_bf8_bf8:
- case Intrinsic::amdgcn_mfma_f32_16x16x32_bf8_fp8:
- case Intrinsic::amdgcn_mfma_f32_16x16x32_fp8_bf8:
- case Intrinsic::amdgcn_mfma_f32_16x16x32_fp8_fp8:
-
- case Intrinsic::amdgcn_mfma_f32_32x32x16_bf8_bf8:
- case Intrinsic::amdgcn_mfma_f32_32x32x16_bf8_fp8:
- case Intrinsic::amdgcn_mfma_f32_32x32x16_fp8_bf8:
- case Intrinsic::amdgcn_mfma_f32_32x32x16_fp8_fp8:
- return true;
- default:
- return false;
- }
-}
-
namespace llvm {
/*class AMDGPUTargetVerify : public TargetVerify {
public:
@@ -129,8 +72,6 @@ void AMDGPUTargetVerify::run(Function &F) {
for (auto &BB : F) {
for (auto &I : BB) {
- //if (MarkUniform)
- //outs() << UA->isUniform(&I) << ' ' << I << '\n';
// Ensure integral types are valid: i8, i16, i32, i64, i128
if (I.getType()->isIntegerTy())
@@ -156,36 +97,6 @@ void AMDGPUTargetVerify::run(Function &F) {
Check(isa_and_present<UnreachableInst>(CI->getNextNode()),
"llvm.amdgcn.cs.chain must be followed by unreachable", CI);
}
-
- // Ensure MFMA is not in control flow with diverging operands
- if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
- if (isMFMA(II->getIntrinsicID())) {
- bool InControlFlow = false;
- for (const auto &P : predecessors(&BB))
- if (!PDT->dominates(&BB, P)) {
- InControlFlow = true;
- break;
- }
- for (const auto &S : successors(&BB))
- if (!DT->dominates(&BB, S)) {
- InControlFlow = true;
- break;
- }
- if (InControlFlow) {
- // If operands to MFMA are not uniform, MFMA cannot be in control flow
- bool hasUniformOperands = true;
- for (unsigned i = 0; i < II->getNumOperands(); i++) {
- if (!UA->isUniform(II->getOperand(i))) {
- dbgs() << "Not uniform: " << *II->getOperand(i) << '\n';
- hasUniformOperands = false;
- }
- }
- if (!hasUniformOperands) Check(false, "MFMA in control flow", II);
- //else Check(false, "MFMA in control flow (uniform operands)", II);
- }
- //else Check(false, "MFMA not in control flow", II);
- }
- }
}
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
index e620df94ccde4..62b220d7d9f49 100644
--- a/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
+++ b/llvm/test/CodeGen/AMDGPU/tgt-verify.ll
@@ -1,30 +1,5 @@
; RUN: not llvm-tgt-verify %s -mtriple=amdgcn |& FileCheck %s
-define amdgpu_kernel void @test_mfma_f32_32x32x1f32_vecarg(ptr addrspace(1) %arg) #0 {
-; CHECK: Not uniform: %in.f32 = load <32 x float>, ptr addrspace(1) %gep, align 128
-; CHECK-NEXT: MFMA in control flow
-; CHECK-NEXT: %mfma = tail call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float 1.000000e+00, float 2.000000e+00, <32 x float> %in.f32, i32 1, i32 2, i32 3)
-s:
- %tid = call i32 @llvm.amdgcn.workitem.id.x()
- %gep = getelementptr inbounds <32 x float>, ptr addrspace(1) %arg, i32 %tid
- %in.i32 = load <32 x i32>, ptr addrspace(1) %gep
- %in.f32 = load <32 x float>, ptr addrspace(1) %gep
-
- %0 = icmp eq <32 x i32> %in.i32, zeroinitializer
- %div.br = extractelement <32 x i1> %0, i32 0
- br i1 %div.br, label %if.3, label %else.0
-
-if.3:
- br label %join
-
-else.0:
- %mfma = tail call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float 1.000000e+00, float 2.000000e+00, <32 x float> %in.f32, i32 1, i32 2, i32 3)
- br label %join
-
-join:
- ret void
-}
-
define amdgpu_cs i32 @shader() {
; CHECK: Shaders must return void
ret i32 0
>From 6b84c73a35a260d64ed45df90052f8212b0ee4e7 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Mon, 21 Apr 2025 20:54:10 -0400
Subject: [PATCH 11/12] Add registerVerifierPasses to PassBuilder and add the
verifier passes to PassRegistry.
---
llvm/include/llvm/InitializePasses.h | 1 +
llvm/include/llvm/Passes/PassBuilder.h | 21 +++++++
.../llvm/Passes/TargetPassRegistry.inc | 12 ++++
.../TargetVerify/AMDGPUTargetVerifier.h | 11 ++--
llvm/lib/Passes/PassBuilder.cpp | 7 +++
llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def | 11 ++++
.../Target/AMDGPU/AMDGPUTargetVerifier.cpp | 56 ++++++++++++++++++-
.../tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 1 +
8 files changed, 114 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 9bef8e496c57e..ae398db3dc1da 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -317,6 +317,7 @@ void initializeUnpackMachineBundlesPass(PassRegistry &);
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry &);
void initializeUnreachableMachineBlockElimLegacyPass(PassRegistry &);
void initializeVerifierLegacyPassPass(PassRegistry &);
+void initializeAMDGPUTargetVerifierLegacyPassPass(PassRegistry &);
void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
void initializeVirtRegRewriterPass(PassRegistry &);
void initializeWasmEHPreparePass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 51ccaa53447d7..6000769ce723b 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -172,6 +172,13 @@ class PassBuilder {
/// additional analyses.
void registerLoopAnalyses(LoopAnalysisManager &LAM);
+ /// Registers all available verifier passes.
+ ///
+ /// This is an interface that can be used to populate a
+ /// \c ModuleAnalysisManager with all registered loop analyses. Callers can
+ /// still manually register any additional analyses.
+ void registerVerifierPasses(ModulePassManager &PM, FunctionPassManager &);
+
/// Registers all available machine function analysis passes.
///
/// This is an interface that can be used to populate a \c
@@ -570,6 +577,15 @@ class PassBuilder {
}
/// @}}
+ /// Register a callback for parsing an Verifier Name to populate
+ /// the given managers.
+ void registerVerifierCallback(
+ const std::function<bool(ModulePassManager &MPM)> &C,
+ const std::function<bool(FunctionPassManager &MPM)> &CF) {
+ VerifierCallbacks.push_back(C);
+ FnVerifierCallbacks.push_back(CF);
+ }
+
/// {{@ Register pipeline parsing callbacks with this pass builder instance.
/// Using these callbacks, callers can parse both a single pass name, as well
/// as entire sub-pipelines, and populate the PassManager instance
@@ -841,6 +857,11 @@ class PassBuilder {
// Callbacks to parse `filter` parameter in register allocation passes
SmallVector<std::function<RegAllocFilterFunc(StringRef)>, 2>
RegClassFilterParsingCallbacks;
+ // Verifier callbacks
+ SmallVector<std::function<bool(ModulePassManager &)>, 2>
+ VerifierCallbacks;
+ SmallVector<std::function<bool(FunctionPassManager &)>, 2>
+ FnVerifierCallbacks;
};
/// This utility template takes care of adding require<> and invalidate<>
diff --git a/llvm/include/llvm/Passes/TargetPassRegistry.inc b/llvm/include/llvm/Passes/TargetPassRegistry.inc
index 521913cb25a4a..2d04b874cf360 100644
--- a/llvm/include/llvm/Passes/TargetPassRegistry.inc
+++ b/llvm/include/llvm/Passes/TargetPassRegistry.inc
@@ -151,6 +151,18 @@ PB.registerPipelineParsingCallback([=](StringRef Name, FunctionPassManager &PM,
return false;
});
+PB.registerVerifierCallback([](ModulePassManager &PM) {
+#define VERIFIER_MODULE_ANALYSIS(NAME, CREATE_PASS) PM.addPass(CREATE_PASS)
+#include GET_PASS_REGISTRY
+#undef VERIFIER_MODULE_ANALYSIS
+ return false;
+}, [](FunctionPassManager &FPM) {
+#define VERIFIER_FUNCTION_ANALYSIS(NAME, CREATE_PASS) FPM.addPass(CREATE_PASS)
+#include GET_PASS_REGISTRY
+#undef VERIFIER_FUNCTION_ANALYSIS
+ return false;
+});
+
#undef ADD_PASS
#undef ADD_PASS_WITH_PARAMS
diff --git a/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
index d8a3fda4f87dc..b6a7412e8c1ef 100644
--- a/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
+++ b/llvm/include/llvm/Target/TargetVerify/AMDGPUTargetVerifier.h
@@ -39,14 +39,17 @@ class AMDGPUTargetVerify : public TargetVerify {
public:
Module *Mod;
- DominatorTree *DT;
- PostDominatorTree *PDT;
- UniformityInfo *UA;
+ DominatorTree *DT = nullptr;
+ PostDominatorTree *PDT = nullptr;
+ UniformityInfo *UA = nullptr;
+
+ AMDGPUTargetVerify(Module *Mod)
+ : TargetVerify(Mod), Mod(Mod) {}
AMDGPUTargetVerify(Module *Mod, DominatorTree *DT, PostDominatorTree *PDT, UniformityInfo *UA)
: TargetVerify(Mod), Mod(Mod), DT(DT), PDT(PDT), UA(UA) {}
- void run(Function &F);
+ bool run(Function &F);
};
} // namespace llvm
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index e7057d9a6b625..e942fed8b6a72 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -582,6 +582,13 @@ void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
C(LAM);
}
+void PassBuilder::registerVerifierPasses(ModulePassManager &MPM, FunctionPassManager &FPM) {
+ for (auto &C : VerifierCallbacks)
+ C(MPM);
+ for (auto &C : FnVerifierCallbacks)
+ C(FPM);
+}
+
static std::optional<std::pair<bool, bool>>
parseFunctionPipelineName(StringRef Name) {
std::pair<bool, bool> Params;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def
index 98a1147ef6d66..41e6a399c7239 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def
+++ b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def
@@ -81,6 +81,17 @@ FUNCTION_ALIAS_ANALYSIS("amdgpu-aa", AMDGPUAA())
#undef FUNCTION_ALIAS_ANALYSIS
#undef FUNCTION_ANALYSIS
+#ifndef VERIFIER_MODULE_ANALYSIS
+#define VERIFIER_MODULE_ANALYSIS(NAME, CREATE_PASS)
+#endif
+#ifndef VERIFIER_FUNCTION_ANALYSIS
+#define VERIFIER_FUNCTION_ANALYSIS(NAME, CREATE_PASS)
+#endif
+VERIFIER_MODULE_ANALYSIS("verifier", VerifierPass())
+VERIFIER_FUNCTION_ANALYSIS("amdgpu-tgtverifier", AMDGPUTargetVerifierPass())
+#undef VERIFIER_MODULE_ANALYSIS
+#undef VERIFIER_FUNCTION_ANALYSIS
+
#ifndef FUNCTION_PASS_WITH_PARAMS
#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
#endif
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index 684ced5bba574..63a7526b9abdc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -5,6 +5,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/InitializePasses.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/Module.h"
@@ -19,7 +20,7 @@ using namespace llvm;
do { \
if (!(C)) { \
TargetVerify::CheckFailed(__VA_ARGS__); \
- return; \
+ return false; \
} \
} while (false)
@@ -64,7 +65,7 @@ static bool isShader(CallingConv::ID CC) {
}
}
-void AMDGPUTargetVerify::run(Function &F) {
+bool AMDGPUTargetVerify::run(Function &F) {
// Ensure shader calling convention returns void
if (isShader(F.getCallingConv()))
Check(F.getReturnType() == Type::getVoidTy(F.getContext()), "Shaders must return void");
@@ -99,6 +100,10 @@ void AMDGPUTargetVerify::run(Function &F) {
}
}
}
+
+ if (!MessagesStr.str().empty())
+ return false;
+ return true;
}
PreservedAnalyses AMDGPUTargetVerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
@@ -120,4 +125,51 @@ PreservedAnalyses AMDGPUTargetVerifierPass::run(Function &F, FunctionAnalysisMan
return PreservedAnalyses::all();
}
+
+struct AMDGPUTargetVerifierLegacyPass : public FunctionPass {
+ static char ID;
+
+ std::unique_ptr<AMDGPUTargetVerify> TV;
+ bool FatalErrors = true;
+
+ AMDGPUTargetVerifierLegacyPass() : FunctionPass(ID) {
+ initializeAMDGPUTargetVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+ 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) && FatalErrors) {
+ errs() << "in function " << F.getName() << '\n';
+ report_fatal_error("Broken function found, compilation aborted!");
+ }
+ return false;
+ }
+
+ bool doFinalization(Module &M) override {
+ bool IsValid = true;
+ for (Function &F : M)
+ if (F.isDeclaration())
+ IsValid &= TV->run(F);
+
+ //IsValid &= TV->run();
+ if (FatalErrors && !IsValid)
+ report_fatal_error("Broken module found, compilation aborted!");
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+char AMDGPUTargetVerifierLegacyPass::ID = 0;
} // namespace llvm
+INITIALIZE_PASS(AMDGPUTargetVerifierLegacyPass, "amdgpu-tgtverify", "AMDGPU Target Verifier", false, false)
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index 627bc51ef3a43..503db7b1f8d18 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -144,6 +144,7 @@ int main(int argc, char **argv) {
PB.registerCGSCCAnalyses(CGAM);
PB.registerFunctionAnalyses(FAM);
PB.registerLoopAnalyses(LAM);
+ //PB.registerVerifierPasses(MPM, FPM);
PB.registerMachineFunctionAnalyses(MFAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
>From 485f05c9cec652de56c72ee110a5187490d09199 Mon Sep 17 00:00:00 2001
From: jofernau <Joe.Fernau at amd.com>
Date: Tue, 22 Apr 2025 14:57:31 -0400
Subject: [PATCH 12/12] Remove leftovers. Add titles. Add call to
registerVerifierCallbacks in llc.
---
.../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 4 ---
.../Target/AMDGPU/AMDGPUTargetVerifier.cpp | 32 +++++++++++--------
llvm/lib/Target/TargetVerifier.cpp | 19 +++++++++++
llvm/tools/llc/NewPMDriver.cpp | 1 +
.../tools/llvm-tgt-verify/llvm-tgt-verify.cpp | 7 ++--
5 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 6ec34d6a0fdbf..257cc724b3da9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -1299,8 +1299,6 @@ void AMDGPUPassConfig::addIRPasses() {
addPass(createLICMPass());
}
- //addPass(AMDGPUTargetVerifierPass());
-
TargetPassConfig::addIRPasses();
// EarlyCSE is not always strong enough to clean up what LSR produces. For
@@ -2043,8 +2041,6 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(AddIRPass &addPass) const {
// but EarlyCSE can do neither of them.
if (isPassEnabled(EnableScalarIRPasses))
addEarlyCSEOrGVNPass(addPass);
-
- addPass(AMDGPUTargetVerifierPass());
}
void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(AddIRPass &addPass) const {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
index 63a7526b9abdc..34cc41d111747 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetVerifier.cpp
@@ -1,3 +1,22 @@
+//===-- 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 "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
#include "llvm/Analysis/UniformityAnalysis.h"
@@ -25,19 +44,6 @@ using namespace llvm;
} while (false)
namespace llvm {
-/*class AMDGPUTargetVerify : public TargetVerify {
-public:
- Module *Mod;
-
- DominatorTree *DT;
- PostDominatorTree *PDT;
- UniformityInfo *UA;
-
- AMDGPUTargetVerify(Module *Mod, DominatorTree *DT, PostDominatorTree *PDT, UniformityInfo *UA)
- : TargetVerify(Mod), Mod(Mod), DT(DT), PDT(PDT), UA(UA) {}
-
- void run(Function &F);
-};*/
static bool IsValidInt(const Type *Ty) {
return Ty->isIntegerTy(1) ||
diff --git a/llvm/lib/Target/TargetVerifier.cpp b/llvm/lib/Target/TargetVerifier.cpp
index de3ff749e7c3c..992a0c91d93b1 100644
--- a/llvm/lib/Target/TargetVerifier.cpp
+++ b/llvm/lib/Target/TargetVerifier.cpp
@@ -1,3 +1,22 @@
+//===-- TargetVerifier.cpp - 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 TargetVerifier.cpp or an
+///// individual backend's TargetVerifier.
+/////
+/////===----------------------------------------------------------------------===//
+
#include "llvm/Target/TargetVerifier.h"
#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h"
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index a060d16e74958..0c6352d1925ed 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -125,6 +125,7 @@ int llvm::compileModuleWithNewPM(
PB.registerFunctionAnalyses(FAM);
PB.registerLoopAnalyses(LAM);
PB.registerMachineFunctionAnalyses(MFAM);
+ PB.registerVerifierPasses(MPM, FPM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
SI.registerCallbacks(PIC, &MAM, &FAM);
diff --git a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
index 503db7b1f8d18..b00bab66c6c3e 100644
--- a/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
+++ b/llvm/tools/llvm-tgt-verify/llvm-tgt-verify.cpp
@@ -1,4 +1,4 @@
-//===--- llvm-isel-fuzzer.cpp - Fuzzer for instruction selection ----------===//
+//===--- llvm-tgt-verify.cpp - Target Verifier ----------------- ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// Tool to fuzz instruction selection using libFuzzer.
+// Tool to verify a target.
//
//===----------------------------------------------------------------------===//
@@ -144,14 +144,11 @@ int main(int argc, char **argv) {
PB.registerCGSCCAnalyses(CGAM);
PB.registerFunctionAnalyses(FAM);
PB.registerLoopAnalyses(LAM);
- //PB.registerVerifierPasses(MPM, FPM);
PB.registerMachineFunctionAnalyses(MFAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
SI.registerCallbacks(PIC, &MAM, &FAM);
- //FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
-
Triple TT(M->getTargetTriple());
if (!NoLint)
FPM.addPass(LintPass(false));
More information about the llvm-commits
mailing list