Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mlir/include/mlir/Dialect/UB/IR/UBOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,24 @@ def PoisonOp : UB_Op<"poison", [ConstantLike, Pure]> {
let hasFolder = 1;
}

//===----------------------------------------------------------------------===//
// UnreachableOp
//===----------------------------------------------------------------------===//

def UnreachableOp : UB_Op<"unreachable", [Terminator]> {
let summary = "Unreachable operation.";
let description = [{
The `unreachable` operation triggers immediate undefined behavior if
executed.

Example:

```
ub.unreachable
```
}];

let assemblyFormat = "attr-dict";
}

#endif // MLIR_DIALECT_UB_IR_UBOPS_TD
35 changes: 28 additions & 7 deletions mlir/lib/Conversion/UBToLLVM/UBToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,20 @@ namespace mlir {

using namespace mlir;

namespace {
//===----------------------------------------------------------------------===//
// PoisonOpLowering
//===----------------------------------------------------------------------===//

namespace {
struct PoisonOpLowering : public ConvertOpToLLVMPattern<ub::PoisonOp> {
using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;

LogicalResult
matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override;
};

} // namespace

//===----------------------------------------------------------------------===//
// PoisonOpLowering
//===----------------------------------------------------------------------===//

LogicalResult
PoisonOpLowering::matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const {
Expand All @@ -60,6 +58,29 @@ PoisonOpLowering::matchAndRewrite(ub::PoisonOp op, OpAdaptor adaptor,
return success();
}

//===----------------------------------------------------------------------===//
// UnreachableOpLowering
//===----------------------------------------------------------------------===//

namespace {
struct UnreachableOpLowering
: public ConvertOpToLLVMPattern<ub::UnreachableOp> {
using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;

LogicalResult
matchAndRewrite(ub::UnreachableOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override;
};
} // namespace
LogicalResult

UnreachableOpLowering::matchAndRewrite(
ub::UnreachableOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const {
rewriter.replaceOpWithNewOp<LLVM::UnreachableOp>(op);
return success();
}

//===----------------------------------------------------------------------===//
// Pass Definition
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -93,7 +114,7 @@ struct UBToLLVMConversionPass

void mlir::ub::populateUBToLLVMConversionPatterns(
const LLVMTypeConverter &converter, RewritePatternSet &patterns) {
patterns.add<PoisonOpLowering>(converter);
patterns.add<PoisonOpLowering, UnreachableOpLowering>(converter);
}

//===----------------------------------------------------------------------===//
Expand Down
14 changes: 13 additions & 1 deletion mlir/lib/Conversion/UBToSPIRV/UBToSPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ struct PoisonOpLowering final : OpConversionPattern<ub::PoisonOp> {
}
};

struct UnreachableOpLowering final : OpConversionPattern<ub::UnreachableOp> {
using Base::Base;

LogicalResult
matchAndRewrite(ub::UnreachableOp op, OpAdaptor,
ConversionPatternRewriter &rewriter) const override {
rewriter.replaceOpWithNewOp<spirv::UnreachableOp>(op);
return success();
}
};

} // namespace

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -75,5 +86,6 @@ struct UBToSPIRVConversionPass final

void mlir::ub::populateUBToSPIRVConversionPatterns(
const SPIRVTypeConverter &converter, RewritePatternSet &patterns) {
patterns.add<PoisonOpLowering>(converter, patterns.getContext());
patterns.add<PoisonOpLowering, UnreachableOpLowering>(converter,
patterns.getContext());
}
6 changes: 6 additions & 0 deletions mlir/test/Conversion/UBToLLVM/ub-to-llvm.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ func.func @check_poison() {
%3 = ub.poison : !llvm.ptr
return
}

// CHECK-LABEL: @check_unrechable
func.func @check_unrechable() {
// CHECK: llvm.unreachable
ub.unreachable
}
15 changes: 15 additions & 0 deletions mlir/test/Conversion/UBToSPIRV/ub-to-spirv.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,18 @@ func.func @check_poison() {
}

}

// -----

// No successful test because the dialect conversion framework does not convert
// unreachable blocks.

module attributes {
spirv.target_env = #spirv.target_env<
#spirv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64, Shader], []>, #spirv.resource_limits<>>
} {
func.func @check_unrechable() {
// expected-error@+1{{cannot be used in reachable block}}
spirv.Unreachable
}
}
6 changes: 6 additions & 0 deletions mlir/test/Dialect/UB/ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ func.func @poison_tensor() -> tensor<8x?xf64> {
%0 = ub.poison : tensor<8x?xf64>
return %0 : tensor<8x?xf64>
}

// CHECK-LABEL: func @unreachable()
// CHECK: ub.unreachable
func.func @unreachable() {
ub.unreachable
}