diff --git a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td --- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td @@ -1642,6 +1642,26 @@ let hasFolder = 0; } +//===----------------------------------------------------------------------===// +// 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 //===----------------------------------------------------------------------===// @@ -3064,6 +3084,28 @@ }]; } +//===----------------------------------------------------------------------===// +// 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 --- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp @@ -2630,6 +2630,11 @@ using Super::Super; }; +struct UIToFPLowering + : public OneToOneConvertToLLVMPattern { + using Super::Super; +}; + struct FPExtLowering : public OneToOneConvertToLLVMPattern { using Super::Super; @@ -2640,6 +2645,11 @@ using Super::Super; }; +struct FPToUILowering + : public OneToOneConvertToLLVMPattern { + using Super::Super; +}; + struct FPTruncLowering : public OneToOneConvertToLLVMPattern { using Super::Super; @@ -3293,6 +3303,7 @@ Log2OpLowering, FPExtLowering, FPToSILowering, + FPToUILowering, FPTruncLowering, ImOpLowering, IndexCastOpLowering, @@ -3320,6 +3331,7 @@ 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 --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -1779,6 +1779,14 @@ return a.isa() && b.isSignlessInteger(); } +//===----------------------------------------------------------------------===// +// FPToUIOp +//===----------------------------------------------------------------------===// + +bool FPToUIOp::areCastCompatible(Type a, Type b) { + return a.isa() && b.isSignlessInteger(); +} + //===----------------------------------------------------------------------===// // FPTruncOp //===----------------------------------------------------------------------===// @@ -2305,6 +2313,15 @@ [](APInt a, APInt b) { return a - b; }); } +//===----------------------------------------------------------------------===// +// 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 --- a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir @@ -580,7 +580,7 @@ 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 @@ 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 @@ 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) {