[flang-commits] [flang] fix optional wait wrongly treated as false (PR #78145)

Yi Wu via flang-commits flang-commits at lists.llvm.org
Mon Jan 15 03:28:04 PST 2024


https://github.com/yi-wu-arm created https://github.com/llvm/llvm-project/pull/78145

When a optional bool in passed as optional, isStaticallyPresent() will actually return true.
    By changing wait from asValue to asAddr and add some check can solve this.

>From 2a36ab7f05771662c361a301f02039757694151a Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Fri, 12 Jan 2024 11:01:06 +0000
Subject: [PATCH 1/5] Fix const cast issue in FreeMemory function call

The FreeMemory function only accepts a void pointer,
but it was being called with a const char pointer,
resulting in a type-casting issue.
To address this, the commit replaces the direct cast with a
const_cast<void *>(static_cast<const void *>(newCmd).
---
 flang/runtime/execute.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp
index 48773ae8114b0b7..fa2b7eca0dde69b 100644
--- a/flang/runtime/execute.cpp
+++ b/flang/runtime/execute.cpp
@@ -199,7 +199,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
   }
   // Deallocate memory if EnsureNullTerminated dynamically allocated memory
   if (newCmd != command.OffsetElement()) {
-    FreeMemory((void *)newCmd);
+    FreeMemory(const_cast<void *>(static_cast<const void *>(newCmd)));
   }
 }
 

>From 0525df1ba81764c10c6f0f4ab1d7a6d616430c6a Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Fri, 12 Jan 2024 13:40:43 +0000
Subject: [PATCH 2/5] remove const

---
 flang/runtime/execute.cpp | 4 ++--
 flang/runtime/tools.cpp   | 4 ++--
 flang/runtime/tools.h     | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp
index fa2b7eca0dde69b..3a818670c96452f 100644
--- a/flang/runtime/execute.cpp
+++ b/flang/runtime/execute.cpp
@@ -116,7 +116,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
     const Descriptor *exitstat, const Descriptor *cmdstat,
     const Descriptor *cmdmsg, const char *sourceFile, int line) {
   Terminator terminator{sourceFile, line};
-  const char *newCmd{EnsureNullTerminated(
+  char *newCmd{EnsureNullTerminated(
       command.OffsetElement(), command.ElementBytes(), terminator)};
 
   if (exitstat) {
@@ -199,7 +199,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
   }
   // Deallocate memory if EnsureNullTerminated dynamically allocated memory
   if (newCmd != command.OffsetElement()) {
-    FreeMemory(const_cast<void *>(static_cast<const void *>(newCmd)));
+    FreeMemory((void *)newCmd);
   }
 }
 
diff --git a/flang/runtime/tools.cpp b/flang/runtime/tools.cpp
index 6d2d86586c5fe64..e653323ed1de037 100644
--- a/flang/runtime/tools.cpp
+++ b/flang/runtime/tools.cpp
@@ -173,8 +173,8 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) {
   ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous());
 }
 
-RT_API_ATTRS const char *EnsureNullTerminated(
-    const char *str, std::size_t length, Terminator &terminator) {
+RT_API_ATTRS char *EnsureNullTerminated(
+    char *str, std::size_t length, Terminator &terminator) {
   if (std::memchr(str, '\0', length) == nullptr) {
     char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)};
     std::memcpy(newCmd, str, length);
diff --git a/flang/runtime/tools.h b/flang/runtime/tools.h
index 47398a910ce73d4..89e5069995748b5 100644
--- a/flang/runtime/tools.h
+++ b/flang/runtime/tools.h
@@ -441,8 +441,8 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from);
 // size memory for null-terminator if necessary. Returns the original or a newly
 // allocated null-terminated string (responsibility for deallocation is on the
 // caller).
-RT_API_ATTRS const char *EnsureNullTerminated(
-    const char *str, std::size_t length, Terminator &terminator);
+RT_API_ATTRS char *EnsureNullTerminated(
+    char *str, std::size_t length, Terminator &terminator);
 
 RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value);
 

>From 25d7a795387741e3dbf4c0906d56d1edcf8333b4 Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Fri, 12 Jan 2024 14:29:33 +0000
Subject: [PATCH 3/5] doc fixes, add more detail to sync and async execution

---
 flang/docs/Intrinsics.md | 58 +++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 190d98569c86568..20fd1dfe9beb61a 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -847,7 +847,7 @@ used in constant expressions have currently no folding support at all.
 
 #### Usage and Info
 
-- **Standard:** Fortran 2008 and later, specified in 16.9.73
+- **Standard:** Fortran 2008 and later, specified in Section 16.9.73
 - **Class:** Subroutine
 - **Syntax:** `CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])`
 - **Arguments:**
@@ -862,28 +862,50 @@ used in constant expressions have currently no folding support at all.
 
 #### Implementation Specifics
 
-- **`COMMAND`:**
-  - Must be preset.
+##### `COMMAND`:
 
-- **`WAIT`:**
-  - If set to `false`, the command is executed asynchronously. If not preset or set to `false`, it is executed synchronously.
-  - Sync: achieved by passing command into `std::system` on all systems.
-  - Async: achieved by calling a `fork()` on POSIX-compatible systems, or `CreateProcess()` on Windows.
+- Must be preset.
 
-- **`CMDSTAT`:**
+##### `WAIT`:
+
+- If set to `false`, the command is executed asynchronously.
+- If not preset or set to `true`, it is executed synchronously.
+- Synchronous execution is achieved by passing the command into `std::system` on all systems.
+- Asynchronous execution is achieved by calling `fork()` on POSIX-compatible systems or `CreateProcess()` on Windows.
+
+##### `EXITSTAT`:
+
+- Synchronous execution:
+  - Inferred by the return value of `std::system(cmd)`.
+    - On POSIX-compatible systems: return value is first passed into `WEXITSTATUS(status)`, then assigned to `EXITSTAT`.
+    - On Windows, the value is directly assigned as the return value of `std::system()`.
+- Asynchronous execution:
+  - Value is not modified.
+
+##### `CMDSTAT`:
+
+- Synchronous execution:
   - -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
   - -1: The processor does not support command line execution.
   - \+ (positive value): An error condition occurs.
-    - 1: Fork Error, where `pid_t < 0`, would only occur on POSIX-compatible systems.
-    - 2: Execution Error, a command exits with status -1.
-    - 3: Invalid Command Error, determined by the exit code depending on the system.
-      - On Windows, if the exit code is 1.
-      - On POSIX-compatible systems, if the exit code is 127 or 126.
-    - 4: Signal error, either it is stopped or killed by signal, would only occur on POSIX-compatible systems.
+    - 1: Fork Error (occurs only on POSIX-compatible systems).
+    - 2: Execution Error (command exits with status -1).
+    - 3: Invalid Command Error (determined by the exit code depending on the system).
+      - On Windows: exit code is 1.
+      - On POSIX-compatible systems: exit code is 127 or 126.
+    - 4: Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
   - 0: Otherwise.
+- Asynchronous execution:
+  - 0 will always be assigned.
+
+##### `CMDMSG`:
 
-- **`CMDMSG`:**
-  - If an error condition occurs, it is assigned an explanatory message. Otherwise, it remains unchanged.
+- Synchronous execution:
+  - If an error condition occurs, it is assigned an explanatory message; otherwise, it remains unchanged.
+  - If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated (applies to both POSIX-compatible systems and Windows).
+- Asynchronous execution:
+  - The value is unchanged.
   - If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated.
-    - On POSIX-compatible systems, this applies to both synchronous and asynchronous error termination. When the execution mode is set to async with error termination, the child process (async process) will be terminated with no effect on the parent process (continues).
-    - On Windows, this only applies to synchronous error termination.
+    - On POSIX-compatible systems, the child process (async process) will be terminated with no effect on the parent process (continues).
+    - On Windows, error termination is not initiated.
+

>From 207b1a23c306f2bbbcf02946bd56a862bd7ad015 Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Fri, 12 Jan 2024 17:11:56 +0000
Subject: [PATCH 4/5] word fix, change from "section" to "subclause"

---
 flang/docs/Intrinsics.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 20fd1dfe9beb61a..5ade25740329771 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -847,7 +847,7 @@ used in constant expressions have currently no folding support at all.
 
 #### Usage and Info
 
-- **Standard:** Fortran 2008 and later, specified in Section 16.9.73
+- **Standard:** Fortran 2008 and later, specified in subclause 16.9.73
 - **Class:** Subroutine
 - **Syntax:** `CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])`
 - **Arguments:**

>From d1cff54be30ea65104a27c422de6ef743df2440f Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Mon, 15 Jan 2024 10:43:35 +0000
Subject: [PATCH 5/5] fix optional wait wrongly treated as false

When a optional bool in passed as optional, isStaticallyPresent() will actually return true.
By changing wait from asValue to asAddr and add some check can solve this.
---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 32 ++++++++++++++---
 .../execute_command_line-optional.f90         | 18 +++++-----
 .../Lower/Intrinsics/execute_command_line.f90 | 35 +++++++++++--------
 3 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index ac7d4fbe23e6738..206e5cfa8f48865 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -217,7 +217,7 @@ static constexpr IntrinsicHandler handlers[]{
     {"execute_command_line",
      &I::genExecuteCommandLine,
      {{{"command", asBox},
-       {"wait", asValue, handleDynamicOptional},
+       {"wait", asAddr, handleDynamicOptional},
        {"exitstat", asBox, handleDynamicOptional},
        {"cmdstat", asBox, handleDynamicOptional},
        {"cmdmsg", asBox, handleDynamicOptional}}},
@@ -2913,7 +2913,8 @@ IntrinsicLibrary::genEoshift(mlir::Type resultType,
 // EXECUTE_COMMAND_LINE
 void IntrinsicLibrary::genExecuteCommandLine(
     llvm::ArrayRef<fir::ExtendedValue> args) {
-  assert(args.size() == 5);
+  // Optional KIND argument.
+  assert(args.size() >= 1);
   mlir::Value command = fir::getBase(args[0]);
   const fir::ExtendedValue &wait = args[1];
   const fir::ExtendedValue &exitstat = args[2];
@@ -2925,9 +2926,29 @@ void IntrinsicLibrary::genExecuteCommandLine(
 
   mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType());
 
-  mlir::Value waitBool = isStaticallyPresent(wait)
-                             ? fir::getBase(wait)
-                             : builder.createBool(loc, true);
+  mlir::Value waitBool;
+  if (isStaticallyAbsent(wait)) {
+    waitBool = builder.createBool(loc, true);
+  } else {
+    mlir::Type i1Ty = builder.getI1Type();
+    mlir::Value waitAddr = fir::getBase(wait);
+    mlir::Value waitIsPresentAtRuntime =
+        builder.genIsNotNullAddr(loc, waitAddr);
+    waitBool = builder
+               .genIfOp(loc, {i1Ty}, waitIsPresentAtRuntime,
+                        /*withElseRegion=*/true)
+               .genThen([&]() {
+                 auto waitLoad = builder.create<fir::LoadOp>(loc, waitAddr);
+                 mlir::Value cast = builder.createConvert(loc, i1Ty, waitLoad);
+                 builder.create<fir::ResultOp>(loc, cast);
+               })
+               .genElse([&]() {
+                 mlir::Value trueVal = builder.createBool(loc, true);
+                 builder.create<fir::ResultOp>(loc, trueVal);
+               })
+               .getResults()[0];
+  }
+
   mlir::Value exitstatBox =
       isStaticallyPresent(exitstat)
           ? fir::getBase(exitstat)
@@ -3185,6 +3206,7 @@ void IntrinsicLibrary::genGetEnvironmentVariable(
 
   // Handle optional TRIM_NAME argument
   mlir::Value trim;
+  llvm::outs() << isStaticallyPresent(trimName) << "\n";
   if (isStaticallyAbsent(trimName)) {
     trim = builder.createBool(loc, true);
   } else {
diff --git a/flang/test/Lower/Intrinsics/execute_command_line-optional.f90 b/flang/test/Lower/Intrinsics/execute_command_line-optional.f90
index e51c0e5fca3004e..57fbacc51cc84fe 100644
--- a/flang/test/Lower/Intrinsics/execute_command_line-optional.f90
+++ b/flang/test/Lower/Intrinsics/execute_command_line-optional.f90
@@ -21,18 +21,10 @@ subroutine all_args_optional(command, isWait, exitVal, cmdVal, msg)
 ! CHECK-NEXT:    %[[cmdmsgUnbox:.*]]:2 = fir.unboxchar %[[cmdmsgArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK-NEXT:    %[[cmdmsgDeclare:.*]] = fir.declare %[[cmdmsgUnbox]]#0 typeparams %[[cmdmsgUnbox]]#1 {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFall_args_optionalEmsg"} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.ref<!fir.char<1,?>>
 ! CHECK-NEXT:    %[[cmdmsgBoxTemp:.*]] = fir.emboxchar %[[cmdmsgDeclare]], %[[cmdmsgUnbox]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
-! CHECK-NEXT:    %[[waitIsPresent:.*]] = fir.is_present %[[waitDeclare]] : (!fir.ref<!fir.logical<4>>) -> i1
 ! CHECK-NEXT:    %[[exitstatIsPresent:.*]] = fir.is_present %[[exitstatDeclare]] : (!fir.ref<i32>) -> i1
 ! CHECK-NEXT:    %[[cmdstatIsPresent:.*]] = fir.is_present %[[cmdstatDeclare]] : (!fir.ref<i32>) -> i1
 ! CHECK-NEXT:    %[[cmdmsgIsPresent:.*]] = fir.is_present %[[cmdmsgBoxTemp]] : (!fir.boxchar<1>) -> i1
 ! CHECK-NEXT:    %[[commandBox:.*]] = fir.embox %[[commandDeclare]] typeparams %[[commandUnbox]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
-! CHECK-NEXT:    %[[waitLoaded:.*]] = fir.if %[[waitIsPresent]] -> (!fir.logical<4>) {
-! CHECK-NEXT:      %[[VAL_31:.*]] = fir.load %[[waitDeclare]] : !fir.ref<!fir.logical<4>>
-! CHECK-NEXT:      fir.result %[[VAL_31]] : !fir.logical<4>
-! CHECK-NEXT:    } else {
-! CHECK-NEXT:      %[[VAL_31:.*]] = fir.convert %false : (i1) -> !fir.logical<4>
-! CHECK-NEXT:      fir.result %[[VAL_31]] : !fir.logical<4>
-! CHECK-NEXT:    }
 ! CHECK-NEXT:    %[[exitstatArgBox:.*]] = fir.embox %[[exitstatDeclare]] : (!fir.ref<i32>) -> !fir.box<i32>
 ! CHECK-NEXT:    %[[absentBoxi32:.*]] = fir.absent !fir.box<i32>
 ! CHECK-NEXT:    %[[exitstatBox:.*]] = arith.select %[[exitstatIsPresent]], %[[exitstatArgBox]], %[[absentBoxi32]] : !fir.box<i32>
@@ -41,8 +33,16 @@ subroutine all_args_optional(command, isWait, exitVal, cmdVal, msg)
 ! CHECK-NEXT:    %[[cmdmsgArgBox:.*]] = fir.embox %[[cmdmsgDeclare]] typeparams %[[cmdmsgUnbox]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
 ! CHECK-NEXT:    %[[absentBox:.*]] = fir.absent !fir.box<!fir.char<1,?>> 
 ! CHECK-NEXT:    %[[cmdmsgBox:.*]] = arith.select %[[cmdmsgIsPresent]], %[[cmdmsgArgBox]], %[[absentBox]] : !fir.box<!fir.char<1,?>>
+! CHECK-NEXT:    %[[waitCast:.*]] = fir.convert %[[waitDeclare]]  : (!fir.ref<!fir.logical<4>>) -> i64
+! CHECK-NEXT:    %[[waitPresent:.*]] = arith.cmpi ne, %[[waitCast]], %c0_i64 : i64
+! CHECK-NEXT:    %[[wait:.*]] = fir.if %[[waitPresent]] -> (i1) {
+! CHECK-NEXT:      %[[waitLoaded:.*]] = fir.load %[[waitDeclare]] : !fir.ref<!fir.logical<4>>
+! CHECK-NEXT:      %[[waitTrueVal:.*]] = fir.convert %[[waitLoaded]] : (!fir.logical<4>) -> i1
+! CHECK-NEXT:      fir.result %[[waitTrueVal]] : i1
+! CHECK-NEXT:    } else {
+! CHECK-NEXT:      fir.result %true : i1
+! CHECK-NEXT:    }
 ! CHECK:         %[[command:.*]] = fir.convert %[[commandBox]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
-! CHECK-NEXT:    %[[wait:.*]] = fir.convert %[[waitLoaded]] : (!fir.logical<4>) -> i1
 ! CHECK-NEXT:    %[[exitstat:.*]] = fir.convert %[[exitstatBox]] : (!fir.box<i32>) -> !fir.box<none>
 ! CHECK-NEXT:    %[[cmdstat:.*]] = fir.convert %[[cmdstatBox]] : (!fir.box<i32>) -> !fir.box<none>
 ! CHECK-NEXT:    %[[cmdmsg:.*]] = fir.convert %[[cmdmsgBox]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
diff --git a/flang/test/Lower/Intrinsics/execute_command_line.f90 b/flang/test/Lower/Intrinsics/execute_command_line.f90
index 1b65bbd5e1550ce..92234c39110ca42 100644
--- a/flang/test/Lower/Intrinsics/execute_command_line.f90
+++ b/flang/test/Lower/Intrinsics/execute_command_line.f90
@@ -11,26 +11,33 @@ subroutine all_args(command, isWait, exitVal, cmdVal, msg)
 INTEGER :: exitVal, cmdVal
 LOGICAL :: isWait
 call execute_command_line(command, isWait, exitVal, cmdVal, msg)
-! CHECK:             %[[cmdstatsDeclear:.*]] = fir.declare %[[cmdstatArg]] {uniq_name = "_QFall_argsEcmdval"} : (!fir.ref<i32>) -> !fir.ref<i32>
+! CHECK:             %[[cmdstatsDeclare:.*]] = fir.declare %[[cmdstatArg]] {uniq_name = "_QFall_argsEcmdval"} : (!fir.ref<i32>) -> !fir.ref<i32>
 ! CHECK-NEXT:        %[[commandUnbox:.*]]:2 = fir.unboxchar %[[commandArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK-NEXT:        %[[commandCast:.*]] = fir.convert %[[commandUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,30>>
-! CHECK-NEXT:        %[[commandDeclear:.*]] = fir.declare %[[commandCast]] typeparams %c30 {uniq_name = "_QFall_argsEcommand"} : (!fir.ref<!fir.char<1,30>>, index) -> !fir.ref<!fir.char<1,30>>
-! CHECK-NEXT:        %[[exitstatDeclear:.*]] = fir.declare %[[exitstatArg]] {uniq_name = "_QFall_argsEexitval"} : (!fir.ref<i32>) -> !fir.ref<i32>
-! CHECK-NEXT:        %[[waitDeclear:.*]] = fir.declare %[[waitArg]] {uniq_name = "_QFall_argsEiswait"} : (!fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>>
+! CHECK-NEXT:        %[[commandDeclare:.*]] = fir.declare %[[commandCast]] typeparams %c30 {uniq_name = "_QFall_argsEcommand"} : (!fir.ref<!fir.char<1,30>>, index) -> !fir.ref<!fir.char<1,30>>
+! CHECK-NEXT:        %[[exitstatDeclare:.*]] = fir.declare %[[exitstatArg]] {uniq_name = "_QFall_argsEexitval"} : (!fir.ref<i32>) -> !fir.ref<i32>
+! CHECK-NEXT:        %[[waitDeclare:.*]] = fir.declare %[[waitArg]] {uniq_name = "_QFall_argsEiswait"} : (!fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>>
 ! CHECK-NEXT:        %[[cmdmsgUnbox:.*]]:2 = fir.unboxchar %[[cmdmsgArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK-NEXT:        %[[cmdmsgCast:.*]] = fir.convert %[[cmdmsgUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,30>>
-! CHECK-NEXT:        %[[cmdmsgDeclear:.*]] = fir.declare %[[cmdmsgCast]] typeparams %c30 {uniq_name = "_QFall_argsEmsg"} : (!fir.ref<!fir.char<1,30>>, index) -> !fir.ref<!fir.char<1,30>>
-! CHECK-NEXT:        %[[commandBox:.*]] = fir.embox %[[commandDeclear]] : (!fir.ref<!fir.char<1,30>>) -> !fir.box<!fir.char<1,30>>
-! CHECK-NEXT:        %[[waitLoaded:.*]] = fir.load %[[waitDeclear]] : !fir.ref<!fir.logical<4>>
-! CHECK-NEXT:        %[[exitstatBox:.*]] = fir.embox %[[exitstatDeclear]] : (!fir.ref<i32>) -> !fir.box<i32>
-! CHECK-NEXT:        %[[cmdstatBox:.*]] = fir.embox %[[cmdstatsDeclear]] : (!fir.ref<i32>) -> !fir.box<i32>
-! CHECK-NEXT:        %[[cmdmsgBox:.*]] = fir.embox %[[cmdmsgDeclear]] : (!fir.ref<!fir.char<1,30>>) -> !fir.box<!fir.char<1,30>>
+! CHECK-NEXT:        %[[cmdmsgDeclare:.*]] = fir.declare %[[cmdmsgCast]] typeparams %c30 {uniq_name = "_QFall_argsEmsg"} : (!fir.ref<!fir.char<1,30>>, index) -> !fir.ref<!fir.char<1,30>>
+! CHECK-NEXT:        %[[commandBox:.*]] = fir.embox %[[commandDeclare]] : (!fir.ref<!fir.char<1,30>>) -> !fir.box<!fir.char<1,30>>
+! CHECK-NEXT:        %[[exitstatBox:.*]] = fir.embox %[[exitstatDeclare]] : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK-NEXT:        %[[cmdstatBox:.*]] = fir.embox %[[cmdstatsDeclare]] : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK-NEXT:        %[[cmdmsgBox:.*]] = fir.embox %[[cmdmsgDeclare]] : (!fir.ref<!fir.char<1,30>>) -> !fir.box<!fir.char<1,30>>
+! CHECK-NEXT:        %[[waitCast:.*]] = fir.convert %[[waitDeclare]]  : (!fir.ref<!fir.logical<4>>) -> i64
+! CHECK-NEXT:        %[[waitPresent:.*]] = arith.cmpi ne, %[[waitCast]], %c0_i64 : i64
+! CHECK-NEXT:        %[[wait:.*]] = fir.if %[[waitPresent]] -> (i1) {
+! CHECK-NEXT:          %[[waitLoaded:.*]] = fir.load %[[waitDeclare]] : !fir.ref<!fir.logical<4>>
+! CHECK-NEXT:          %[[waitTrueVal:.*]] = fir.convert %[[waitLoaded]] : (!fir.logical<4>) -> i1
+! CHECK-NEXT:          fir.result %[[waitTrueVal]] : i1
+! CHECK-NEXT:        } else {
+! CHECK-NEXT:          fir.result %true : i1
+! CHECK-NEXT:        }
 ! CHECK:             %[[command:.*]] = fir.convert %[[commandBox]] : (!fir.box<!fir.char<1,30>>) -> !fir.box<none>
-! CHECK-NEXT:        %[[wait:.*]] = fir.convert %[[waitLoaded]] : (!fir.logical<4>) -> i1
 ! CHECK-NEXT:        %[[exitstat:.*]] = fir.convert %[[exitstatBox]] : (!fir.box<i32>) -> !fir.box<none>
 ! CHECK-NEXT:        %[[cmdstat:.*]] = fir.convert %[[cmdstatBox]] : (!fir.box<i32>) -> !fir.box<none>
 ! CHECK-NEXT:        %[[cmdmsg:.*]] = fir.convert %[[cmdmsgBox]] : (!fir.box<!fir.char<1,30>>) -> !fir.box<none>
-! CHECK:             %[[VAL_21:.*]] = fir.call @_FortranAExecuteCommandLine(%[[command]], %[[wait]], %[[exitstat]], %[[cmdstat]], %[[cmdmsg]], %[[VAL_20:.*]], %c13_i32) fastmath<contract> : (!fir.box<none>, i1, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+! CHECK:             %[[VAL_22:.*]] = fir.call @_FortranAExecuteCommandLine(%[[command]], %[[wait]], %[[exitstat]], %[[cmdstat]], %[[cmdmsg]], %[[VAL_20:.*]], %c13_i32) fastmath<contract> : (!fir.box<none>, i1, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
 ! CHECK-NEXT:        return
 end subroutine all_args
 
@@ -39,7 +46,7 @@ end subroutine all_args
 subroutine only_command_default_wait_true(command)
 CHARACTER(30) :: command
 call execute_command_line(command)
-! CHECK-NEXT:     %c41_i32 = arith.constant 41 : i32 
+! CHECK-NEXT:     %c48_i32 = arith.constant 48 : i32 
 ! CHECK-NEXT:     %true = arith.constant true 
 ! CHECK-NEXT:     %c30 = arith.constant 30 : index
 ! CHECK-NEXT:     %[[commandUnbox:.*]]:2 = fir.unboxchar %[[cmdArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
@@ -48,6 +55,6 @@ subroutine only_command_default_wait_true(command)
 ! CHECK-NEXT:     %[[commandBox:.*]] = fir.embox %[[commandDeclare]] : (!fir.ref<!fir.char<1,30>>) -> !fir.box<!fir.char<1,30>>
 ! CHECK-NEXT:     %[[absent:.*]] = fir.absent !fir.box<none>
 ! CHECK:          %[[command:.*]] = fir.convert %[[commandBox]] : (!fir.box<!fir.char<1,30>>) -> !fir.box<none> 
-! CHECK:          %[[VAL_21:.*]] = fir.call @_FortranAExecuteCommandLine(%[[command]], %true, %[[absent]], %[[absent]], %[[absent]], %[[VAL_7:.*]], %c41_i32) fastmath<contract> : (!fir.box<none>, i1, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+! CHECK:          %[[VAL_8:.*]] = fir.call @_FortranAExecuteCommandLine(%[[command]], %true, %[[absent]], %[[absent]], %[[absent]], %[[VAL_7:.*]], %c48_i32) fastmath<contract> : (!fir.box<none>, i1, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
 ! CHECK-NEXT:     return
 end subroutine only_command_default_wait_true



More information about the flang-commits mailing list