[mlir] Convert std.and/std.or ops to spv.LogicalAnd/spv.LogicalOr

The conversion from std.and/std.or to spv.LogicalAnd/spv.LogicalOr is
only valid for boolean (i1) types. Modify BinaryOpPattern in
StandardToSPIRV.td to allow limiting the type of the operands for
which the pattern is applied.

Differential Revision: https://reviews.llvm.org/D71881
This commit is contained in:
MaheshRavishankar 2019-12-25 16:29:17 -08:00
parent ef7a659c21
commit c3d3569d4c
2 changed files with 49 additions and 7 deletions

View File

@ -16,15 +16,17 @@
include "mlir/Dialect/StandardOps/Ops.td"
include "mlir/Dialect/SPIRV/SPIRVOps.td"
class BinaryOpPattern<Op src, Op tgt> :
Pat<(src SPV_ScalarOrVector:$l, SPV_ScalarOrVector:$r),
class BinaryOpPattern<Type type, Op src, Op tgt> :
Pat<(src SPV_ScalarOrVectorOf<type>:$l, SPV_ScalarOrVectorOf<type>:$r),
(tgt $l, $r)>;
def : BinaryOpPattern<AddFOp, SPV_FAddOp>;
def : BinaryOpPattern<DivFOp, SPV_FDivOp>;
def : BinaryOpPattern<MulFOp, SPV_FMulOp>;
def : BinaryOpPattern<RemFOp, SPV_FRemOp>;
def : BinaryOpPattern<SubFOp, SPV_FSubOp>;
def : BinaryOpPattern<SPV_Bool, AndOp, SPV_LogicalAndOp>;
def : BinaryOpPattern<SPV_Bool, OrOp, SPV_LogicalOrOp>;
def : BinaryOpPattern<SPV_Float, AddFOp, SPV_FAddOp>;
def : BinaryOpPattern<SPV_Float, DivFOp, SPV_FDivOp>;
def : BinaryOpPattern<SPV_Float, MulFOp, SPV_FMulOp>;
def : BinaryOpPattern<SPV_Float, RemFOp, SPV_FRemOp>;
def : BinaryOpPattern<SPV_Float, SubFOp, SPV_FSubOp>;
// Constant Op
// TODO(ravishankarm): Handle lowering other constant types.

View File

@ -134,6 +134,46 @@ func @constant() {
return
}
//===----------------------------------------------------------------------===//
// std logical binary operations
//===----------------------------------------------------------------------===//
// CHECK-LABEL: @logical_scalar
func @logical_scalar(%arg0 : i1, %arg1 : i1) {
// CHECK: spv.LogicalAnd
%0 = and %arg0, %arg1 : i1
// CHECK: spv.LogicalOr
%1 = or %arg0, %arg1 : i1
return
}
// CHECK-LABEL: @logical_vector
func @logical_vector(%arg0 : vector<4xi1>, %arg1 : vector<4xi1>) {
// CHECK: spv.LogicalAnd
%0 = and %arg0, %arg1 : vector<4xi1>
// CHECK: spv.LogicalOr
%1 = or %arg0, %arg1 : vector<4xi1>
return
}
// CHECK-LABEL: @logical_scalar_fail
func @logical_scalar_fail(%arg0 : i32, %arg1 : i32) {
// CHECK-NOT: spv.LogicalAnd
%0 = and %arg0, %arg1 : i32
// CHECK-NOT: spv.LogicalOr
%1 = or %arg0, %arg1 : i32
return
}
// CHECK-LABEL: @logical_vector_fail
func @logical_vector_fail(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
// CHECK-NOT: spv.LogicalAnd
%0 = and %arg0, %arg1 : vector<4xi32>
// CHECK-NOT: spv.LogicalOr
%1 = or %arg0, %arg1 : vector<4xi32>
return
}
//===----------------------------------------------------------------------===//
// std.select
//===----------------------------------------------------------------------===//