From d34df52377fda5452a8c244a8378957eaed66700 Mon Sep 17 00:00:00 2001 From: Mars Saxman Date: Wed, 19 Aug 2020 22:45:18 +0200 Subject: [PATCH] Implement FPToUI and UIToFP ops in standard dialect Add the unsigned complements to the existing FPToSI and SIToFP operations in the standard dialect, with one-to-one lowerings to the corresponding LLVM operations. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D85557 --- mlir/include/mlir/Dialect/StandardOps/IR/Ops.td | 42 ++++++++++++++++++++++ .../Conversion/StandardToLLVM/StandardToLLVM.cpp | 12 +++++++ mlir/lib/Dialect/StandardOps/IR/Ops.cpp | 17 +++++++++ .../StandardToLLVM/convert-to-llvmir.mlir | 31 +++++++++++++++- 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td index 510d485..b80da29 100644 --- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td @@ -1643,6 +1643,26 @@ def FPToSIOp : CastOp<"fptosi">, Arguments<(ins AnyType:$in)> { } //===----------------------------------------------------------------------===// +// FPToUIOp +//===----------------------------------------------------------------------===// + +def FPToUIOp : CastOp<"fptoui">, Arguments<(ins AnyType:$in)> { + let summary = "cast from floating-point type to integer type"; + let description = [{ + Cast from a value interpreted as floating-point to the nearest (rounding + towards zero) unsigned integer value. + }]; + + let extraClassDeclaration = [{ + /// Return true if `a` and `b` are valid operand and result pairs for + /// the operation. + static bool areCastCompatible(Type a, Type b); + }]; + + let hasFolder = 0; +} + +//===----------------------------------------------------------------------===// // FPTruncOp //===----------------------------------------------------------------------===// @@ -3065,6 +3085,28 @@ def TruncateIOp : Std_Op<"trunci", [NoSideEffect, SameOperandsAndResultShape]> { } //===----------------------------------------------------------------------===// +// UIToFPOp +//===----------------------------------------------------------------------===// + +def UIToFPOp : CastOp<"uitofp">, Arguments<(ins AnyType:$in)> { + let summary = "cast from unsigned integer type to floating-point"; + let description = [{ + Cast from a value interpreted as unsigned integer to the corresponding + floating-point value. If the value cannot be exactly represented, it is + rounded using the default rounding mode. Only scalars are currently + supported. + }]; + + let extraClassDeclaration = [{ + /// Return true if `a` and `b` are valid operand and result pairs for + /// the operation. + static bool areCastCompatible(Type a, Type b); + }]; + + let hasFolder = 0; +} + +//===----------------------------------------------------------------------===// // UnsignedDivIOp //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp index 44d912b..36d786d 100644 --- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp @@ -2630,6 +2630,11 @@ struct SIToFPLowering using Super::Super; }; +struct UIToFPLowering + : public OneToOneConvertToLLVMPattern { + using Super::Super; +}; + struct FPExtLowering : public OneToOneConvertToLLVMPattern { using Super::Super; @@ -2640,6 +2645,11 @@ struct FPToSILowering using Super::Super; }; +struct FPToUILowering + : public OneToOneConvertToLLVMPattern { + using Super::Super; +}; + struct FPTruncLowering : public OneToOneConvertToLLVMPattern { using Super::Super; @@ -3293,6 +3303,7 @@ void mlir::populateStdToLLVMNonMemoryConversionPatterns( Log2OpLowering, FPExtLowering, FPToSILowering, + FPToUILowering, FPTruncLowering, ImOpLowering, IndexCastOpLowering, @@ -3320,6 +3331,7 @@ void mlir::populateStdToLLVMNonMemoryConversionPatterns( SubFOpLowering, SubIOpLowering, TruncateIOpLowering, + UIToFPLowering, UnsignedDivIOpLowering, UnsignedRemIOpLowering, UnsignedShiftRightOpLowering, diff --git a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp index 447e500..9a54430 100644 --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -1780,6 +1780,14 @@ bool FPToSIOp::areCastCompatible(Type a, Type b) { } //===----------------------------------------------------------------------===// +// FPToUIOp +//===----------------------------------------------------------------------===// + +bool FPToUIOp::areCastCompatible(Type a, Type b) { + return a.isa() && b.isSignlessInteger(); +} + +//===----------------------------------------------------------------------===// // FPTruncOp //===----------------------------------------------------------------------===// @@ -2306,6 +2314,15 @@ OpFoldResult SubIOp::fold(ArrayRef operands) { } //===----------------------------------------------------------------------===// +// UIToFPOp +//===----------------------------------------------------------------------===// + +// uitofp is applicable from integer types to float types. +bool UIToFPOp::areCastCompatible(Type a, Type b) { + return a.isSignlessInteger() && b.isa(); +} + +//===----------------------------------------------------------------------===// // SubViewOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir index 419ee17..62be478 100644 --- a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir @@ -580,7 +580,7 @@ func @index_cast(%arg0: index, %arg1: i1) { return } -// Checking conversion of integer types to floating point. +// Checking conversion of signed integer types to floating point. // CHECK-LABEL: @sitofp func @sitofp(%arg0 : i32, %arg1 : i64) { // CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i32 to !llvm.float @@ -594,6 +594,20 @@ func @sitofp(%arg0 : i32, %arg1 : i64) { return } +// Checking conversion of unsigned integer types to floating point. +// CHECK-LABEL: @uitofp +func @uitofp(%arg0 : i32, %arg1 : i64) { +// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.float + %0 = uitofp %arg0: i32 to f32 +// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.double + %1 = uitofp %arg0: i32 to f64 +// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.float + %2 = uitofp %arg1: i64 to f32 +// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.double + %3 = uitofp %arg1: i64 to f64 + return +} + // Checking conversion of integer types to floating point. // CHECK-LABEL: @fpext func @fpext(%arg0 : f16, %arg1 : f32) { @@ -632,6 +646,21 @@ func @fptosi(%arg0 : f32, %arg1 : f64) { return } +// Checking conversion of floating point to integer types. +// CHECK-LABEL: @fptoui +func @fptoui(%arg0 : f32, %arg1 : f64) { +// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i32 + %0 = fptoui %arg0: f32 to i32 +// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i64 + %1 = fptoui %arg0: f32 to i64 +// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i32 + %2 = fptoui %arg1: f64 to i32 +// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i64 + %3 = fptoui %arg1: f64 to i64 + return +} + + // Checking conversion of integer types to floating point. // CHECK-LABEL: @fptrunc func @fptrunc(%arg0 : f32, %arg1 : f64) { -- 2.7.4