diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -893,6 +893,21 @@ // Conversion from narrow logical to wide logical may be implemented // as a zero or sign extension of the input, but it may use value // normalization as well. + + if (isFloatingPointTy(fromTy)) { + // convert fp to integer + auto integer = rewriter.create(loc, toTy, op0); + // normalise integer + mlir::Value zero = genConstantIndex(loc, toTy, rewriter, 0); + auto isTrue = rewriter.create( + loc, mlir::LLVM::ICmpPredicate::ne, integer, zero); + rewriter.replaceOpWithNewOp(convert, toTy, isTrue); + return mlir::success(); + } + if (isFloatingPointTy(toTy)) { + rewriter.replaceOpWithNewOp(convert, toTy, op0); + return mlir::success(); + } if (!fromTy.isa() || !toTy.isa()) return mlir::emitError(loc) << "unsupported types for logical conversion: " << fromTy diff --git a/flang/test/Fir/logical-convert.fir b/flang/test/Fir/logical-convert.fir --- a/flang/test/Fir/logical-convert.fir +++ b/flang/test/Fir/logical-convert.fir @@ -511,3 +511,47 @@ %0 = fir.convert %arg0 : (!fir.logical<8>) -> !fir.logical<4> return %0 : !fir.logical<4> } +// ----- +// CHECK-LABEL: @test_f32_l4 +// CHECK: %[[INT:.*]] = llvm.fptosi %arg0 : f32 to i32 +// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: %[[CMP:.*]] = llvm.icmp "ne" %[[INT]], %[[ZERO]] : i32 +// CHECK: %[[EXT:.*]] = llvm.zext %[[CMP]] : i1 to i32 +// CHECK: llvm.return %[[EXT]] +func.func @test_f32_l4(%arg0: f32) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (f32) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_f64_l4 +// CHECK: %[[INT:.*]] = llvm.fptosi %arg0 : f64 to i32 +// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: %[[CMP:.*]] = llvm.icmp "ne" %[[INT]], %[[ZERO]] : i32 +// CHECK: %[[EXT:.*]] = llvm.zext %[[CMP]] : i1 to i32 +// CHECK: llvm.return %[[EXT]] +func.func @test_f64_l4(%arg0: f64) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (f64) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_f32_l8 +// CHECK: %[[INT:.*]] = llvm.fptosi %arg0 : f32 to i64 +// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: %[[CMP:.*]] = llvm.icmp "ne" %[[INT]], %[[ZERO]] : i64 +// CHECK: %[[EXT:.*]] = llvm.zext %[[CMP]] : i1 to i64 +// CHECK: llvm.return %[[EXT]] +func.func @test_f32_l8(%arg0: f32) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (f32) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_f64_l8 +// CHECK: %[[INT:.*]] = llvm.fptosi %arg0 : f64 to i64 +// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: %[[CMP:.*]] = llvm.icmp "ne" %[[INT]], %[[ZERO]] : i64 +// CHECK: %[[EXT:.*]] = llvm.zext %[[CMP]] : i1 to i64 +// CHECK: llvm.return %[[EXT]] +func.func @test_f64_l8(%arg0: f64) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (f64) -> !fir.logical<8> + return %0 : !fir.logical<8> +}