The `reconcile-unrealized-casts` pass used to crash when the input contains circular chains of `unrealized_conversion_cast` ops. Furthermore, the `reconcileUnrealizedCasts` helper functions used to erase ops that were not passed via the `castOps` operand. Such ops are now preserved. That's why some integration tests had to be changed. Also avoid copying the set of all unresolved materializations in `convertOperations`. This commit is in preparation of turning `RewriterBase::replaceOp` into a non-virtual function. This is a re-upload of #158067, which was reverted due to CI failures. Note for LLVM integration: If you are seeing tests that are failing with `error: LLVM Translation failed for operation: builtin.unrealized_conversion_cast`, you may have to add the `-reconcile-unrealized-casts` pass to your pass pipeline. (Or switch to the `-convert-to-llvm` pass instead of combining the various `-convert-*-to-llvm` passes.) --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
92 lines
3.6 KiB
C++
92 lines
3.6 KiB
C++
//===------------------ TestVulkanRunnerPipeline.cpp --------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Implements a pipeline for use by Vulkan runner tests.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
|
|
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h"
|
|
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
|
|
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
|
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
|
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
|
|
#include "mlir/Dialect/GPU/Transforms/Passes.h"
|
|
#include "mlir/Dialect/LLVMIR/Transforms/RequestCWrappers.h"
|
|
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
|
|
#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
|
|
#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
|
|
#include "mlir/Pass/PassManager.h"
|
|
#include "mlir/Pass/PassOptions.h"
|
|
|
|
using namespace mlir;
|
|
|
|
// Defined in the test directory, no public header.
|
|
namespace mlir::test {
|
|
std::unique_ptr<Pass> createTestConvertToSPIRVPass(bool convertGPUModules,
|
|
bool nestInGPUModule);
|
|
} // namespace mlir::test
|
|
|
|
namespace {
|
|
|
|
struct VulkanRunnerPipelineOptions
|
|
: PassPipelineOptions<VulkanRunnerPipelineOptions> {
|
|
Option<bool> spirvWebGPUPrepare{
|
|
*this, "spirv-webgpu-prepare",
|
|
llvm::cl::desc("Run MLIR transforms used when targetting WebGPU")};
|
|
};
|
|
|
|
void buildTestVulkanRunnerPipeline(OpPassManager &passManager,
|
|
const VulkanRunnerPipelineOptions &options) {
|
|
passManager.addPass(createGpuKernelOutliningPass());
|
|
passManager.addPass(memref::createFoldMemRefAliasOpsPass());
|
|
|
|
GpuSPIRVAttachTargetOptions attachTargetOptions{};
|
|
attachTargetOptions.spirvVersion = "v1.0";
|
|
attachTargetOptions.spirvCapabilities.push_back("Shader");
|
|
attachTargetOptions.spirvExtensions.push_back(
|
|
"SPV_KHR_storage_buffer_storage_class");
|
|
passManager.addPass(createGpuSPIRVAttachTarget(attachTargetOptions));
|
|
|
|
passManager.addPass(test::createTestConvertToSPIRVPass(
|
|
/*convertGPUModules=*/true, /*nestInGPUModule=*/true));
|
|
|
|
OpPassManager &spirvModulePM =
|
|
passManager.nest<gpu::GPUModuleOp>().nest<spirv::ModuleOp>();
|
|
spirvModulePM.addPass(spirv::createSPIRVLowerABIAttributesPass());
|
|
spirvModulePM.addPass(spirv::createSPIRVUpdateVCEPass());
|
|
if (options.spirvWebGPUPrepare)
|
|
spirvModulePM.addPass(spirv::createSPIRVWebGPUPreparePass());
|
|
|
|
passManager.addPass(createGpuModuleToBinaryPass());
|
|
|
|
passManager.addPass(createFinalizeMemRefToLLVMConversionPass());
|
|
passManager.nest<func::FuncOp>().addPass(
|
|
LLVM::createLLVMRequestCWrappersPass());
|
|
// VulkanRuntimeWrappers.cpp requires these calling convention options.
|
|
GpuToLLVMConversionPassOptions opt;
|
|
opt.hostBarePtrCallConv = false;
|
|
opt.kernelBarePtrCallConv = true;
|
|
opt.kernelIntersperseSizeCallConv = true;
|
|
passManager.addPass(createGpuToLLVMConversionPass(opt));
|
|
passManager.addPass(createReconcileUnrealizedCastsPass());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace mlir::test {
|
|
void registerTestVulkanRunnerPipeline() {
|
|
PassPipelineRegistration<VulkanRunnerPipelineOptions>(
|
|
"test-vulkan-runner-pipeline",
|
|
"Runs a series of passes intended for Vulkan runner tests. Lowers GPU "
|
|
"dialect to LLVM dialect for the host and to serialized Vulkan SPIR-V "
|
|
"for the device.",
|
|
buildTestVulkanRunnerPipeline);
|
|
}
|
|
} // namespace mlir::test
|