diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index a2743edd7844a..2302c08fae508 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -835,10 +835,20 @@ struct ConvertOpConversion : public fir::FIROpConversion { return mlir::success(); } if (mlir::isa(toTy)) { - if (toTy.isUnsignedInteger()) - rewriter.replaceOpWithNewOp(convert, toTy, op0); - else - rewriter.replaceOpWithNewOp(convert, toTy, op0); + // NOTE: We are checking the fir type here because toTy is an LLVM type + // which is signless, and we need to use the intrinsic that matches the + // sign of the output in fir. + if (toFirTy.isUnsignedInteger()) { + auto intrinsicName = + mlir::StringAttr::get(convert.getContext(), "llvm.fptoui.sat"); + rewriter.replaceOpWithNewOp( + convert, toTy, intrinsicName, op0); + } else { + auto intrinsicName = + mlir::StringAttr::get(convert.getContext(), "llvm.fptosi.sat"); + rewriter.replaceOpWithNewOp( + convert, toTy, intrinsicName, op0); + } return mlir::success(); } } else if (mlir::isa(fromTy)) { diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir index c7037019ee701..2960528fb6c24 100644 --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -701,6 +701,10 @@ func.func @convert_from_float(%arg0 : f32) { %7 = fir.convert %arg0 : (f32) -> i16 %8 = fir.convert %arg0 : (f32) -> i32 %9 = fir.convert %arg0 : (f32) -> i64 + %10 = fir.convert %arg0 : (f32) -> ui8 + %11 = fir.convert %arg0 : (f32) -> ui16 + %12 = fir.convert %arg0 : (f32) -> ui32 + %13 = fir.convert %arg0 : (f32) -> ui64 return } @@ -711,11 +715,15 @@ func.func @convert_from_float(%arg0 : f32) { // CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f64 // CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f80 // CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f128 -// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i1 -// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i8 -// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i16 -// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i32 -// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i64 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i1 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i8 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i16 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i32 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i64 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i8 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i16 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i32 +// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i64 // -----