From 1917ecc6cb1b9e5a3ce8839f196105bed86f7d91 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Wed, 22 May 2024 13:00:05 -0700 Subject: [PATCH 1/3] [flang] Lower selected_logical_kind to its runtime call Runtime support has been added in #89691. This patch adds lowering in a similar way than `selected_int_kind` and `selected_real_kind`. --- .../flang/Optimizer/Builder/IntrinsicCall.h | 1 + .../flang/Optimizer/Builder/Runtime/Numeric.h | 4 ++ flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 15 ++++ .../lib/Optimizer/Builder/Runtime/Numeric.cpp | 21 ++++++ .../Intrinsics/selected_logical_kind.f90 | 72 +++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 flang/test/Lower/Intrinsics/selected_logical_kind.f90 diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index 977a69af52813..2731392e6707b 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -334,6 +334,7 @@ struct IntrinsicLibrary { mlir::Value genScale(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef); mlir::Value genSelectedIntKind(mlir::Type, llvm::ArrayRef); + mlir::Value genSelectedLogicalKind(mlir::Type, llvm::ArrayRef); mlir::Value genSelectedRealKind(mlir::Type, llvm::ArrayRef); mlir::Value genSetExponent(mlir::Type resultType, llvm::ArrayRef args); diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h b/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h index fec8c9906effe..84a8e10e69c58 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h @@ -50,6 +50,10 @@ mlir::Value genScale(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value genSelectedIntKind(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value x); +/// Generate call to Selected_logical_kind intrinsic runtime routine. +mlir::Value genSelectedLogicalKind(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value x); + /// Generate call to Selected_real_kind intrinsic runtime routine. mlir::Value genSelectedRealKind(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value precision, mlir::Value range, diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index ae7e650987448..5bc0af979968c 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -553,6 +553,10 @@ static constexpr IntrinsicHandler handlers[]{ &I::genSelectedIntKind, {{{"scalar", asAddr}}}, /*isElemental=*/false}, + {"selected_logical_kind", + &I::genSelectedLogicalKind, + {{{"scalar", asAddr}}}, + /*isElemental=*/false}, {"selected_real_kind", &I::genSelectedRealKind, {{{"precision", asAddr, handleDynamicOptional}, @@ -5884,6 +5888,17 @@ IntrinsicLibrary::genSelectedIntKind(mlir::Type resultType, fir::runtime::genSelectedIntKind(builder, loc, fir::getBase(args[0]))); } +// SELECTED_LOGICAL_KIND +mlir::Value +IntrinsicLibrary::genSelectedLogicalKind(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + + return builder.createConvert(loc, resultType, + fir::runtime::genSelectedLogicalKind( + builder, loc, fir::getBase(args[0]))); +} + // SELECTED_REAL_KIND mlir::Value IntrinsicLibrary::genSelectedRealKind(mlir::Type resultType, diff --git a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp index 81d5d21ece7ae..93e4a297af43b 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp @@ -489,6 +489,27 @@ mlir::Value fir::runtime::genSelectedIntKind(fir::FirOpBuilder &builder, return builder.create(loc, func, args).getResult(0); } +/// Generate call to Selected_logical_kind intrinsic runtime routine. +mlir::Value fir::runtime::genSelectedLogicalKind(fir::FirOpBuilder &builder, + mlir::Location loc, + mlir::Value x) { + mlir::func::FuncOp func = + fir::runtime::getRuntimeFunc(loc, builder); + auto fTy = func.getFunctionType(); + auto sourceFile = fir::factory::locationToFilename(builder, loc); + auto sourceLine = + fir::factory::locationToLineNo(builder, loc, fTy.getInput(1)); + if (!fir::isa_ref_type(x.getType())) + fir::emitFatalError(loc, "argument address for runtime not found"); + mlir::Type eleTy = fir::unwrapRefType(x.getType()); + mlir::Value xKind = builder.createIntegerConstant( + loc, fTy.getInput(3), eleTy.getIntOrFloatBitWidth() / 8); + auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile, + sourceLine, x, xKind); + + return builder.create(loc, func, args).getResult(0); +} + /// Generate call to Selected_real_kind intrinsic runtime routine. mlir::Value fir::runtime::genSelectedRealKind(fir::FirOpBuilder &builder, mlir::Location loc, diff --git a/flang/test/Lower/Intrinsics/selected_logical_kind.f90 b/flang/test/Lower/Intrinsics/selected_logical_kind.f90 new file mode 100644 index 0000000000000..bd6521ea3bea3 --- /dev/null +++ b/flang/test/Lower/Intrinsics/selected_logical_kind.f90 @@ -0,0 +1,72 @@ +! REQUIRES: shell +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s + +subroutine selected_logical_kind_test1(input) + integer(1) :: input, res + res = selected_logical_kind(input) +end + +! CHECK-LABEL: func.func @_QPselected_logical_kind_test1( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "input"}) +! CHECK: %[[INPUT:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {uniq_name = "_QFselected_logical_kind_test1Einput"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[RES_ALLOCA:.*]] = fir.alloca i8 {bindc_name = "res", uniq_name = "_QFselected_logical_kind_test1Eres"} +! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_logical_kind_test1Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[KIND:.*]] = arith.constant 1 : i32 +! CHECK: %[[INPUT_ADDR:.*]] = fir.convert %1#1 : (!fir.ref) -> !fir.llvm_ptr +! CHECK: %{{.*}} = fir.call @_FortranASelectedLogicalKind(%{{.*}}, %{{.*}}, %[[INPUT_ADDR]], %[[KIND]]) fastmath : (!fir.ref, i32, !fir.llvm_ptr, i32) -> i32 + +subroutine selected_logical_kind_test2(input) + integer(2) :: input, res + res = selected_logical_kind(input) +end + +! CHECK-LABEL: func.func @_QPselected_logical_kind_test2( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "input"}) +! CHECK: %[[INPUT:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {uniq_name = "_QFselected_logical_kind_test2Einput"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[RES_ALLOCA:.*]] = fir.alloca i16 {bindc_name = "res", uniq_name = "_QFselected_logical_kind_test2Eres"} +! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_logical_kind_test2Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[KIND:.*]] = arith.constant 2 : i32 +! CHECK: %[[INPUT_ADDR:.*]] = fir.convert %[[INPUT]]#1 : (!fir.ref) -> !fir.llvm_ptr +! CHECK: %{{.*}} = fir.call @_FortranASelectedLogicalKind(%{{.*}}, %{{.*}}, %[[INPUT_ADDR]], %[[KIND]]) fastmath : (!fir.ref, i32, !fir.llvm_ptr, i32) -> i32 + +subroutine selected_logical_kind_test4(input) + integer(4) :: input, res + res = selected_logical_kind(input) +end + +! CHECK-LABEL: func.func @_QPselected_logical_kind_test4( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "input"}) +! CHECK: %[[INPUT:.*]]:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFselected_logical_kind_test4Einput"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[RES_ALLOCA:.*]] = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFselected_logical_kind_test4Eres"} +! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_logical_kind_test4Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[KIND:.*]] = arith.constant 4 : i32 +! CHECK: %[[INPUT_ADDR:.*]] = fir.convert %[[INPUT]]#1 : (!fir.ref) -> !fir.llvm_ptr +! CHECK: %{{.*}} = fir.call @_FortranASelectedLogicalKind(%{{.*}}, %{{.*}}, %[[INPUT_ADDR]], %[[KIND]]) fastmath : (!fir.ref, i32, !fir.llvm_ptr, i32) -> i32 + +subroutine selected_logical_kind_test8(input) + integer(8) :: input, res + res = selected_logical_kind(input) +end + +! CHECK-LABEL: func.func @_QPselected_logical_kind_test8( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "input"}) +! CHECK: %[[INPUT:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {uniq_name = "_QFselected_logical_kind_test8Einput"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[RES_ALLOCA]] = fir.alloca i64 {bindc_name = "res", uniq_name = "_QFselected_logical_kind_test8Eres"} +! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_logical_kind_test8Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[KIND:.*]] = arith.constant 8 : i32 +! CHECK: %[[INPUT_ADDR:.*]] = fir.convert %[[INPUT]]#1 : (!fir.ref) -> !fir.llvm_ptr +! CHECK: %{{.*}} = fir.call @_FortranASelectedLogicalKind(%{{.*}}, %{{.*}}, %[[INPUT_ADDR]], %[[KIND]]) fastmath : (!fir.ref, i32, !fir.llvm_ptr, i32) -> i32 + +subroutine selected_logical_kind_test16(input) + integer(16) :: input, res + res = selected_logical_kind(input) +end + +! CHECK-LABEL: func.func @_QPselected_logical_kind_test16( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "input"}) +! CHECK: %[[INPUT:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {uniq_name = "_QFselected_logical_kind_test16Einput"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[RES_ALLOCA:.*]] = fir.alloca i128 {bindc_name = "res", uniq_name = "_QFselected_logical_kind_test16Eres"} +! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_logical_kind_test16Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[KIND:.*]] = arith.constant 16 : i32 +! CHECK: %[[INPUT_ADDR:.*]] = fir.convert %[[INPUT]]#1 : (!fir.ref) -> !fir.llvm_ptr +! CHECK: %{{.*}} = fir.call @_FortranASelectedLogicalKind(%{{.*}}, %{{.*}}, %[[INPUT_ADDR]], %[[KIND]]) fastmath : (!fir.ref, i32, !fir.llvm_ptr, i32) -> i32 From 198186ba0aa438eee5ca4f9c0a7071baf799b85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= Date: Wed, 22 May 2024 13:11:28 -0700 Subject: [PATCH 2/3] Use argument name from the spec --- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 5bc0af979968c..e45f7d59c1489 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -555,7 +555,7 @@ static constexpr IntrinsicHandler handlers[]{ /*isElemental=*/false}, {"selected_logical_kind", &I::genSelectedLogicalKind, - {{{"scalar", asAddr}}}, + {{{"bits", asAddr}}}, /*isElemental=*/false}, {"selected_real_kind", &I::genSelectedRealKind, From b2e8676bc2f8c7def4776b6fb66f512a98448ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= Date: Wed, 22 May 2024 13:48:19 -0700 Subject: [PATCH 3/3] Remove require --- flang/test/Lower/Intrinsics/selected_logical_kind.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/flang/test/Lower/Intrinsics/selected_logical_kind.f90 b/flang/test/Lower/Intrinsics/selected_logical_kind.f90 index bd6521ea3bea3..93952762cce5e 100644 --- a/flang/test/Lower/Intrinsics/selected_logical_kind.f90 +++ b/flang/test/Lower/Intrinsics/selected_logical_kind.f90 @@ -1,4 +1,3 @@ -! REQUIRES: shell ! RUN: bbc -emit-hlfir %s -o - | FileCheck %s subroutine selected_logical_kind_test1(input)