Skip to content

[flang] Lower selected_char_kind to runtime call #93095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ struct IntrinsicLibrary {
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genScale(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genSelectedCharKind(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genSelectedIntKind(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genSelectedRealKind(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genSetExponent(mlir::Type resultType,
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/Numeric.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ mlir::Value genRRSpacing(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value genScale(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value x, mlir::Value i);

/// Generate call to Selected_char_kind intrinsic runtime routine.
mlir::Value genSelectedCharKind(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value name, mlir::Value length);

/// Generate call to Selected_int_kind intrinsic runtime routine.
mlir::Value genSelectedIntKind(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value x);
Expand Down
16 changes: 16 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ static constexpr IntrinsicHandler handlers[]{
{"back", asValue, handleDynamicOptional},
{"kind", asValue}}},
/*isElemental=*/true},
{"selected_char_kind",
&I::genSelectedCharKind,
{{{"name", asAddr}}},
/*isElemental=*/false},
{"selected_int_kind",
&I::genSelectedIntKind,
{{{"scalar", asAddr}}},
Expand Down Expand Up @@ -5873,6 +5877,18 @@ IntrinsicLibrary::genScan(mlir::Type resultType,
return readAndAddCleanUp(resultMutableBox, resultType, "SCAN");
}

// SELECTED_CHAR_KIND
fir::ExtendedValue
IntrinsicLibrary::genSelectedCharKind(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 1);

return builder.createConvert(
loc, resultType,
fir::runtime::genSelectedCharKind(builder, loc, fir::getBase(args[0]),
fir::getLen(args[0])));
}

// SELECTED_INT_KIND
mlir::Value
IntrinsicLibrary::genSelectedIntKind(mlir::Type resultType,
Expand Down
20 changes: 20 additions & 0 deletions flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,26 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}

/// Generate call to Selected_char_kind intrinsic runtime routine.
mlir::Value fir::runtime::genSelectedCharKind(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value name,
mlir::Value length) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(SelectedCharKind)>(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(name.getType()))
fir::emitFatalError(loc, "argument address for runtime not found");

auto args = fir::runtime::createArguments(builder, loc, fTy, sourceFile,
sourceLine, name, length);

return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}

/// Generate call to Selected_int_kind intrinsic runtime routine.
mlir::Value fir::runtime::genSelectedIntKind(fir::FirOpBuilder &builder,
mlir::Location loc,
Expand Down
17 changes: 17 additions & 0 deletions flang/test/Lower/Intrinsics/selected_char_kind.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s

subroutine selected_char_kind_test(c)
character(*) :: c
integer :: res
res = selected_char_kind(c)
end

! CHECK-LABEL: func.func @_QPselected_char_kind_test(
! CHECK-SAME: %[[ARG0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c"})
! CHECK: %[[UNBOXCHAR:.*]]:2 = fir.unboxchar %[[ARG0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK: %[[C:.*]]:2 = hlfir.declare %[[UNBOXCHAR]]#0 typeparams %[[UNBOXCHAR]]#1 dummy_scope %0 {uniq_name = "_QFselected_char_kind_testEc"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
! CHECK: %[[RES_ALLOCA:.*]] = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFselected_char_kind_testEres"}
! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOCA]] {uniq_name = "_QFselected_char_kind_testEres"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[CHAR_PTR:.*]] = fir.convert %[[C]]#1 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
! CHECK: %[[CHAR_LEN:.*]] = fir.convert %[[UNBOXCHAR]]#1 : (index) -> i64
! CHECK: %{{.*}} = fir.call @_FortranASelectedCharKind(%{{.*}}, %{{.*}}, %[[CHAR_PTR]], %[[CHAR_LEN]]) fastmath<contract> : (!fir.ref<i8>, i32, !fir.ref<i8>, i64) -> i32
Loading