//===-- SPIRVLogicalOps.td - MLIR SPIR-V Logical Ops -------*- tablegen -*-===// // // 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 contains arithmetic ops for the SPIR-V dialect. It corresponds // to "3.32.15. Relational and Logical Instructions" of the SPIR-V spec. // //===----------------------------------------------------------------------===// #ifndef MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS #define MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS include "mlir/Dialect/SPIRV/IR/SPIRVBase.td" include "mlir/Interfaces/SideEffectInterfaces.td" class SPIRV_LogicalBinaryOp traits = []> : // Result type is SPIRV_Bool. SPIRV_BinaryOp])> { let assemblyFormat = "$operand1 `,` $operand2 `:` type($operand1) attr-dict"; } class SPIRV_LogicalUnaryOp traits = []> : // Result type is SPIRV_Bool. SPIRV_UnaryOp])> { let assemblyFormat = "$operand `:` type($operand) attr-dict"; } // ----- def SPIRV_AnyOp : SPIRV_Op<"Any", [Pure]> { let summary = "Result is true if any component of Vector is true."; let description = [{ Result Type must be a Boolean type scalar. Vector must be a vector of Boolean type. #### Example: ```mlir %result = spirv.Any %vector : vector<4xi1> ``` }]; let arguments = (ins SPIRV_VectorOf:$vector ); let results = (outs SPIRV_Bool:$result ); let assemblyFormat = "$vector attr-dict `:` type($vector)"; let hasVerifier = 0; } // ----- def SPIRV_AllOp : SPIRV_Op<"All", [Pure]> { let summary = "Result is true if all components of Vector are true."; let description = [{ Result Type must be a Boolean type scalar. Vector must be a vector of Boolean type. #### Example: ```mlir %result = spirv.All %vector : vector<4xi1> ``` }]; let arguments = (ins SPIRV_VectorOf:$vector ); let results = (outs SPIRV_Bool:$result ); let assemblyFormat = "$vector attr-dict `:` type($vector)"; let hasVerifier = 0; } // ----- def SPIRV_FOrdEqualOp : SPIRV_LogicalBinaryOp<"FOrdEqual", SPIRV_Float, [Commutative]> { let summary = "Floating-point comparison for being ordered and equal."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdEqual %0, %1 : f32 %5 = spirv.FOrdEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FOrdGreaterThanOp : SPIRV_LogicalBinaryOp<"FOrdGreaterThan", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are ordered and Operand 1 is greater than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdGreaterThan %0, %1 : f32 %5 = spirv.FOrdGreaterThan %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FOrdGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"FOrdGreaterThanEqual", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are ordered and Operand 1 is greater than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdGreaterThanEqual %0, %1 : f32 %5 = spirv.FOrdGreaterThanEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FOrdLessThanOp : SPIRV_LogicalBinaryOp<"FOrdLessThan", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are ordered and Operand 1 is less than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdLessThan %0, %1 : f32 %5 = spirv.FOrdLessThan %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FOrdLessThanEqualOp : SPIRV_LogicalBinaryOp<"FOrdLessThanEqual", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are ordered and Operand 1 is less than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdLessThanEqual %0, %1 : f32 %5 = spirv.FOrdLessThanEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FOrdNotEqualOp : SPIRV_LogicalBinaryOp<"FOrdNotEqual", SPIRV_Float, [Commutative]> { let summary = "Floating-point comparison for being ordered and not equal."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FOrdNotEqual %0, %1 : f32 %5 = spirv.FOrdNotEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordEqualOp : SPIRV_LogicalBinaryOp<"FUnordEqual", SPIRV_Float, [Commutative]> { let summary = "Floating-point comparison for being unordered or equal."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordEqual %0, %1 : f32 %5 = spirv.FUnordEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordGreaterThanOp : SPIRV_LogicalBinaryOp<"FUnordGreaterThan", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are unordered or Operand 1 is greater than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordGreaterThan %0, %1 : f32 %5 = spirv.FUnordGreaterThan %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"FUnordGreaterThanEqual", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are unordered or Operand 1 is greater than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordGreaterThanEqual %0, %1 : f32 %5 = spirv.FUnordGreaterThanEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordLessThanOp : SPIRV_LogicalBinaryOp<"FUnordLessThan", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are unordered or Operand 1 is less than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordLessThan %0, %1 : f32 %5 = spirv.FUnordLessThan %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordLessThanEqualOp : SPIRV_LogicalBinaryOp<"FUnordLessThanEqual", SPIRV_Float, []> { let summary = [{ Floating-point comparison if operands are unordered or Operand 1 is less than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordLessThanEqual %0, %1 : f32 %5 = spirv.FUnordLessThanEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_FUnordNotEqualOp : SPIRV_LogicalBinaryOp<"FUnordNotEqual", SPIRV_Float, [Commutative]> { let summary = "Floating-point comparison for being unordered or not equal."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. They must have the same type, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.FUnordNotEqual %0, %1 : f32 %5 = spirv.FUnordNotEqual %2, %3 : vector<4xf32> ``` }]; } // ----- def SPIRV_IEqualOp : SPIRV_LogicalBinaryOp<"IEqual", SPIRV_Integer, [Commutative, UsableInSpecConstantOp]> { let summary = "Integer comparison for equality."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.IEqual %0, %1 : i32 %5 = spirv.IEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_INotEqualOp : SPIRV_LogicalBinaryOp<"INotEqual", SPIRV_Integer, [Commutative, UsableInSpecConstantOp]> { let summary = "Integer comparison for inequality."; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.INotEqual %0, %1 : i32 %5 = spirv.INotEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_IsFiniteOp : SPIRV_LogicalUnaryOp<"IsFinite", SPIRV_Float, []> { let summary = "Result is true if x is an IEEE Finite, otherwise result is false"; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.IsFinite %0: f32 %3 = spirv.IsFinite %1: vector<4xf32> ``` }]; } // ----- def SPIRV_IsInfOp : SPIRV_LogicalUnaryOp<"IsInf", SPIRV_Float, []> { let summary = "Result is true if x is an IEEE Inf, otherwise result is false"; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.IsInf %0: f32 %3 = spirv.IsInf %1: vector<4xf32> ``` }]; } // ----- def SPIRV_IsNanOp : SPIRV_LogicalUnaryOp<"IsNan", SPIRV_Float, []> { let summary = [{ Result is true if x is an IEEE NaN, otherwise result is false. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.IsNan %0: f32 %3 = spirv.IsNan %1: vector<4xf32> ``` }]; } // ----- def SPIRV_IsNormalOp : SPIRV_LogicalUnaryOp<"IsNormal", SPIRV_Float, []> { let summary = "Result is true if x is an IEEE normal number, otherwise result is false"; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.IsNormal %0: f32 %3 = spirv.IsNormal %1: vector<4xf32> ``` }]; } // ----- def SPIRV_LogicalAndOp : SPIRV_LogicalBinaryOp<"LogicalAnd", SPIRV_Bool, [Commutative, UsableInSpecConstantOp]> { let summary = [{ Result is true if both Operand 1 and Operand 2 are true. Result is false if either Operand 1 or Operand 2 are false. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 must be the same as Result Type. The type of Operand 2 must be the same as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.LogicalAnd %0, %1 : i1 %2 = spirv.LogicalAnd %0, %1 : vector<4xi1> ``` }]; let hasFolder = 1; } // ----- def SPIRV_LogicalEqualOp : SPIRV_LogicalBinaryOp<"LogicalEqual", SPIRV_Bool, [Commutative, UsableInSpecConstantOp]> { let summary = [{ Result is true if Operand 1 and Operand 2 have the same value. Result is false if Operand 1 and Operand 2 have different values. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 must be the same as Result Type. The type of Operand 2 must be the same as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.LogicalEqual %0, %1 : i1 %2 = spirv.LogicalEqual %0, %1 : vector<4xi1> ``` }]; let hasFolder = 1; } // ----- def SPIRV_LogicalNotOp : SPIRV_LogicalUnaryOp<"LogicalNot", SPIRV_Bool, [UsableInSpecConstantOp]> { let summary = [{ Result is true if Operand is false. Result is false if Operand is true. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand must be the same as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.LogicalNot %0 : i1 %2 = spirv.LogicalNot %0 : vector<4xi1> ``` }]; let hasCanonicalizer = 1; let hasFolder = 1; } // ----- def SPIRV_LogicalNotEqualOp : SPIRV_LogicalBinaryOp<"LogicalNotEqual", SPIRV_Bool, [Commutative, UsableInSpecConstantOp]> { let summary = [{ Result is true if Operand 1 and Operand 2 have different values. Result is false if Operand 1 and Operand 2 have the same value. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 must be the same as Result Type. The type of Operand 2 must be the same as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.LogicalNotEqual %0, %1 : i1 %2 = spirv.LogicalNotEqual %0, %1 : vector<4xi1> ``` }]; let hasFolder = 1; } // ----- def SPIRV_LogicalOrOp : SPIRV_LogicalBinaryOp<"LogicalOr", SPIRV_Bool, [Commutative, UsableInSpecConstantOp]> { let summary = [{ Result is true if either Operand 1 or Operand 2 is true. Result is false if both Operand 1 and Operand 2 are false. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 must be the same as Result Type. The type of Operand 2 must be the same as Result Type. Results are computed per component. #### Example: ```mlir %2 = spirv.LogicalOr %0, %1 : i1 %2 = spirv.LogicalOr %0, %1 : vector<4xi1> ``` }]; let hasFolder = 1; } // ----- def SPIRV_OrderedOp : SPIRV_LogicalBinaryOp<"Ordered", SPIRV_Float, [Commutative]> { let summary = [{ Result is true if both x == x and y == y are true, where IEEE comparison is used, otherwise result is false. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. y must have the same type as x. Results are computed per component. #### Example: ```mlir %4 = spirv.Ordered %0, %1 : f32 %5 = spirv.Ordered %2, %3 : vector<4xf32> ``` }]; let availability = [ MinVersion, MaxVersion, Extension<[]>, Capability<[SPIRV_C_Kernel]> ]; } // ----- def SPIRV_SGreaterThanOp : SPIRV_LogicalBinaryOp<"SGreaterThan", SPIRV_Integer, [UsableInSpecConstantOp, SignedOp]> { let summary = [{ Signed-integer comparison if Operand 1 is greater than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.SGreaterThan %0, %1 : i32 %5 = spirv.SGreaterThan %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_SGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"SGreaterThanEqual", SPIRV_Integer, [UsableInSpecConstantOp, SignedOp]> { let summary = [{ Signed-integer comparison if Operand 1 is greater than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.SGreaterThanEqual %0, %1 : i32 %5 = spirv.SGreaterThanEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_SLessThanOp : SPIRV_LogicalBinaryOp<"SLessThan", SPIRV_Integer, [UsableInSpecConstantOp, SignedOp]> { let summary = [{ Signed-integer comparison if Operand 1 is less than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.SLessThan %0, %1 : i32 %5 = spirv.SLessThan %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_SLessThanEqualOp : SPIRV_LogicalBinaryOp<"SLessThanEqual", SPIRV_Integer, [UsableInSpecConstantOp, SignedOp]> { let summary = [{ Signed-integer comparison if Operand 1 is less than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.SLessThanEqual %0, %1 : i32 %5 = spirv.SLessThanEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_SelectOp : SPIRV_Op<"Select", [Pure, AllTypesMatch<["true_value", "false_value", "result"]>, UsableInSpecConstantOp, DeclareOpInterfaceMethods]> { let summary = [{ Select between two objects. Before version 1.4, results are only computed per component. }]; let description = [{ Before version 1.4, Result Type must be a pointer, scalar, or vector. The types of Object 1 and Object 2 must be the same as Result Type. Condition must be a scalar or vector of Boolean type. If Condition is a scalar and true, the result is Object 1. If Condition is a scalar and false, the result is Object 2. If Condition is a vector, Result Type must be a vector with the same number of components as Condition and the result is a mix of Object 1 and Object 2: When a component of Condition is true, the corresponding component in the result is taken from Object 1, otherwise it is taken from Object 2. #### Example: ```mlir %3 = spirv.Select %0, %1, %2 : i1, f32 %3 = spirv.Select %0, %1, %2 : i1, vector<3xi32> %3 = spirv.Select %0, %1, %2 : vector<3xi1>, vector<3xf32> ``` }]; let arguments = (ins SPIRV_ScalarOrVectorOf:$condition, SPIRV_SelectType:$true_value, SPIRV_SelectType:$false_value ); let results = (outs SPIRV_SelectType:$result ); let assemblyFormat = [{ operands attr-dict `:` type($condition) `,` type($result) }]; // These ops require dynamic availability specification based on operand and // result types. bit autogenAvailability = 0; let hasFolder = 1; } // ----- def SPIRV_UGreaterThanOp : SPIRV_LogicalBinaryOp<"UGreaterThan", SPIRV_Integer, [UnsignedOp, UsableInSpecConstantOp]> { let summary = [{ Unsigned-integer comparison if Operand 1 is greater than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.UGreaterThan %0, %1 : i32 %5 = spirv.UGreaterThan %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_UGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"UGreaterThanEqual", SPIRV_Integer, [UnsignedOp, UsableInSpecConstantOp]> { let summary = [{ Unsigned-integer comparison if Operand 1 is greater than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.UGreaterThanEqual %0, %1 : i32 %5 = spirv.UGreaterThanEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_ULessThanOp : SPIRV_LogicalBinaryOp<"ULessThan", SPIRV_Integer, [UnsignedOp, UsableInSpecConstantOp]> { let summary = [{ Unsigned-integer comparison if Operand 1 is less than Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.ULessThan %0, %1 : i32 %5 = spirv.ULessThan %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } // ----- def SPIRV_UnorderedOp : SPIRV_LogicalBinaryOp<"Unordered", SPIRV_Float, [Commutative]> { let summary = [{ Result is true if either x or y is an IEEE NaN, otherwise result is false. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. x must be a scalar or vector of floating-point type. It must have the same number of components as Result Type. y must have the same type as x. Results are computed per component. #### Example: ```mlir %4 = spirv.Unordered %0, %1 : f32 %5 = spirv.Unordered %2, %3 : vector<4xf32> ``` }]; let availability = [ MinVersion, MaxVersion, Extension<[]>, Capability<[SPIRV_C_Kernel]> ]; } // ----- def SPIRV_ULessThanEqualOp : SPIRV_LogicalBinaryOp<"ULessThanEqual", SPIRV_Integer, [UnsignedOp, UsableInSpecConstantOp]> { let summary = [{ Unsigned-integer comparison if Operand 1 is less than or equal to Operand 2. }]; let description = [{ Result Type must be a scalar or vector of Boolean type. The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. They must have the same component width, and they must have the same number of components as Result Type. Results are computed per component. #### Example: ```mlir %4 = spirv.ULessThanEqual %0, %1 : i32 %5 = spirv.ULessThanEqual %2, %3 : vector<4xi32> ``` }]; let hasFolder = 1; } #endif // MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS