28 Commits

Author SHA1 Message Date
Slava Zakharin
50d848d076
[flang] Added lowering and runtime for COMPLEX(16) intrinsics. (#83874)
For `LDBL_MANT_DIG == 113` targets the FortranFloat128Math library
is just an interface library that provides sources and compilation
options to be used for building FortranRuntime - there are not extra
dependencies on other libraries, so it can be a part of FortranRuntime,
which helps to avoid extra linking steps in the compiler driver.
Targets with __float128 support in libc will also use this path.
Other targets, where the math support comes from
FLANG_RUNTIME_F128_MATH_LIB,
FortranFloat128Math is built as a standalone static library,
and the compiler driver needs to conduct the linking.

Flang APIs for COMPLEX(16) are just thin C wrappers around
the C math functions. Flang uses C _Complex ABI for passing/returning
COMPLEX values, so the runtime is aligned to this.
2024-03-05 13:36:48 -08:00
Slava Zakharin
c5cdf3432a
[flang][runtime] Partial revert of #83383. (#83478)
For `LDBL_MANT_DIG == 113` targets the REAL(16) versions of F18
runtime APIs can stay and should better stay in FortranRuntime.
This way, no additional linking actions are required, because
glibc provides all that is needed.
I thought I would isolate all REAL(16) implementations (both
via `__float128` and `long double`) into Float128Math library,
but that was a bad idea.

This should fix aarch64 buildbots failing gfortran tests.
2024-02-29 14:47:28 -08:00
Slava Zakharin
0699749cb4
[flang][runtime] Moved support for some REAL(16) intrinsics to Float128Math. (#83383)
This adds support for 128-bit float versions of SCALE, NEAREST, MOD,
MODULO, SET_EXPONENT, EXPONENT, FRACTION, SPACING and RRSPACING.
2024-02-29 09:05:43 -08:00
Peter Klausler
dbf547f8ff
[flang][runtime] Add limit check to MOD/MODULO (#80026)
When testing the arguments to see whether they are integers, check first
that they are within the maximum range of a 64-bit integer; otherwise, a
value of larger magnitude will set an invalid operand exception flag.
2024-01-31 11:50:30 -08:00
Peter Klausler
e6fdbd1776
[flang][runtime] Add special-case faster path to real MOD/MODULO (#79625)
When a real-valued reference to the MOD/MODULO intrinsic functions has
operands that are exact integers, use the fast exact integer algorithm
rather than calling std::fmod.
2024-01-29 14:13:27 -08:00
Peter Klausler
e8a5010c03
[flang][runtime] Use std::fmod for most MOD/MODULO (#78745)
The new accurate algorithm for real MOD and MODULO in the runtime is not
as fast as std::fmod(), which is also accurate. So use std::fmod() for
those floating-point types that it supports.

Fixes https://github.com/llvm/llvm-project/issues/78641.
2024-01-25 15:24:54 -08:00
Peter Klausler
f089691157
[flang][runtime] Better real MOD/MODULO results (#77167)
The Fortran standard defines real MOD and MODULO with expressions like
MOD(a,p) = a - AINT(a/p)*p. Unfortunately, these definitions have poor
accuracy when a is much larger in magnitude than p, and every Fortran
compiler uses better algorithms instead.

Fixes llvm-test-suite/Fortran/gfortran/regression/mod_large_1.f90.
2024-01-15 11:48:36 -08:00
Slava Zakharin
76facde32c
[flang][runtime] Enable more APIs in the offload build. (#76486) 2023-12-28 13:50:43 -08:00
Peter Klausler
39c2f59709
[flang][runtime] Fix NEAREST() when exponent decreases (#75368)
When the result of NEAREST() has an exponent less than that of the
argument (e.g., NEAREST(1.,-1.) and NEAREST(-1.,1.)), the result was
wrong, because the increment value uses the result of SPACING() in terms
of the argument. Fix by just calling into the C runtime routine
std::nextafter().
2023-12-26 15:28:36 -08:00
Slava Zakharin
b4b23ff7f8
[flang][runtime] Enable more APIs in the offload build. (#75996)
This patch enables more numeric (mod, sum, matmul, etc.) APIs,
and some others.

I added new macros to disable warnings about using C++ STD methods
like operators of std::complex, which do not have __device__ attribute.
This may probably result in unresolved references, if the header files
implementation relies on libstdc++. I will need to follow up on this.
2023-12-20 11:52:51 -08:00
Peter Klausler
1c35c1a739
[flang] Allow runtime build with AVOID_NATIVE_INT128_T=1
This patch enables the Fortran runtime support library to be
built without native 128-bit integer support in the C++ compiler.

Experimental: do not merge yet.

Differential Revision: https://reviews.llvm.org/D154660
2023-09-01 08:54:38 -07:00
Peter Steinfeld
478e0b5860 [flang] Quadmath 128 bit floating point intrinsics
This update allows constant folding for many 128 bit floating point intrinsics
through the library quadmath, which is only available on some platforms.

Differential Revision: https://reviews.llvm.org/D156435
2023-07-31 11:12:29 -07:00
V Donaldson
6c9c69bd76 [flang] Retain the sign of the argument for the result of fraction(0)
The f18 clause 16.9.80 description of the FRACTION(X) intrinsic states:

    Result Value. The result has the value ....
    If X has the value zero, the result is zero.
    If X is an IEEE NaN, the result is that NaN.
    If X is an IEEE infinity, the result is an IEEE NaN.

This clause does not specify whether fraction(-0.0) should be -0.0 or +0.0.
However, a folded result and a runtime result should be consistent, and
returning -0.0 is more in line with the result for fraction(NaN).

For this test:

  print '(2f6.1)', 0.0, fraction(0.0)
  call f(0.0)
  print '(2f6.1)', -0.0, fraction(-0.0)
  call f(-0.0)
  end

  subroutine f(x)
    print '(2f6.1)', x, fraction(x)
  end

Current output is:

   0.0   0.0
   0.0   0.0
  -0.0  -0.0
  -0.0   0.0

Change that to:

   0.0   0.0
   0.0   0.0
  -0.0  -0.0
  -0.0  -0.0
2023-05-26 09:24:30 -07:00
Peter Klausler
d71297ce74
[flang] Fix SPACING() of very small values
SPACING() must return TINY() for zero arguments (which we do)
and also for subnormal values smaller than TINY() in absolute value,
which we get wrong.  Fix folding and the runtime.

Differential Revision: https://reviews.llvm.org/D151272
2023-05-24 08:04:39 -07:00
Slava Zakharin
9e8f677299 [flang] Lower exponentiation without using pgmath.
Exponentiation is lowered to either math::FPowI or Fortran runtime
call (in case of --math-runtime=precise).

MathToFuncs convertor will convert math::FPowI operations with
exponent width >32 to calls of outlined implementations and otherwise
will leave the operation to MathToLLVM convertor.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D139806
2022-12-14 15:32:51 -08:00
Peixin Qiao
f532c07211 [flang] Support intrinsic selected_int_kind for variables
As Fortran 2018 16.9.169, the argument of selected_int_kind is integer
scalar, and result is default integer scalar. The constant expression in
this intrinsic has been supported by folding the constant expression.
This supports lowering and runtime for variables in this intrinsic.

Reviewed By: Jean Perier

Differential Revision: https://reviews.llvm.org/D129959
2022-07-26 00:33:27 +08:00
Peixin Qiao
57e3fa3815 [flang] Support lowering intrinsic selected_real_kind for variables
As Fortran 2018 16.9.170, the argument of `selected_real_kind` is integer
scalar, and result is default integer scalar. The constant expression in
this intrinsic has been supported by folding the constant expression.
This supports lowering this intrinsic for variables using runtime.

Reviewed By: Jean Perier

Differential Revision: https://reviews.llvm.org/D130183
2022-07-25 19:36:14 +08:00
Peixin Qiao
3ccd4ce29c [flang] Support aint/anint for 80/128 bit in lowering
For aint/anint, LLVM conversion operations llvm.trunc and llvm.round
can support the edge case of aint(-0.) and anint(-0.). The output is -0.
and it is the same of `gfortran` and `classic flang`, while the output
of `ifort` is 0.. The `real(10)/real(16)` is not supported before.
Support it and remove the runtime functions for aint/anint.

For nint, `gfortran`, `ifort`, and LLVM Flang using llvm.lround have
different results when the magnitude of argument is more than the max of
result value range. So delay its support in lowering after more
investigations.

Reviewed By: vzakhari

Differential Revision: https://reviews.llvm.org/D130024
2022-07-23 14:44:20 +08:00
Peter Steinfeld
9f9e9d9cfc [flang] SET_EXPONENT(-0.0) should return -0.0
Section 16.9.171 says:

If X has the value zero, the result has the same value as X

So if X is -0.0, SET_EXPONENT should return -0.0.

Differential Revision: https://reviews.llvm.org/D129309
2022-07-07 12:43:30 -07:00
Peter Klausler
715283aa17 [flang] Cope with overflow in real MOD/MODULO
In folding and in the runtime library for real MOD/MODULO(A,P),
detect overflow from the division A/P and return a properly signed
zero result.  (When A/P overflows and both A and P are finite numbers
with nonzero P, the quotient would be a large integer when rounded to
the precision of the floating-point representation.)

Differential Revision: https://reviews.llvm.org/D129020
2022-07-06 17:31:11 -07:00
Peter Klausler
4daa33f6d1 [flang][runtime] Use __float128 where possible & needed in runtime
On targets with __float128 available and distinct from long double,
use it to support more kind=16 entry points.  This affects mostly
x86-64 targets.  This means that more runtime entry points are
defined for lowering to call.

Delete Common/long-double.h and its LONG_DOUBLE macro in favor of
testing the standard macro LDBL_MANT_DIG.

Differential Revision: https://reviews.llvm.org/D127025
2022-06-05 09:16:57 -07:00
Peter Klausler
562fd2c99b [flang][runtime] Emit error message rather than crashing for MOD(ULO)(x,P=0)
Add extra arguments and checks to the runtime support library so that
a call to the intrinsic functions MOD and MODULO with "denominator"
argument P of zero will cause a crash with a source location rather
than an uninformative floating-point error or integer division by
zero signal.

Additional work is required in lowering to (1) pass source file path and
source line number arguments and (2) actually call these runtime
library APIs instead of emitting inline code for MOD &/or MODULO.

Differential Revision: https://reviews.llvm.org/D127034
2022-06-04 11:02:48 -07:00
Peter Klausler
830c0b9023 [flang] Move runtime API headers to flang/include/flang/Runtime
Move the closure of the subset of flang/runtime/*.h header files that
are referenced by source files outside flang/runtime (apart from unit tests)
into a new directory (flang/include/flang/Runtime) so that relative
include paths into ../runtime need not be used.

flang/runtime/pgmath.h.inc is moved to flang/include/flang/Evaluate;
it's not used by the runtime.

Differential Revision: https://reviews.llvm.org/D109107
2021-09-03 11:08:34 -07:00
Diana Picus
651f58bf63 [flang] Remove *- C++ -* incantation from runtime .cpp files. NFC
We should only need to spell the language out in .h files.

Differential Revision: https://reviews.llvm.org/D109138
2021-09-03 07:17:45 +00:00
peter klausler
a05bae6163 [flang] Correct off-by-one error in SET_EXPONENT
SET_EXPONENT is returning values that are too large by a factor
of two.

Differential Revision: https://reviews.llvm.org/D107986
2021-08-12 12:50:16 -07:00
peter klausler
71d868cf90 [flang] Define missing & needed IEEE_ARITHMETIC symbols
Define IEEE_IS_NAN, IEEE_IS_FINITE, & IEEE_REM.

Differential Revision: https://reviews.llvm.org/D100599
2021-04-19 11:44:43 -07:00
peter klausler
c115c28914 [flang] Address more MSVC build issues with reductions
Move #include <complex.h> to complex-reduction.h, where
it is needed in MSVC builds.

Exclude code that requires a native 128-bit integer type from
compilation by MSVC.

Differential Revision: https://reviews.llvm.org/D99806
2021-04-02 15:01:16 -07:00
peter klausler
5f6c5c63c7 [flang] Implement numeric intrinsic functions in runtime
Adds APIs, implementations, and unit tests for AINT, ANINT,
CEILING, EXPONENT, FLOOR, FRACTION, MOD, MODULO, NEAREST, NINT,
RRSPACING, SCALE, SET_EXPONENT, & SPACING.

Differential Revision: https://reviews.llvm.org/D99764
2021-04-01 15:39:32 -07:00