This is a follow-up to5df62bdc9b. That commit should not have needed to make the vector.insert and vector.extract conversions to SPIR-V directly handle the static poison index case, as there is a fold from those to ub.poison, and a conversion pattern from ub.poison to spirv.Undef, however: - The ub.poison fold result could not be materialized by the vector dialect (fixed as ofd13940ee26). - The conversion pattern wasn't being populated in VectorToSPIRVPass, which is used by the tests. This commit changes this. - The ub.poison to spirv.Undef pattern rejected non-scalar types, which prevented its use for vector results. It is unclear why this restriction existed; a remark in D156163 said this was to avoid converting "user types", but it is not obvious why these shouldn't be permitted (the SPIR-V specification allows OpUndef for all types except OpTypeVoid). This commit removes this restriction. With these fixed, this commit removes the redundant static poison index handling, and updates the tests.
63 lines
2.2 KiB
C++
63 lines
2.2 KiB
C++
//===- VectorToSPIRVPass.cpp - Vector to SPIR-V Passes --------------------===//
|
|
//
|
|
// 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 implements a pass to convert Vector dialect to SPIRV dialect.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Conversion/VectorToSPIRV/VectorToSPIRVPass.h"
|
|
|
|
#include "mlir/Conversion/UBToSPIRV/UBToSPIRV.h"
|
|
#include "mlir/Conversion/VectorToSPIRV/VectorToSPIRV.h"
|
|
#include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h"
|
|
#include "mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h"
|
|
#include "mlir/Dialect/UB/IR/UBOps.h"
|
|
#include "mlir/Pass/Pass.h"
|
|
#include "mlir/Transforms/DialectConversion.h"
|
|
|
|
namespace mlir {
|
|
#define GEN_PASS_DEF_CONVERTVECTORTOSPIRV
|
|
#include "mlir/Conversion/Passes.h.inc"
|
|
} // namespace mlir
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
struct ConvertVectorToSPIRVPass
|
|
: public impl::ConvertVectorToSPIRVBase<ConvertVectorToSPIRVPass> {
|
|
void runOnOperation() override;
|
|
};
|
|
} // namespace
|
|
|
|
void ConvertVectorToSPIRVPass::runOnOperation() {
|
|
MLIRContext *context = &getContext();
|
|
Operation *op = getOperation();
|
|
|
|
auto targetAttr = spirv::lookupTargetEnvOrDefault(op);
|
|
std::unique_ptr<ConversionTarget> target =
|
|
SPIRVConversionTarget::get(targetAttr);
|
|
|
|
SPIRVTypeConverter typeConverter(targetAttr);
|
|
|
|
// Use UnrealizedConversionCast as the bridge so that we don't need to pull in
|
|
// patterns for other dialects.
|
|
target->addLegalOp<UnrealizedConversionCastOp>();
|
|
|
|
RewritePatternSet patterns(context);
|
|
populateVectorToSPIRVPatterns(typeConverter, patterns);
|
|
// Used for folds, e.g. vector.extract[-1] -> ub.poison -> spirv.Undef.
|
|
ub::populateUBToSPIRVConversionPatterns(typeConverter, patterns);
|
|
|
|
if (failed(applyPartialConversion(op, *target, std::move(patterns))))
|
|
return signalPassFailure();
|
|
}
|
|
|
|
std::unique_ptr<OperationPass<>> mlir::createConvertVectorToSPIRVPass() {
|
|
return std::make_unique<ConvertVectorToSPIRVPass>();
|
|
}
|