diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -40,6 +40,7 @@ let arguments = (ins LLVM_Type:$in, I<1>:$zero_undefined); } +def LLVM_AbsOp : LLVM_UnaryIntrinsicOp<"abs">; def LLVM_CopySignOp : LLVM_BinarySameArgsIntrinsicOp<"copysign">; def LLVM_CosOp : LLVM_UnaryIntrinsicOp<"cos">; def LLVM_ExpOp : LLVM_UnaryIntrinsicOp<"exp">; 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 @@ -86,6 +86,27 @@ let hasFolder = 1; } +//===----------------------------------------------------------------------===// +// AbsIOp +//===----------------------------------------------------------------------===// + +def Math_AbsIOp : Math_IntegerUnaryOp<"absi"> { + let summary = "integer absolute-value operation"; + let description = [{ + The `absi` operation computes the absolute value. It takes one operand of + integer type (i.e., scalar, tensor or vector) and returns one result of the + same type. + + Example: + + ```mlir + // Scalar absolute value. + %a = math.absi %b : i64 + ``` + }]; + let hasFolder = 1; +} + //===----------------------------------------------------------------------===// // AtanOp //===----------------------------------------------------------------------===// 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 @@ -19,6 +19,7 @@ namespace { using AbsFOpLowering = VectorConvertToLLVMPattern; +using AbsIOpLowering = VectorConvertToLLVMPattern; using CeilOpLowering = VectorConvertToLLVMPattern; using CopySignOpLowering = VectorConvertToLLVMPattern; @@ -269,6 +270,7 @@ // clang-format off patterns.add< AbsFOpLowering, + AbsIOpLowering, CeilOpLowering, CopySignOpLowering, CosOpLowering, diff --git a/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp b/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp --- a/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp +++ b/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp @@ -288,6 +288,7 @@ .add, ExpM1OpPattern, PowFOpPattern, RoundOpPattern, spirv::ElementwiseOpPattern, + spirv::ElementwiseOpPattern, spirv::ElementwiseOpPattern, spirv::ElementwiseOpPattern, spirv::ElementwiseOpPattern, diff --git a/mlir/lib/Dialect/Math/IR/MathOps.cpp b/mlir/lib/Dialect/Math/IR/MathOps.cpp --- a/mlir/lib/Dialect/Math/IR/MathOps.cpp +++ b/mlir/lib/Dialect/Math/IR/MathOps.cpp @@ -30,6 +30,15 @@ [](const APFloat &a) { return abs(a); }); } +//===----------------------------------------------------------------------===// +// AbsIOp folder +//===----------------------------------------------------------------------===// + +OpFoldResult math::AbsIOp::fold(ArrayRef operands) { + return constFoldUnaryOp(operands, + [](const APInt &a) { return a.abs(); }); +} + //===----------------------------------------------------------------------===// // AtanOp folder //===----------------------------------------------------------------------===// 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 @@ -2,14 +2,16 @@ // CHECK-LABEL: @ops func.func @ops(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64) { -// CHECK: = "llvm.intr.exp"(%{{.*}}) : (f32) -> f32 - %13 = math.exp %arg0 : f32 -// CHECK: = "llvm.intr.exp2"(%{{.*}}) : (f32) -> f32 - %14 = math.exp2 %arg0 : f32 -// CHECK: = "llvm.intr.sqrt"(%{{.*}}) : (f32) -> f32 - %19 = math.sqrt %arg0 : f32 -// CHECK: = "llvm.intr.sqrt"(%{{.*}}) : (f64) -> f64 - %20 = math.sqrt %arg4 : f64 + // CHECK: = "llvm.intr.exp"(%{{.*}}) : (f32) -> f32 + %0 = math.exp %arg0 : f32 + // CHECK: = "llvm.intr.exp2"(%{{.*}}) : (f32) -> f32 + %1 = math.exp2 %arg0 : f32 + // CHECK: = "llvm.intr.sqrt"(%{{.*}}) : (f32) -> f32 + %2 = math.sqrt %arg0 : f32 + // CHECK: = "llvm.intr.sqrt"(%{{.*}}) : (f64) -> f64 + %3 = math.sqrt %arg4 : f64 + // CHECK: = "llvm.intr.abs"(%{{.*}}) : (i32) -> i32 + %4 = math.absi %arg2 : i32 func.return } diff --git a/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir b/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir --- a/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir +++ b/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir @@ -79,6 +79,13 @@ return } +// CHECK-LABEL: @int_unary +func.func @int_unary(%arg0: i32) { + // CHECK: spv.GL.SAbs %{{.*}} + %0 = math.absi %arg0 : i32 + return +} + // CHECK-LABEL: @ctlz_scalar // CHECK-SAME: (%[[VAL:.+]]: i32) func.func @ctlz_scalar(%val: i32) -> i32 {