[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