-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] implement function form of SYSTEM intrinsic #117585
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
Conversation
SYSTEM is a gfortran extension which we already supported in subroutine form. Gfortran also allows it to be called as a function, which was requested by a user https://discourse.llvm.org/t/unresolved-externals-with-appendend-underscore/83305/4
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Tom Eccles (tblah) ChangesSYSTEM is a gfortran extension which we already supported in subroutine form. Gfortran also allows it to be called as a function, which was requested by a user Full diff: https://github.com/llvm/llvm-project/pull/117585.diff 4 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index e83d1a42e34133..19c623cc1ec006 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -395,7 +395,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genSignalSubroutine(llvm::ArrayRef<fir::ExtendedValue>);
void genSleep(llvm::ArrayRef<fir::ExtendedValue>);
- void genSystem(mlir::ArrayRef<fir::ExtendedValue> args);
+ fir::ExtendedValue genSystem(std::optional<mlir::Type>,
+ mlir::ArrayRef<fir::ExtendedValue> args);
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genTand(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>);
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 1e27c0ae4216c5..f9096a8e3f1103 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -884,6 +884,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
IntrinsicClass::transformationalFunction},
{"sum", {{"array", SameNumeric, Rank::array}, MissingDIM, OptionalMASK},
SameNumeric, Rank::scalar, IntrinsicClass::transformationalFunction},
+ {"system", {{"command", DefaultChar, Rank::scalar}}, DefaultInt,
+ Rank::scalar},
{"tan", {{"x", SameFloating}}, SameFloating},
{"tand", {{"x", SameFloating}}, SameFloating},
{"tanh", {{"x", SameFloating}}, SameFloating},
@@ -2640,7 +2642,7 @@ bool IntrinsicProcTable::Implementation::IsDualIntrinsic(
// Collection for some intrinsics with function and subroutine form,
// in order to pass the semantic check.
static const std::string dualIntrinsic[]{
- {"etime"s}, {"getcwd"s}, {"rename"s}, {"second"s}};
+ {"etime"s}, {"getcwd"s}, {"rename"s}, {"second"s}, {"system"s}};
return llvm::is_contained(dualIntrinsic, name);
}
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index a2b327f45c6939..08ca71699396f9 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -7280,12 +7280,22 @@ IntrinsicLibrary::genSum(mlir::Type resultType,
}
// SYSTEM
-void IntrinsicLibrary::genSystem(llvm::ArrayRef<fir::ExtendedValue> args) {
- assert(args.size() == 2);
+fir::ExtendedValue
+IntrinsicLibrary::genSystem(std::optional<mlir::Type> resultType,
+ llvm::ArrayRef<fir::ExtendedValue> args) {
+ assert((!resultType && (args.size() == 2)) ||
+ (resultType && (args.size() == 1)));
mlir::Value command = fir::getBase(args[0]);
- const fir::ExtendedValue &exitstat = args[1];
assert(command && "expected COMMAND parameter");
+ fir::ExtendedValue exitstat;
+ if (resultType) {
+ mlir::Value tmp = builder.createTemporary(loc, *resultType);
+ exitstat = builder.createBox(loc, tmp);
+ } else {
+ exitstat = args[1];
+ }
+
mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType());
mlir::Value waitBool = builder.createBool(loc, true);
@@ -7307,6 +7317,12 @@ void IntrinsicLibrary::genSystem(llvm::ArrayRef<fir::ExtendedValue> args) {
fir::runtime::genExecuteCommandLine(builder, loc, command, waitBool,
exitstatBox, cmdstatBox, cmdmsgBox);
+
+ if (resultType) {
+ mlir::Value exitstatAddr = builder.create<fir::BoxAddrOp>(loc, exitstatBox);
+ return builder.create<fir::LoadOp>(loc, fir::getBase(exitstatAddr));
+ }
+ return {};
}
// SYSTEM_CLOCK
diff --git a/flang/test/Lower/Intrinsics/system.f90 b/flang/test/Lower/Intrinsics/system.f90
index 71655938113f77..87ac8d9c7e6f95 100644
--- a/flang/test/Lower/Intrinsics/system.f90
+++ b/flang/test/Lower/Intrinsics/system.f90
@@ -51,3 +51,35 @@ subroutine only_command(command)
! CHECK-NEXT: return
! CHECK-NEXT: }
end subroutine only_command
+
+! CHECK-LABEL: func.func @_QPas_function(
+! CHECK-SAME: %[[commandArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "command"}
+subroutine as_function(command)
+CHARACTER(*) :: command
+INTEGER :: exitstat
+exitstat = system(command)
+end subroutine
+! CHECK-NEXT: %[[cmdstatVal:.*]] = fir.alloca i16
+! CHECK-NEXT: %[[RETVAL:.*]] = fir.alloca i32
+! CHECK-NEXT: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK-NEXT: %[[commandUnbox:.*]]:2 = fir.unboxchar %[[commandArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[commandDeclare:.*]]:2 = hlfir.declare %[[commandUnbox]]#0 typeparams %[[commandUnbox]]#1 dummy_scope %[[DSCOPE]] {uniq_name = "_QFas_functionEcommand"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+! CHECK-NEXT: %[[EXITSTAT_ALLOC:.*]] = fir.alloca i32
+! CHECK-NEXT: %[[exitstatDeclare:.*]]:2 = hlfir.declare %[[EXITSTAT_ALLOC]] {uniq_name = "_QFas_functionEexitstat"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK-NEXT: %[[commandBox:.*]] = fir.embox %[[commandDeclare]]#1 typeparams %[[commandUnbox]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+! CHECK-NEXT: %[[exitstatBox:.*]] = fir.embox %[[RETVAL]] : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK-NEXT: %[[true:.*]] = arith.constant true
+! CHECK-NEXT: %[[c0_i16:.*]] = arith.constant 0 : i16
+! CHECK-NEXT: fir.store %[[c0_i16]] to %[[cmdstatVal]] : !fir.ref<i16>
+! CHECK-NEXT: %[[cmdstatBox:.*]] = fir.embox %[[cmdstatVal]] : (!fir.ref<i16>) -> !fir.box<i16>
+! CHECK-NEXT: %[[absentBox:.*]] = fir.absent !fir.box<none>
+! CHECK: %[[LINE_NO:.*]] = arith.constant {{.*}} : i32
+! CHECK-NEXT: %[[command:.*]] = fir.convert %[[commandBox]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
+! CHECK-NEXT: %[[exitstat:.*]] = fir.convert %[[exitstatBox]] : (!fir.box<i32>) -> !fir.box<none>
+! CHECK-NEXT: %[[cmdstat:.*]] = fir.convert %[[cmdstatBox]] : (!fir.box<i16>) -> !fir.box<none>
+! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAExecuteCommandLine(%[[command]], %[[true]], %[[exitstat]], %[[cmdstat]], %[[absentBox]], %[[VAL_12:.*]], %[[LINE_NO]]) fastmath<contract> : (!fir.box<none>, i1, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+! CHECK-NEXT: %[[RET_ADDR:.*]] = fir.box_addr %[[exitstatBox]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK-NEXT: %[[RET:.*]] = fir.load %[[RET_ADDR]] : !fir.ref<i32>
+! CHECK-NEXT: hlfir.assign %[[RET]] to %[[exitstatDeclare]]#0 : i32, !fir.ref<i32>
+! CHECK-NEXT: return
+! CHECK-NEXT: }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks
SYSTEM is a gfortran extension which we already supported in subroutine form. Gfortran also allows it to be called as a function, which was requested by a user
https://discourse.llvm.org/t/unresolved-externals-with-appendend-underscore/83305/4