[flang] [llvm] [flang][flang-rt] Add support for non-standard TIMEF intrinsic (PR #185377)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 21:49:45 PDT 2026


https://github.com/NimishMishra updated https://github.com/llvm/llvm-project/pull/185377

>From dcec8ea682cbd77a8b4d8f378850b25cb4110b1e Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Mon, 9 Mar 2026 12:37:26 +0530
Subject: [PATCH 1/5] [flang][flang-rt] Implement non-standard TIMEF intrinsic

---
 flang-rt/lib/runtime/extensions.cpp               | 13 +++++++++++++
 flang-rt/unittests/Runtime/Time.cpp               | 14 ++++++++++++++
 .../flang/Optimizer/Builder/IntrinsicCall.h       |  1 +
 .../flang/Optimizer/Builder/Runtime/Intrinsics.h  |  3 +++
 flang/include/flang/Runtime/time-intrinsic.h      |  3 +++
 flang/lib/Evaluate/intrinsics.cpp                 |  1 +
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp     |  8 ++++++++
 .../lib/Optimizer/Builder/Runtime/Intrinsics.cpp  |  8 ++++++++
 flang/test/Lower/Intrinsics/timef.f90             | 15 +++++++++++++++
 9 files changed, 66 insertions(+)
 create mode 100644 flang/test/Lower/Intrinsics/timef.f90

diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index b06b9eabe2c60..126cadadc1619 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -413,6 +413,19 @@ double RTNAME(Dsecnds)(double *refTime, const char *sourceFile, int line) {
 // GNU extension function TIME()
 std::int64_t RTNAME(time)() { return time(nullptr); }
 
+// Intel extension function TIMEF()
+// Returns number of seconds that have elapsed since the first time 
+// TIMEF was called. For the first call, it returns 0.
+double RTNAME(Timef)() {
+        static double first = -1;
+	if(first < 0){
+		first = time(nullptr);
+		return 0;
+	}
+	else
+		return time(nullptr) - first;
+}
+
 // MCLOCK: returns accumulated CPU time in ticks
 std::int32_t FORTRAN_PROCEDURE_NAME(mclock)() { return std::clock(); }
 
diff --git a/flang-rt/unittests/Runtime/Time.cpp b/flang-rt/unittests/Runtime/Time.cpp
index 548c0834e34a3..be668e9a8f3c2 100644
--- a/flang-rt/unittests/Runtime/Time.cpp
+++ b/flang-rt/unittests/Runtime/Time.cpp
@@ -31,6 +31,20 @@ TEST(TimeIntrinsics, CpuTime) {
   }
 }
 
+TEST(TimeIntrinsics, Timef) {
+  // We can't really test that we get the "right" result for Timef, but we
+  // can have a smoke test to see that we get something reasonable on the
+  // platforms where we expect to support it.
+  double start{RTNAME(Timef)()};
+  ASSERT_GE(start, 0.0);
+
+  // Loop until we get a different value from Timef
+  for (double end = start; end == start; end = RTNAME(CpuTime)()) {
+    ASSERT_GE(end, 0.0);
+    ASSERT_GE(end, start);
+  }
+}
+
 using count_t = std::int64_t;
 
 TEST(TimeIntrinsics, SystemClock) {
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index ca9677a8cb2b1..c54a4cf120394 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -214,6 +214,7 @@ struct IntrinsicLibrary {
   void genExecuteCommandLine(mlir::ArrayRef<fir::ExtendedValue> args);
   fir::ExtendedValue genEtime(std::optional<mlir::Type>,
                               mlir::ArrayRef<fir::ExtendedValue> args);
+  mlir::Value genTimef(mlir::Type resultType, llvm::ArrayRef<mlir::Value> args);
   mlir::Value genExponent(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genExtendsTypeOf(mlir::Type,
                                       llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
index 1f751827309a4..d6f0f5051e219 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
@@ -82,6 +82,9 @@ mlir::Value genSecnds(fir::FirOpBuilder &builder, mlir::Location loc,
 /// generate time runtime call
 mlir::Value genTime(fir::FirOpBuilder &builder, mlir::Location loc);
 
+/// generate timef runtime call
+mlir::Value genTimef(fir::FirOpBuilder &builder, mlir::Location loc);
+
 /// generate runtime call to transfer intrinsic with no size argument
 void genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
                  mlir::Value resultBox, mlir::Value sourceBox,
diff --git a/flang/include/flang/Runtime/time-intrinsic.h b/flang/include/flang/Runtime/time-intrinsic.h
index 80490a17e4559..4df151451d735 100644
--- a/flang/include/flang/Runtime/time-intrinsic.h
+++ b/flang/include/flang/Runtime/time-intrinsic.h
@@ -26,6 +26,9 @@ extern "C" {
 // real kind.
 double RTNAME(CpuTime)();
 
+// Interface for Timef()
+double RTNAME(Timef)();
+
 // Interface for the SYSTEM_CLOCK intrinsic. We break it up into 3 distinct
 // function calls, one for each of SYSTEM_CLOCK's optional output arguments.
 // Lowering converts the results to the types of the actual arguments,
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 84cd2288fcd0b..d304ffcff49a1 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1030,6 +1030,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
         IntrinsicClass::transformationalFunction},
     {"time", {}, TypePattern{IntType, KindCode::exactKind, 8}, Rank::scalar,
         IntrinsicClass::transformationalFunction},
+    {"timef", {}, TypePattern{RealType, KindCode::exactKind, 8}, Rank::scalar},
     {"tiny",
         {{"x", SameReal, Rank::anyOrAssumedRank, Optionality::required,
             common::Intent::In,
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index d6dee88f422e0..b09e72e664864 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -806,6 +806,7 @@ static constexpr IntrinsicHandler handlers[]{
        {"team", asBox, handleDynamicOptional}}},
      /*isElemental=*/false},
     {"time", &I::genTime, {}, /*isElemental=*/false},
+    {"timef", &I::genTimef, {}, /*isElemental=*/false},
     {"tokenize",
      &I::genTokenize,
      {{{"string", asAddr},
@@ -8264,6 +8265,13 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType,
   return builder.createConvert(loc, resultType, res);
 }
 
+// TIMEF
+mlir::Value IntrinsicLibrary::genTimef(mlir::Type resultType,
+                                       llvm::ArrayRef<mlir::Value> args) {
+  assert(args.empty() && "timef does not accept any args");
+  return fir::runtime::genTimef(builder, loc);
+}
+
 // TRAILZ
 mlir::Value IntrinsicLibrary::genTrailz(mlir::Type resultType,
                                         llvm::ArrayRef<mlir::Value> args) {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
index a5f16f89b260a..dc87638937d7a 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
@@ -327,6 +327,14 @@ mlir::Value fir::runtime::genTime(fir::FirOpBuilder &builder,
       .getResult(0);
 }
 
+/// generate runtime call to timef intrinsic
+mlir::Value fir::runtime::genTimef(fir::FirOpBuilder &builder,
+                                   mlir::Location loc) {
+  auto func = fir::runtime::getRuntimeFunc<mkRTKey(Timef)>(loc, builder);
+  return fir::CallOp::create(builder, loc, func, mlir::ValueRange{})
+      .getResult(0);
+}
+
 /// generate runtime call to transfer intrinsic with no size argument
 void fir::runtime::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
                                mlir::Value resultBox, mlir::Value sourceBox,
diff --git a/flang/test/Lower/Intrinsics/timef.f90 b/flang/test/Lower/Intrinsics/timef.f90
new file mode 100644
index 0000000000000..5ec4a71e49d29
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/timef.f90
@@ -0,0 +1,15 @@
+!RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+!RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+
+subroutine test_timef(t)
+  real(8) :: t
+  t = timef()
+end subroutine
+! CHECK-LABEL:   func.func @_QPtest_timef(
+! CHECK-SAME:                                %[[VAL_0:.*]]: !fir.ref<f64> {fir.bindc_name = "t"}) {
+! CHECK:           %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_timefEt"} : (!fir.ref<f64>, !fir.dscope) -> (!fir.ref<f64>, !fir.ref<f64>)
+! CHECK:           %[[VAL_4:.*]] = fir.call @_FortranATimef() fastmath<contract> : () -> f64
+! CHECK:           hlfir.assign %[[VAL_4]] to %[[VAL_3]]#0 : f64, !fir.ref<f64>
+! CHECK:           return
+! CHECK:         }

>From 49249bae9b39e2d6d3ef36a516adc08863d07cca Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Mon, 9 Mar 2026 13:45:30 +0530
Subject: [PATCH 2/5] Add documentation changes

---
 flang-rt/lib/runtime/extensions.cpp | 15 +++++++--------
 flang/docs/Intrinsics.md            | 13 +++++++++++++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 126cadadc1619..3ffeec511da31 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -414,16 +414,15 @@ double RTNAME(Dsecnds)(double *refTime, const char *sourceFile, int line) {
 std::int64_t RTNAME(time)() { return time(nullptr); }
 
 // Intel extension function TIMEF()
-// Returns number of seconds that have elapsed since the first time 
+// Returns number of seconds that have elapsed since the first time
 // TIMEF was called. For the first call, it returns 0.
 double RTNAME(Timef)() {
-        static double first = -1;
-	if(first < 0){
-		first = time(nullptr);
-		return 0;
-	}
-	else
-		return time(nullptr) - first;
+  static double first = -1;
+  if (first < 0) {
+    first = time(nullptr);
+    return 0;
+  } else
+    return time(nullptr) - first;
 }
 
 // MCLOCK: returns accumulated CPU time in ticks
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 330fcf303de0e..56d63978070c1 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1233,6 +1233,19 @@ PROGRAM example_time
 END PROGRAM
 ```
 
+### Non-Standard Intrinsics: TIMEF
+
+#### Description
+`TIMEF` returns the number of seconds that have 
+elapsed since the first time TIMEF was called.
+The first time it is called, TIMEF returns 0.
+
+#### Usage and Info
+
+- **Standard:** Intel extension
+- **Class:** function
+- **Syntax:** `RESULT = TIMEF()`
+
 ### Non-Standard Intrinsics: UNLINK
 
 #### Description

>From 6943754d514882572665b2e7f8e6fa5e26a778cb Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Sat, 28 Mar 2026 18:43:01 +0530
Subject: [PATCH 3/5] Add environment variable to fix resolution

---
 .../include/flang-rt/runtime/environment.h    |  4 ++
 flang-rt/lib/runtime/environment.cpp          | 11 ++++
 flang-rt/lib/runtime/extensions.cpp           | 59 ++++++++++++++++---
 flang/docs/Intrinsics.md                      | 10 +++-
 4 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/environment.h b/flang-rt/include/flang-rt/runtime/environment.h
index 71814aa1d5c1f..2e2f30bdde3ee 100644
--- a/flang-rt/include/flang-rt/runtime/environment.h
+++ b/flang-rt/include/flang-rt/runtime/environment.h
@@ -67,6 +67,10 @@ struct ExecutionEnvironment {
       decimal::FortranRounding::RoundNearest}; // RP(==PN)
   Convert conversion{Convert::Unknown}; // FORT_CONVERT
   bool noStopMessage{false}; // NO_STOP_MESSAGE=1 inhibits "Fortran STOP"
+  /* TIMEF_IN_MILLISECONDS=1 sets TIMEF resolution to milliseconds.
+   * Default resolution is seconds.
+   */
+  bool timefInMillisec{false};
   bool defaultUTF8{false}; // DEFAULT_UTF8
   bool checkPointerDeallocation{true}; // FORT_CHECK_POINTER_DEALLOCATION
   bool truncateStream{true}; // FORT_TRUNCATE_STREAM
diff --git a/flang-rt/lib/runtime/environment.cpp b/flang-rt/lib/runtime/environment.cpp
index 53e13cd929bf8..3c2a5de37ad10 100644
--- a/flang-rt/lib/runtime/environment.cpp
+++ b/flang-rt/lib/runtime/environment.cpp
@@ -168,6 +168,17 @@ void ExecutionEnvironment::Configure(int ac, const char *av[],
     }
   }
 
+  if (auto *x{std::getenv("TIMEF_IN_MILLISECONDS")}) {
+    char *end;
+    auto n{std::strtol(x, &end, 10)};
+    if (n >= 0 && n <= 1 && *end == '\0') {
+      timefInMillisec = n != 0;
+    } else {
+      std::fprintf(stderr,
+          "Fortran runtime: TIMEF_IN_MILLISECONDS=%s is invalid; ignored\n", x);
+    }
+  }
+
   if (auto *x{std::getenv("DEFAULT_UTF8")}) {
     char *end;
     auto n{std::strtol(x, &end, 10)};
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 3ffeec511da31..a707df29d6964 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -12,6 +12,7 @@
 #include "flang/Runtime/extensions.h"
 #include "unit.h"
 #include "flang-rt/runtime/descriptor.h"
+#include "flang-rt/runtime/environment.h"
 #include "flang-rt/runtime/lock.h"
 #include "flang-rt/runtime/terminator.h"
 #include "flang-rt/runtime/tools.h"
@@ -55,6 +56,7 @@ inline void CtimeBuffer(char *buffer, size_t bufsize, const time_t cur_time,
 
 #ifndef _WIN32
 // posix-compliant and has getlogin_r and F_OK
+#include <sys/times.h>
 #include <unistd.h>
 #else
 #include <direct.h>
@@ -66,6 +68,7 @@ namespace Fortran::runtime {
 #define GFC_RAND_M 2147483647
 static unsigned rand_seed = 1;
 static Lock rand_seed_lock;
+static Lock timef_lock;
 
 // Common implementation that could be used for either SECNDS() or DSECNDS(),
 // which are defined for float or double.
@@ -413,16 +416,54 @@ double RTNAME(Dsecnds)(double *refTime, const char *sourceFile, int line) {
 // GNU extension function TIME()
 std::int64_t RTNAME(time)() { return time(nullptr); }
 
-// Intel extension function TIMEF()
-// Returns number of seconds that have elapsed since the first time
-// TIMEF was called. For the first call, it returns 0.
+/*
+ * Extension function TIMEF().
+ * By default, it returns number of seconds that have
+ * elapsed since the first time TIMEF was called.
+ * For the first call, it returns 0.
+ *
+ * TIMEF_IN_MILLISECONDS=1 sets the resolution to
+ * milliseconds
+ */
 double RTNAME(Timef)() {
-  static double first = -1;
-  if (first < 0) {
-    first = time(nullptr);
-    return 0;
-  } else
-    return time(nullptr) - first;
+#ifndef _WIN32
+
+  // posix-compliant
+  static clock_t start = (clock_t)-1;
+  static long ticks_per_sec = 0;
+
+  struct tms b;
+  clock_t current;
+  double duration;
+
+  {
+    CriticalSection critical{timef_lock};
+    if (ticks_per_sec <= 0) {
+      ticks_per_sec = sysconf(_SC_CLK_TCK);
+      if (ticks_per_sec <= 0)
+        return 0.0;
+    }
+
+    if (times(&b) == (clock_t)-1) {
+      return 0.0;
+    }
+
+    current = b.tms_utime + b.tms_stime;
+
+    if (start == (clock_t)-1) {
+      start = current;
+      return 0.0;
+    }
+    if (Fortran::runtime::executionEnvironment.timefInMillisec)
+      duration = ((double)(current - start) * 1000) / (double)ticks_per_sec;
+    else
+      duration = (double)(current - start) / (double)ticks_per_sec;
+
+    return duration;
+  }
+#else
+// TODO: Windows implementation
+#endif
 }
 
 // MCLOCK: returns accumulated CPU time in ticks
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 56d63978070c1..fad822b2b7efd 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1240,9 +1240,17 @@ END PROGRAM
 elapsed since the first time TIMEF was called.
 The first time it is called, TIMEF returns 0.
 
+By default, the behaviour matches that of
+ifort and classic-flang compilers. To
+match behaviour of compilers like XLF
+and nvfortran, use 
+`export TIMEF_IN_MILLISECONDS=1` to 
+ensure TIMEF returns number of milliseconds
+elapsed since last call.
+
 #### Usage and Info
 
-- **Standard:** Intel extension
+- **Standard:** Intel/classic-flang extension
 - **Class:** function
 - **Syntax:** `RESULT = TIMEF()`
 

>From 8a90cbb3eb4d823da7933de58385d54771ccf652 Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Sat, 28 Mar 2026 18:48:19 +0530
Subject: [PATCH 4/5] Add result type and minor formatting fixes

---
 flang-rt/lib/runtime/extensions.cpp | 3 ---
 flang/docs/Intrinsics.md            | 1 +
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index a707df29d6964..ef3e7df481351 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -427,15 +427,12 @@ std::int64_t RTNAME(time)() { return time(nullptr); }
  */
 double RTNAME(Timef)() {
 #ifndef _WIN32
-
   // posix-compliant
   static clock_t start = (clock_t)-1;
   static long ticks_per_sec = 0;
-
   struct tms b;
   clock_t current;
   double duration;
-
   {
     CriticalSection critical{timef_lock};
     if (ticks_per_sec <= 0) {
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index fad822b2b7efd..c67e1b1b92738 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1253,6 +1253,7 @@ elapsed since last call.
 - **Standard:** Intel/classic-flang extension
 - **Class:** function
 - **Syntax:** `RESULT = TIMEF()`
+- **Return type**: REAL(8)
 
 ### Non-Standard Intrinsics: UNLINK
 

>From c2da18cea581ac04a5074edf977d68366e804281 Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Tue, 31 Mar 2026 10:18:36 +0530
Subject: [PATCH 5/5] Address review comments

---
 flang-rt/include/flang-rt/runtime/environment.h |  5 ++---
 flang-rt/lib/runtime/environment.cpp            |  6 ++++--
 flang-rt/lib/runtime/extensions.cpp             |  3 ++-
 flang-rt/unittests/Runtime/Time.cpp             | 12 ++++++------
 flang/docs/Intrinsics.md                        | 13 ++++---------
 5 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/environment.h b/flang-rt/include/flang-rt/runtime/environment.h
index 2e2f30bdde3ee..0dabcaa8a107b 100644
--- a/flang-rt/include/flang-rt/runtime/environment.h
+++ b/flang-rt/include/flang-rt/runtime/environment.h
@@ -67,9 +67,8 @@ struct ExecutionEnvironment {
       decimal::FortranRounding::RoundNearest}; // RP(==PN)
   Convert conversion{Convert::Unknown}; // FORT_CONVERT
   bool noStopMessage{false}; // NO_STOP_MESSAGE=1 inhibits "Fortran STOP"
-  /* TIMEF_IN_MILLISECONDS=1 sets TIMEF resolution to milliseconds.
-   * Default resolution is seconds.
-   */
+  // FLANG_TIMEF_IN_MILLISECONDS=1 sets TIMEF resolution to milliseconds.
+  // Default resolution is seconds.
   bool timefInMillisec{false};
   bool defaultUTF8{false}; // DEFAULT_UTF8
   bool checkPointerDeallocation{true}; // FORT_CHECK_POINTER_DEALLOCATION
diff --git a/flang-rt/lib/runtime/environment.cpp b/flang-rt/lib/runtime/environment.cpp
index 3c2a5de37ad10..373215e28bdfd 100644
--- a/flang-rt/lib/runtime/environment.cpp
+++ b/flang-rt/lib/runtime/environment.cpp
@@ -168,14 +168,16 @@ void ExecutionEnvironment::Configure(int ac, const char *av[],
     }
   }
 
-  if (auto *x{std::getenv("TIMEF_IN_MILLISECONDS")}) {
+  if (auto *x{std::getenv("FLANG_TIMEF_IN_MILLISECONDS")}) {
     char *end;
     auto n{std::strtol(x, &end, 10)};
     if (n >= 0 && n <= 1 && *end == '\0') {
       timefInMillisec = n != 0;
     } else {
       std::fprintf(stderr,
-          "Fortran runtime: TIMEF_IN_MILLISECONDS=%s is invalid; ignored\n", x);
+          "Fortran runtime: FLANG_TIMEF_IN_MILLISECONDS=%s is invalid; "
+          "ignored\n",
+          x);
     }
   }
 
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index ef3e7df481351..782fa21026e1c 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -422,7 +422,7 @@ std::int64_t RTNAME(time)() { return time(nullptr); }
  * elapsed since the first time TIMEF was called.
  * For the first call, it returns 0.
  *
- * TIMEF_IN_MILLISECONDS=1 sets the resolution to
+ * FLANG_TIMEF_IN_MILLISECONDS=1 sets the resolution to
  * milliseconds
  */
 double RTNAME(Timef)() {
@@ -460,6 +460,7 @@ double RTNAME(Timef)() {
   }
 #else
 // TODO: Windows implementation
+return 0.0;
 #endif
 }
 
diff --git a/flang-rt/unittests/Runtime/Time.cpp b/flang-rt/unittests/Runtime/Time.cpp
index be668e9a8f3c2..399c4efeacf15 100644
--- a/flang-rt/unittests/Runtime/Time.cpp
+++ b/flang-rt/unittests/Runtime/Time.cpp
@@ -12,6 +12,7 @@
 #include <cctype>
 #include <cerrno>
 #include <string>
+#include <unistd.h>
 
 using namespace Fortran::runtime;
 
@@ -35,14 +36,13 @@ TEST(TimeIntrinsics, Timef) {
   // We can't really test that we get the "right" result for Timef, but we
   // can have a smoke test to see that we get something reasonable on the
   // platforms where we expect to support it.
-  double start{RTNAME(Timef)()};
+  double start{RTNAME(Timef)()}, end{0.0};
   ASSERT_GE(start, 0.0);
 
-  // Loop until we get a different value from Timef
-  for (double end = start; end == start; end = RTNAME(CpuTime)()) {
-    ASSERT_GE(end, 0.0);
-    ASSERT_GE(end, start);
-  }
+  sleep(2);
+
+  ASSERT_GE(end, 0.0);
+  ASSERT_GE(end, start);
 }
 
 using count_t = std::int64_t;
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index c67e1b1b92738..0d3e182397117 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1236,17 +1236,12 @@ END PROGRAM
 ### Non-Standard Intrinsics: TIMEF
 
 #### Description
-`TIMEF` returns the number of seconds that have 
-elapsed since the first time TIMEF was called.
+`TIMEF` returns the number of seconds that have elapsed since the first time TIMEF was called.
 The first time it is called, TIMEF returns 0.
 
-By default, the behaviour matches that of
-ifort and classic-flang compilers. To
-match behaviour of compilers like XLF
-and nvfortran, use 
-`export TIMEF_IN_MILLISECONDS=1` to 
-ensure TIMEF returns number of milliseconds
-elapsed since last call.
+By default, the behaviour matches that of ifort and classic-flang compilers. To match 
+behaviour of compilers like XLF and nvfortran, use `export FLANG_TIMEF_IN_MILLISECONDS=1` to 
+ensure TIMEF returns number of milliseconds elapsed since the first time TIMEF() was called
 
 #### Usage and Info
 



More information about the llvm-commits mailing list