diff --git a/mlir/include/mlir/Dialect/Math/IR/MathOps.td b/mlir/include/mlir/Dialect/Math/IR/MathOps.td --- a/mlir/include/mlir/Dialect/Math/IR/MathOps.td +++ b/mlir/include/mlir/Dialect/Math/IR/MathOps.td @@ -21,6 +21,17 @@ DeclareOpInterfaceMethods] # ElementwiseMappable.traits>; +// Base class for unary math operations on integer types. Require a operand and +// result of the same type. This type can be an integer type, or vector or tensor +// thereof. +class Math_IntegerUnaryOp traits = []> : + Math_Op { + let arguments = (ins SignlessIntegerLike:$operand); + let results = (outs SignlessIntegerLike:$result); + + let assemblyFormat = "$operand attr-dict `:` type($result)"; +} + // Base class for unary math operations on floating point types. Require a // operand and result of the same type. This type can be a floating point type, // or vector or tensor thereof. @@ -286,6 +297,30 @@ }]; } +//===----------------------------------------------------------------------===// +// CtPopOp +//===----------------------------------------------------------------------===// + +def Math_CtPopOp : Math_IntegerUnaryOp<"ctpop"> { + let summary = "counts the number of set bits of an integer value"; + let description = [{ + The `ctpop` operation computes the number of set bits of an integer value. + + Example: + + ```mlir + // Scalar ctpop function value. + %a = math.ctpop %b : i32 + + // SIMD vector element-wise ctpop function value. + %f = math.ctpop %g : vector<4xi16> + + // Tensor element-wise ctpop function value. + %x = math.ctpop %y : tensor<4x?xi8> + ``` + }]; +} + //===----------------------------------------------------------------------===// // ErfOp //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Conversion/MathToLLVM/MathToLLVM.cpp b/mlir/lib/Conversion/MathToLLVM/MathToLLVM.cpp --- a/mlir/lib/Conversion/MathToLLVM/MathToLLVM.cpp +++ b/mlir/lib/Conversion/MathToLLVM/MathToLLVM.cpp @@ -23,6 +23,8 @@ using CopySignOpLowering = VectorConvertToLLVMPattern; using CosOpLowering = VectorConvertToLLVMPattern; +using CtPopFOpLowering = + VectorConvertToLLVMPattern; using ExpOpLowering = VectorConvertToLLVMPattern; using Exp2OpLowering = VectorConvertToLLVMPattern; using FloorOpLowering = @@ -220,6 +222,7 @@ CeilOpLowering, CopySignOpLowering, CosOpLowering, + CtPopFOpLowering, ExpOpLowering, Exp2OpLowering, ExpM1OpLowering, diff --git a/mlir/test/Conversion/MathToLLVM/math-to-llvm.mlir b/mlir/test/Conversion/MathToLLVM/math-to-llvm.mlir --- a/mlir/test/Conversion/MathToLLVM/math-to-llvm.mlir +++ b/mlir/test/Conversion/MathToLLVM/math-to-llvm.mlir @@ -74,6 +74,26 @@ // ----- +// CHECK-LABEL: func @ctpop( +// CHECK-SAME: i32 +func @ctpop(%arg0 : i32) { + // CHECK: "llvm.intr.ctpop"(%arg0) : (i32) -> i32 + %0 = math.ctpop %arg0 : i32 + std.return +} + +// ----- + +// CHECK-LABEL: func @ctpop_vector( +// CHECK-SAME: vector<3xi32> +func @ctpop_vector(%arg0 : vector<3xi32>) { + // CHECK: "llvm.intr.ctpop"(%arg0) : (vector<3xi32>) -> vector<3xi32> + %0 = math.ctpop %arg0 : vector<3xi32> + std.return +} + +// ----- + // CHECK-LABEL: func @rsqrt_double( // CHECK-SAME: f64 func @rsqrt_double(%arg0 : f64) {