forked from OSchip/llvm-project
Add support for OpBitwiseOr, OpBitwiseXor, and OpBitwiseAnd in SPIR-V dialect.
PiperOrigin-RevId: 274935374
This commit is contained in:
parent
2fc29f1eab
commit
950979745a
|
@ -161,6 +161,9 @@ def SPV_OC_OpFOrdLessThanEqual : I32EnumAttrCase<"OpFOrdLessThanEqual", 188
|
|||
def SPV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>;
|
||||
def SPV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>;
|
||||
def SPV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>;
|
||||
def SPV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>;
|
||||
def SPV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>;
|
||||
def SPV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>;
|
||||
def SPV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>;
|
||||
def SPV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>;
|
||||
def SPV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>;
|
||||
|
@ -201,6 +204,7 @@ def SPV_OpcodeAttr :
|
|||
SPV_OC_OpFOrdGreaterThan, SPV_OC_OpFUnordGreaterThan,
|
||||
SPV_OC_OpFOrdLessThanEqual, SPV_OC_OpFUnordLessThanEqual,
|
||||
SPV_OC_OpFOrdGreaterThanEqual, SPV_OC_OpFUnordGreaterThanEqual,
|
||||
SPV_OC_OpBitwiseOr, SPV_OC_OpBitwiseXor, SPV_OC_OpBitwiseAnd,
|
||||
SPV_OC_OpControlBarrier, SPV_OC_OpMemoryBarrier, SPV_OC_OpLoopMerge,
|
||||
SPV_OC_OpSelectionMerge, SPV_OC_OpLabel, SPV_OC_OpBranch,
|
||||
SPV_OC_OpBranchConditional, SPV_OC_OpReturn, SPV_OC_OpReturnValue,
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
//===-- SPIRVBitOps.td - MLIR SPIR-V Bit Ops -*- tablegen -*-===//
|
||||
//
|
||||
// Copyright 2019 The MLIR Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
//
|
||||
// This file contains bit ops for the SPIR-V dialect. It corresponds
|
||||
// to "3.32.13. Bit Instructions" of the SPIR-V specification.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef SPIRV_BIT_OPS
|
||||
#else
|
||||
#define SPIRV_BIT_OPS
|
||||
|
||||
#ifdef SPIRV_BASE
|
||||
#else
|
||||
include "mlir/SPIRV/SPIRVBase.td"
|
||||
#endif // SPIRV_BASE
|
||||
|
||||
class SPV_BitBinaryOp<string mnemonic, list<OpTrait> traits = []> :
|
||||
// All the operands type used in bit instructions are SPV_Integer.
|
||||
SPV_BinaryOp<mnemonic, SPV_Integer, SPV_Integer,
|
||||
!listconcat(traits,
|
||||
[NoSideEffect, SameOperandsAndResultType])>;
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_BitwiseOrOp : SPV_BitBinaryOp<"BitwiseOr", [Commutative]> {
|
||||
let summary = [{
|
||||
Result is 1 if either Operand 1 or Operand 2 is 1. Result is 0 if both
|
||||
Operand 1 and Operand 2 are 0.
|
||||
}];
|
||||
|
||||
let description = [{
|
||||
Results are computed per component, and within each component, per bit.
|
||||
|
||||
Result Type must be a scalar or vector of integer type. The type of
|
||||
Operand 1 and Operand 2 must be a scalar or vector of integer type.
|
||||
They must have the same number of components as Result Type. They must
|
||||
have the same component width as Result Type.
|
||||
|
||||
### Custom assembly form
|
||||
|
||||
``` {.ebnf}
|
||||
integer-scalar-vector-type ::= integer-type |
|
||||
`vector<` integer-literal `x` integer-type `>`
|
||||
bitwise-or-op ::= ssa-id `=` `spv.BitwiseOr` ssa-use, ssa-use
|
||||
`:` integer-scalar-vector-type
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
%2 = spv.BitwiseOr %0, %1 : i32
|
||||
%2 = spv.BitwiseOr %0, %1 : vector<4xi32>
|
||||
```
|
||||
}];
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_BitwiseXorOp : SPV_BitBinaryOp<"BitwiseXor", [Commutative]> {
|
||||
let summary = [{
|
||||
Result is 1 if exactly one of Operand 1 or Operand 2 is 1. Result is 0
|
||||
if Operand 1 and Operand 2 have the same value.
|
||||
}];
|
||||
|
||||
let description = [{
|
||||
Results are computed per component, and within each component, per bit.
|
||||
|
||||
Result Type must be a scalar or vector of integer type. The type of
|
||||
Operand 1 and Operand 2 must be a scalar or vector of integer type.
|
||||
They must have the same number of components as Result Type. They must
|
||||
have the same component width as Result Type.
|
||||
|
||||
### Custom assembly form
|
||||
|
||||
``` {.ebnf}
|
||||
integer-scalar-vector-type ::= integer-type |
|
||||
`vector<` integer-literal `x` integer-type `>`
|
||||
bitwise-xor-op ::= ssa-id `=` `spv.BitwiseXor` ssa-use, ssa-use
|
||||
`:` integer-scalar-vector-type
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
%2 = spv.BitwiseXor %0, %1 : i32
|
||||
%2 = spv.BitwiseXor %0, %1 : vector<4xi32>
|
||||
```
|
||||
}];
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_BitwiseAndOp : SPV_BitBinaryOp<"BitwiseAnd", [Commutative]> {
|
||||
let summary = [{
|
||||
Result is 1 if both Operand 1 and Operand 2 are 1. Result is 0 if either
|
||||
Operand 1 or Operand 2 are 0.
|
||||
}];
|
||||
|
||||
let description = [{
|
||||
Results are computed per component, and within each component, per bit.
|
||||
|
||||
Result Type must be a scalar or vector of integer type. The type of
|
||||
Operand 1 and Operand 2 must be a scalar or vector of integer type.
|
||||
They must have the same number of components as Result Type. They must
|
||||
have the same component width as Result Type.
|
||||
|
||||
### Custom assembly form
|
||||
|
||||
``` {.ebnf}
|
||||
integer-scalar-vector-type ::= integer-type |
|
||||
`vector<` integer-literal `x` integer-type `>`
|
||||
bitwise-and-op ::= ssa-id `=` `spv.BitwiseAnd` ssa-use, ssa-use
|
||||
`:` integer-scalar-vector-type
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
%2 = spv.BitwiseAnd %0, %1 : i32
|
||||
%2 = spv.BitwiseAnd %0, %1 : vector<4xi32>
|
||||
```
|
||||
}];
|
||||
}
|
||||
|
||||
#endif // SPIRV_BIT_OPS
|
|
@ -40,6 +40,11 @@ include "mlir/Dialect/SPIRV/SPIRVBase.td"
|
|||
include "mlir/Dialect/SPIRV/SPIRVArithmeticOps.td"
|
||||
#endif // SPIRV_ARITHMETIC_OPS
|
||||
|
||||
#ifdef SPIRV_BIT_OPS
|
||||
#else
|
||||
include "mlir/Dialect/SPIRV/SPIRVBitOps.td"
|
||||
#endif // SPIRV_BIT_OPS
|
||||
|
||||
#ifdef SPIRV_CONTROLFLOW_OPS
|
||||
#else
|
||||
include "mlir/Dialect/SPIRV/SPIRVControlFlowOps.td"
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// spv.BitwiseOr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
func @bitwise_or_scalar(%arg: i32) -> i32 {
|
||||
// CHECK: spv.BitwiseOr
|
||||
%0 = spv.BitwiseOr %arg, %arg : i32
|
||||
return %0 : i32
|
||||
}
|
||||
|
||||
func @bitwise_or_vector(%arg: vector<4xi32>) -> vector<4xi32> {
|
||||
// CHECK: spv.BitwiseOr
|
||||
%0 = spv.BitwiseOr %arg, %arg : vector<4xi32>
|
||||
return %0 : vector<4xi32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @bitwise_or_float(%arg0: f16, %arg1: f16) -> f16 {
|
||||
// expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
|
||||
%0 = spv.BitwiseOr %arg0, %arg1 : f16
|
||||
return %0 : f16
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// spv.BitwiseXor
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
func @bitwise_xor_scalar(%arg: i32) -> i32 {
|
||||
// CHECK: spv.BitwiseXor
|
||||
%0 = spv.BitwiseXor %arg, %arg : i32
|
||||
return %0 : i32
|
||||
}
|
||||
|
||||
func @bitwise_xor_vector(%arg: vector<4xi32>) -> vector<4xi32> {
|
||||
// CHECK: spv.BitwiseXor
|
||||
%0 = spv.BitwiseXor %arg, %arg : vector<4xi32>
|
||||
return %0 : vector<4xi32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @bitwise_xor_float(%arg0: f16, %arg1: f16) -> f16 {
|
||||
// expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
|
||||
%0 = spv.BitwiseXor %arg0, %arg1 : f16
|
||||
return %0 : f16
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// spv.BitwiseAnd
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
func @bitwise_and_scalar(%arg: i32) -> i32 {
|
||||
// CHECK: spv.BitwiseAnd
|
||||
%0 = spv.BitwiseAnd %arg, %arg : i32
|
||||
return %0 : i32
|
||||
}
|
||||
|
||||
func @bitwise_and_vector(%arg: vector<4xi32>) -> vector<4xi32> {
|
||||
// CHECK: spv.BitwiseAnd
|
||||
%0 = spv.BitwiseAnd %arg, %arg : vector<4xi32>
|
||||
return %0 : vector<4xi32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @bitwise_and_float(%arg0: f16, %arg1: f16) -> f16 {
|
||||
// expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
|
||||
%0 = spv.BitwiseAnd %arg0, %arg1 : f16
|
||||
return %0 : f16
|
||||
}
|
Loading…
Reference in New Issue