Skip to content

[flang] Allow getenv as alternate spelling for get_environment_variable #95777

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 4 commits into from
Jul 10, 2024

Conversation

DavidTruby
Copy link
Member

This patch adds getenv as an alternate spelling for get_environment_variable.
This spelling is allowed by multiple other compilers and is used in OpenRadioss.

This patch adds getenv as an alternate spelling for get_environment_variable.
This spelling is allowed by multiple other compilers and is used in OpenRadioss.
@DavidTruby DavidTruby requested a review from klausler June 17, 2024 12:47
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:semantics labels Jun 17, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 17, 2024

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-fir-hlfir

Author: David Truby (DavidTruby)

Changes

This patch adds getenv as an alternate spelling for get_environment_variable.
This spelling is allowed by multiple other compilers and is used in OpenRadioss.


Full diff: https://github.com/llvm/llvm-project/pull/95777.diff

3 Files Affected:

  • (modified) flang/lib/Evaluate/intrinsics.cpp (+12)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+10)
  • (modified) flang/test/Lower/Intrinsics/get_environment_variable.f90 (+162)
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index ace316174a892..fbdc54a2fc5e6 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1416,6 +1416,18 @@ static const IntrinsicInterface intrinsicSubroutine[]{
             {"status", TypePattern{IntType, KindCode::greaterOrEqualToKind, 4},
                 Rank::scalar, Optionality::optional, common::Intent::Out}},
         {}, Rank::elemental, IntrinsicClass::impureSubroutine},
+    {"getenv",
+        {{"name", DefaultChar, Rank::scalar},
+            {"value", DefaultChar, Rank::scalar, Optionality::optional,
+                common::Intent::Out},
+            {"length", AnyInt, Rank::scalar, Optionality::optional,
+                common::Intent::Out},
+            {"status", AnyInt, Rank::scalar, Optionality::optional,
+                common::Intent::Out},
+            {"trim_name", AnyLogical, Rank::scalar, Optionality::optional},
+            {"errmsg", DefaultChar, Rank::scalar, Optionality::optional,
+                common::Intent::InOut}},
+        {}, Rank::elemental, IntrinsicClass::impureSubroutine},
     {"move_alloc",
         {{"from", SameType, Rank::known, Optionality::required,
              common::Intent::InOut},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 3204369b9328a..22911a3fcaa0d 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -285,6 +285,16 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genGetCwd,
      {{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}},
      /*isElemental=*/false},
+    {"getenv",
+     &I::genGetEnvironmentVariable,
+     {{{"name", asBox},
+       {"value", asBox, handleDynamicOptional},
+       {"length", asBox, handleDynamicOptional},
+       {"status", asAddr, handleDynamicOptional},
+       {"trim_name", asAddr, handleDynamicOptional},
+       {"errmsg", asBox, handleDynamicOptional}}},
+     /*isElemental=*/false},
+
     {"getpid", &I::genGetPID},
     {"iachar", &I::genIchar},
     {"iall",
diff --git a/flang/test/Lower/Intrinsics/get_environment_variable.f90 b/flang/test/Lower/Intrinsics/get_environment_variable.f90
index 41634aaa97f4d..cc342940f95ff 100644
--- a/flang/test/Lower/Intrinsics/get_environment_variable.f90
+++ b/flang/test/Lower/Intrinsics/get_environment_variable.f90
@@ -161,3 +161,165 @@ subroutine all_arguments(name, value, length, status, trim_name, errmsg)
 ! CHECK-64: %[[status:.*]] = fir.convert %[[status32]] : (i32) -> i64
 ! CHECK: fir.store %[[status]] to %[[statusArg]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 end subroutine all_arguments
+
+
+! CHECK-LABEL: func @_QPgetenv_name_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"}) {
+subroutine getenv_name_only(name)
+    character(len=32) :: name
+    call getenv(name)
+! CHECK-NOT: fir.call @_FortranAGetEnvVariable
+! CHECK-NEXT: return
+end subroutine getenv_name_only
+
+! CHECK-LABEL: func @_QPgetenv_name_and_value_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-SAME: %[[valueArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "value"}) {
+subroutine getenv_name_and_value_only(name, value)
+    character(len=32) :: name, value
+    call getenv(name, value)
+! CHECK: %[[nameUnbox:.*]]:2 = fir.unboxchar %[[nameArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[nameCast:.*]] = fir.convert %[[nameUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[valueUnbox:.*]]:2 = fir.unboxchar %[[valueArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[valueCast:.*]] = fir.convert %[[valueUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameBox:.*]] = fir.embox %[[nameCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %[[valueBox:.*]] = fir.embox %[[valueCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %true = arith.constant true
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 11]] : i32
+! CHECK-NEXT: %[[name:.*]] = fir.convert %[[nameBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[value:.*]] = fir.convert %[[valueBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %true, %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-NEXT: return
+end subroutine getenv_name_and_value_only
+
+! CHECK-LABEL: func @_QPgetenv_name_and_length_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-SAME: %[[lengthArg:.*]]: !fir.ref<i[[DEFAULT_INTEGER_SIZE]]> {fir.bindc_name = "length"}) {
+subroutine getenv_name_and_length_only(name, length)
+    character(len=32) :: name
+    integer :: length
+    call getenv(name, LENGTH=length)
+! CHECK: %[[nameUnbox:.*]]:2 = fir.unboxchar %[[nameArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[nameCast:.*]] = fir.convert %[[nameUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameBox:.*]] = fir.embox %[[nameCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %[[lengthBox:.*]] = fir.embox %arg1 : (!fir.ref<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<i[[DEFAULT_INTEGER_SIZE]]>
+! CHECK-NEXT: %true = arith.constant true
+! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK: %[[sourceFileString:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 9]] : i32
+! CHECK-NEXT: %[[name:.*]] = fir.convert %[[nameBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.convert %[[lengthBox]] : (!fir.box<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-NEXT: %{{.*}} = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %true, %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+end subroutine getenv_name_and_length_only
+
+! CHECK-LABEL: func @_QPgetenv_name_and_status_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-SAME: %[[statusArg:.*]]: !fir.ref<i[[DEFAULT_INTEGER_SIZE]]> {fir.bindc_name = "status"}) {
+subroutine getenv_name_and_status_only(name, status)
+    character(len=32) :: name
+    integer :: status
+    call getenv(name, STATUS=status)
+! CHECK: %[[nameUnbox:.*]]:2 = fir.unboxchar %[[nameArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[nameCast:.*]] = fir.convert %[[nameUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameBox:.*]] = fir.embox %[[nameCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %true = arith.constant true
+! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 9]] : i32
+! CHECK-NEXT: %[[name:.*]] = fir.convert %[[nameBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %[[status:.*]] = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %true, %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %[[status32:.*]] = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %true, %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64: %[[status:.*]] = fir.convert %[[status32]] : (i32) -> i64
+! CHECK: fir.store %[[status]] to %[[statusArg]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
+end subroutine getenv_name_and_status_only
+
+! CHECK-LABEL: func @_QPgetenv_name_and_trim_name_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-32-SAME: %[[trimNameArg:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "trim_name"}) {
+! CHECK-64-SAME: %[[trimNameArg:.*]]: !fir.ref<!fir.logical<8>> {fir.bindc_name = "trim_name"}) {
+subroutine getenv_name_and_trim_name_only(name, trim_name)
+    character(len=32) :: name
+    logical :: trim_name
+    call getenv(name, TRIM_NAME=trim_name)
+    ! CHECK-NOT: fir.call @_FortranAGetEnvVariable
+    ! CHECK-NEXT: return
+end subroutine getenv_name_and_trim_name_only
+
+! CHECK-LABEL: func @_QPgetenv_name_and_errmsg_only(
+! CHECK-SAME: %[[nameArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-SAME: %[[errmsgArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "errmsg"}) {
+subroutine getenv_name_and_errmsg_only(name, errmsg)
+    character(len=32) :: name, errmsg
+    call getenv(name, ERRMSG=errmsg)
+! CHECK: %[[errmsgUnbox:.*]]:2 = fir.unboxchar %[[errmsgArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[errmsgCast:.*]] = fir.convert %[[errmsgUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameUnbox:.*]]:2 = fir.unboxchar %[[nameArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[nameCast:.*]] = fir.convert %[[nameUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameBox:.*]] = fir.embox %[[nameCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %[[errmsgBox:.*]] = fir.embox %[[errmsgCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %true = arith.constant true
+! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 11]] : i32
+! CHECK-NEXT: %[[name:.*]] = fir.convert %[[nameBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.convert %[[errmsgBox]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %true, %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-NEXT: return
+end subroutine getenv_name_and_errmsg_only
+
+! CHECK-LABEL: func @_QPgetenv_all_arguments(
+! CHECK-SAME: %[[nameArg:[^:]*]]: !fir.boxchar<1> {fir.bindc_name = "name"},
+! CHECK-SAME: %[[valueArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "value"},
+! CHECK-SAME: %[[lengthArg:[^:]*]]: !fir.ref<i[[DEFAULT_INTEGER_SIZE]]> {fir.bindc_name = "length"},
+! CHECK-SAME: %[[statusArg:.*]]: !fir.ref<i[[DEFAULT_INTEGER_SIZE]]> {fir.bindc_name = "status"},
+! CHECK-32-SAME: %[[trimNameArg:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "trim_name"},
+! CHECK-64-SAME: %[[trimNameArg:.*]]: !fir.ref<!fir.logical<8>> {fir.bindc_name = "trim_name"},
+! CHECK-SAME: %[[errmsgArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "errmsg"}) {
+subroutine getenv_all_arguments(name, value, length, status, trim_name, errmsg)
+    character(len=32) :: name, value, errmsg
+    integer :: length, status
+    logical :: trim_name
+    call getenv(name, value, length, status, trim_name, errmsg)
+! CHECK: %[[errmsgUnbox:.*]]:2 = fir.unboxchar %[[errmsgArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[errmsgCast:.*]] = fir.convert %[[errmsgUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameUnbox:.*]]:2 = fir.unboxchar %[[nameArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[nameCast:.*]] = fir.convert %[[nameUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[valueUnbox:.*]]:2 = fir.unboxchar %[[valueArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK-NEXT: %[[valueCast:.*]] = fir.convert %[[valueUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,32>>
+! CHECK-NEXT: %[[nameBoxed:.*]] = fir.embox %[[nameCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %[[valueBoxed:.*]] = fir.embox %[[valueCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK-NEXT: %[[lengthBoxed:.*]] = fir.embox %[[lengthArg]] : (!fir.ref<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<i[[DEFAULT_INTEGER_SIZE]]>
+! CHECK-NEXT: %[[errmsgBoxed:.*]] = fir.embox %[[errmsgCast]] : (!fir.ref<!fir.char<1,32>>) -> !fir.box<!fir.char<1,32>>
+! CHECK:      %[[trimName:.*]] = fir.if %{{.*}} -> (i1) {
+! CHECK-32-NEXT:   %[[trimNameLoaded:.*]] = fir.load %[[trimNameArg]] : !fir.ref<!fir.logical<4>>
+! CHECK-64-NEXT:   %[[trimNameLoaded:.*]] = fir.load %[[trimNameArg]] : !fir.ref<!fir.logical<8>>
+! CHECK-32-NEXT:   %[[trimCast:.*]] = fir.convert %[[trimNameLoaded]] : (!fir.logical<4>) -> i1
+! CHECK-64-NEXT:   %[[trimCast:.*]] = fir.convert %[[trimNameLoaded]] : (!fir.logical<8>) -> i1
+! CHECK-NEXT:   fir.result %[[trimCast]] : i1
+! CHECK-NEXT: } else {
+! CHECK-NEXT:   %[[trueVal:.*]] = arith.constant true
+! CHECK-NEXT:   fir.result %[[trueVal]] : i1
+! CHECK-NEXT: }
+! CHECK: %[[sourceFileString:.*]] = fir.address_of(@_QQclX[[fileString:.*]]) : !fir.ref<!fir.char<1,[[fileStringLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 22]] : i32
+! CHECK-NEXT: %[[name:.*]] = fir.convert %[[nameBoxed]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[value:.*]] = fir.convert %[[valueBoxed]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.convert %[[lengthBoxed]] : (!fir.box<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.convert %[[errmsgBoxed]] : (!fir.box<!fir.char<1,32>>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[fileStringLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %[[status:.*]] = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %[[trimName]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %[[status32:.*]] = fir.call @_FortranAGetEnvVariable(%[[name]], %[[value]], %[[length]], %[[trimName]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) {{.*}}: (!fir.box<none>, !fir.box<none>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64: %[[status:.*]] = fir.convert %[[status32]] : (i32) -> i64
+! CHECK: fir.store %[[status]] to %[[statusArg]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
+end subroutine getenv_all_arguments

@kiranchandramohan
Copy link
Contributor

Could you point to the usage in OpenRadioss?

Gfortran defines Getenv in https://gcc.gnu.org/onlinedocs/gfortran/GETENV.html. Only a subset of the GET_ENVIRONMENT_VARIABLE standard intrinsic is supported.

@DavidTruby
Copy link
Member Author

This is used in a number of places in OpenRadioss, for example here: https://github.com/OpenRadioss/OpenRadioss/blob/7aadf0746ecf6b34fee7df39a614e5b9865e4ddd/common_source/qa/qa_out_mod.F#L78

OpenRadioss only uses the flags that gfortran accepts, however it would be more complicated to restrict the flags to just those and I don't see a good reason to restrict it as they're a strict subset of what get_environment_variable accepts.

@tblah
Copy link
Contributor

tblah commented Jun 24, 2024

@kiranchandramohan does this look okay to you with the updated documentation?

@kiranchandramohan
Copy link
Contributor

@kiranchandramohan does this look okay to you with the updated documentation?

Looks OK to me. My original concern was whether we should only support the gfortran extension specification (CALL GETENV(NAME, VALUE)). And whether the lowering code can be avoided by directly calling a new runtime function like fdate (#71222).

Please wait for @klausler.

@klausler
Copy link
Contributor

Why not use the genericAlias table in flang/lib/Evaluate/intrinsics.cpp?

@DavidTruby
Copy link
Member Author

@klausler I've switched this to use the genericAlias table as requested, does this look better now?

@DavidTruby DavidTruby merged commit 1afd4b7 into llvm:main Jul 10, 2024
8 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 10, 2024

LLVM Buildbot has detected a new failure on builder publish-sphinx-docs running on as-worker-4 while building flang at step 6 "Publish docs-llvm-html".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/45/builds/1579

Here is the relevant piece of the build log for the reference:

Step 6 (Publish docs-llvm-html) failure: 'rsync -vrl ...' (failure)
ssh: Could not resolve hostname lists.llvm.org: Temporary failure in name resolution
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]
Step 7 (Publish docs-clang-html) failure: 'rsync -vrl ...' (failure)
ssh: Could not resolve hostname lists.llvm.org: Temporary failure in name resolution
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]
Step 8 (Publish docs-clang-tools-html) failure: 'rsync -vrl ...' (failure)
ssh: Could not resolve hostname lists.llvm.org: Temporary failure in name resolution
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]
Step 9 (Publish docs-lld-html) failure: 'rsync -vrl ...' (failure)
ssh: Could not resolve hostname lists.llvm.org: Temporary failure in name resolution
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]

aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
…le (llvm#95777)

This patch adds getenv as an alternate spelling for
get_environment_variable.
This spelling is allowed by multiple other compilers and is used in
OpenRadioss.
@DavidTruby DavidTruby deleted the getenv branch October 1, 2024 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants