[flang] [llvm] [flang-rt] Runtime implementation of extended intrinsic function SECNDS() (PR #152021)
Peter Klausler via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 6 09:56:34 PDT 2025
================
@@ -303,6 +304,75 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
// PERROR(STRING)
void RTNAME(Perror)(const char *str) { perror(str); }
+// GNU extension function SECNDS(refTime)
+float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) {
+ constexpr float FAIL_SECNDS{-1.0f}; // Failure code for this function
+ // Failure code for time functions that return std::time_t
+ constexpr std::time_t FAIL_TIME{std::time_t{-1}};
+ constexpr std::time_t TIME_UNINITIALIZED{std::time_t{0}};
+ if (!refTime) {
+ return FAIL_SECNDS;
+ }
+ std::time_t now{std::time(nullptr)};
+ if (now == FAIL_TIME) {
+ return FAIL_SECNDS;
+ }
+ // In float result, we can only precisely store 2^24 seconds, which
+ // comes out to about 194 days. Thus, need to pick a starting point,
+ // which will allow us to keep the time diffs as precise as possible.
+ // Given the description of this function, midnight of the current
+ // day is the best starting point.
+ static std::atomic<std::time_t> startingPoint{TIME_UNINITIALIZED};
+ // "Acquire" will give us writes from other threads.
+ std::time_t localStartingPoint{startingPoint.load(std::memory_order_acquire)};
+ // Initialize startingPoint if we haven't initialized it yet or
+ // if we were passed 0.0f, which indicates to compute seconds from
+ // current day's midnight.
+ if (localStartingPoint == TIME_UNINITIALIZED || *refTime < 0.5f) {
----------------
klausler wrote:
You don't need the `f` suffix, and the comparison will be true for both `0.` and `-0.` inputs. If that's what was documented, it's best to stick to it.
https://github.com/llvm/llvm-project/pull/152021
More information about the llvm-commits
mailing list