/// Returns true if the given `type` is a boolean scalar or vector type.
static bool isBoolScalarOrVector(Type type) {
+ assert(type && "Not a valid type");
if (type.isInteger(1))
return true;
+
if (auto vecType = type.dyn_cast<VectorType>())
return vecType.getElementType().isInteger(1);
+
return false;
}
return aBW != 0 && bBW != 0 && aBW == bBW;
}
+/// Returns a source type conversion failure for `srcType` and operation `op`.
+static LogicalResult
+getTypeConversionFailure(ConversionPatternRewriter &rewriter, Operation *op,
+ Type srcType) {
+ return rewriter.notifyMatchFailure(
+ op->getLoc(),
+ llvm::formatv("failed to convert source type '{0}'", srcType));
+}
+
+/// Returns a source type conversion failure for the result type of `op`.
+static LogicalResult
+getTypeConversionFailure(ConversionPatternRewriter &rewriter, Operation *op) {
+ assert(op->getNumResults() == 1);
+ return getTypeConversionFailure(rewriter, op, op->getResultTypes().front());
+}
+
//===----------------------------------------------------------------------===//
// ConstantOp with composite type
//===----------------------------------------------------------------------===//
Op op, typename Op::Adaptor adaptor,
ConversionPatternRewriter &rewriter) const {
assert(adaptor.getOperands().size() == 2);
- auto dstType =
- this->getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = this->getTypeConverter()->convertType(op.getType());
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op);
+
if (isBoolScalarOrVector(adaptor.getOperands().front().getType())) {
rewriter.template replaceOpWithNewOp<SPIRVLogicalOp>(op, dstType,
adaptor.getOperands());
Type dstType = getTypeConverter()->convertType(op.getType());
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op);
+
rewriter.replaceOpWithNewOp<spirv::BitwiseXorOp>(op, dstType,
adaptor.getOperands());
Type dstType = getTypeConverter()->convertType(op.getType());
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op);
+
rewriter.replaceOpWithNewOp<spirv::LogicalNotEqualOp>(op, dstType,
adaptor.getOperands());
return success();
if (!isBoolScalarOrVector(srcType))
return failure();
- Type dstType = getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return getTypeConversionFailure(rewriter, op);
+
Location loc = op.getLoc();
Value zero = spirv::ConstantOp::getZero(dstType, loc, rewriter);
Value one = spirv::ConstantOp::getOne(dstType, loc, rewriter);
return failure();
Location loc = op.getLoc();
- Type dstType = getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return getTypeConversionFailure(rewriter, op);
Value allOnes;
if (auto intTy = dstType.dyn_cast<IntegerType>()) {
if (!isBoolScalarOrVector(srcType))
return failure();
- Type dstType = getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return getTypeConversionFailure(rewriter, op);
+
Location loc = op.getLoc();
Value zero = spirv::ConstantOp::getZero(dstType, loc, rewriter);
Value one = spirv::ConstantOp::getOne(dstType, loc, rewriter);
LogicalResult
TruncII1Pattern::matchAndRewrite(arith::TruncIOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const {
- Type dstType = getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return getTypeConversionFailure(rewriter, op);
+
if (!isBoolScalarOrVector(dstType))
return failure();
ConversionPatternRewriter &rewriter) const {
assert(adaptor.getOperands().size() == 1);
Type srcType = adaptor.getOperands().front().getType();
- Type dstType =
- this->getTypeConverter()->convertType(op.getResult().getType());
+ Type dstType = this->getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return getTypeConversionFailure(rewriter, op);
+
if (isBoolScalarOrVector(srcType) || isBoolScalarOrVector(dstType))
return failure();
+
if (dstType == srcType) {
// Due to type conversion, we are seeing the same source and target type.
// Then we can just erase this operation by forwarding its operand.
return failure();
Type dstType = getTypeConverter()->convertType(srcType);
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op, srcType);
switch (op.getPredicate()) {
case arith::CmpIPredicate::eq: {
return failure();
Type dstType = getTypeConverter()->convertType(srcType);
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op, srcType);
switch (op.getPredicate()) {
#define DISPATCH(cmpPredicate, spirvOp) \
auto *converter = this->template getTypeConverter<SPIRVTypeConverter>();
Type dstType = converter->convertType(op.getType());
if (!dstType)
- return failure();
+ return getTypeConversionFailure(rewriter, op);
// arith.maxf/minf:
// "if one of the arguments is NaN, then the result is also NaN."