aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-06-02 14:06:57 -0700
committerPeter Klausler <pklausler@nvidia.com>2022-06-04 11:02:48 -0700
commit562fd2c99b70691affe7776a1900e95ee7da0b3b (patch)
treea2cb3498d56f0ea4e2700b38212a06cb93240929
parent11f928af9bfaefc0965a43f5ad6d480ded3de4a5 (diff)
downloadllvm-562fd2c99b70691affe7776a1900e95ee7da0b3b.zip
llvm-562fd2c99b70691affe7776a1900e95ee7da0b3b.tar.gz
llvm-562fd2c99b70691affe7776a1900e95ee7da0b3b.tar.bz2
[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
-rw-r--r--flang/include/flang/Runtime/numeric.h54
-rw-r--r--flang/runtime/numeric.cpp109
2 files changed, 103 insertions, 60 deletions
diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index 6130a25..a1645eb 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -214,48 +214,66 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16>);
// MOD & MODULO
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
- CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
+ CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
- CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
+ CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
- CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
+ CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
- CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
+ CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
CppTypeFor<TypeCategory::Integer, 16>,
- CppTypeFor<TypeCategory::Integer, 16>);
+ CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
+ int sourceLine = 0);
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
- CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
+ CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
- CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
+ CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
- CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
+ CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
- CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
+ CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
- CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
+ CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
- CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
+ CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
- CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
+ CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
- CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
+ CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
CppTypeFor<TypeCategory::Integer, 16>,
- CppTypeFor<TypeCategory::Integer, 16>);
+ CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
+ int sourceLine = 0);
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
- CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
+ CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
- CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
+ CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
- CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
+ CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
- CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
+ CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
+ const char *sourceFile = nullptr, int sourceLine = 0);
// NINT
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index c04d501..4ffb282 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "terminator.h"
#include "flang/Runtime/numeric.h"
#include "flang/Common/long-double.h"
#include <climits>
@@ -62,14 +63,24 @@ template <typename T> inline T Fraction(T x) {
}
// MOD & MODULO (16.9.135, .136)
-template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) {
+template <bool IS_MODULO, typename T>
+inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) {
+ if (p == 0) {
+ Terminator{sourceFile, sourceLine}.Crash(
+ IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
+ }
auto mod{x - (x / p) * p};
if (IS_MODULO && (x > 0) != (p > 0)) {
mod += p;
}
return mod;
}
-template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) {
+template <bool IS_MODULO, typename T>
+inline T RealMod(T x, T p, const char *sourceFile, int sourceLine) {
+ if (p == 0) {
+ Terminator{sourceFile, sourceLine}.Crash(
+ IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
+ }
if constexpr (IS_MODULO) {
return x - std::floor(x / p) * p;
} else {
@@ -542,99 +553,113 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
CppTypeFor<TypeCategory::Integer, 1> x,
- CppTypeFor<TypeCategory::Integer, 1> p) {
- return IntMod<false>(x, p);
+ CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<false>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
CppTypeFor<TypeCategory::Integer, 2> x,
- CppTypeFor<TypeCategory::Integer, 2> p) {
- return IntMod<false>(x, p);
+ CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<false>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
CppTypeFor<TypeCategory::Integer, 4> x,
- CppTypeFor<TypeCategory::Integer, 4> p) {
- return IntMod<false>(x, p);
+ CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<false>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
CppTypeFor<TypeCategory::Integer, 8> x,
- CppTypeFor<TypeCategory::Integer, 8> p) {
- return IntMod<false>(x, p);
+ CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<false>(x, p, sourceFile, sourceLine);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
CppTypeFor<TypeCategory::Integer, 16> x,
- CppTypeFor<TypeCategory::Integer, 16> p) {
- return IntMod<false>(x, p);
+ CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<false>(x, p, sourceFile, sourceLine);
}
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
- CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
- return RealMod<false>(x, p);
+ CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<false>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
- CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
- return RealMod<false>(x, p);
+ CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<false>(x, p, sourceFile, sourceLine);
}
#if LONG_DOUBLE == 80
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
- CppTypeFor<TypeCategory::Real, 10> x,
- CppTypeFor<TypeCategory::Real, 10> p) {
- return RealMod<false>(x, p);
+ CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<false>(x, p, sourceFile, sourceLine);
}
#elif LONG_DOUBLE == 128
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
- CppTypeFor<TypeCategory::Real, 16> x,
- CppTypeFor<TypeCategory::Real, 16> p) {
- return RealMod<false>(x, p);
+ CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<false>(x, p, sourceFile, sourceLine);
}
#endif
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
CppTypeFor<TypeCategory::Integer, 1> x,
- CppTypeFor<TypeCategory::Integer, 1> p) {
- return IntMod<true>(x, p);
+ CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<true>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
CppTypeFor<TypeCategory::Integer, 2> x,
- CppTypeFor<TypeCategory::Integer, 2> p) {
- return IntMod<true>(x, p);
+ CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<true>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
CppTypeFor<TypeCategory::Integer, 4> x,
- CppTypeFor<TypeCategory::Integer, 4> p) {
- return IntMod<true>(x, p);
+ CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<true>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
CppTypeFor<TypeCategory::Integer, 8> x,
- CppTypeFor<TypeCategory::Integer, 8> p) {
- return IntMod<true>(x, p);
+ CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<true>(x, p, sourceFile, sourceLine);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
CppTypeFor<TypeCategory::Integer, 16> x,
- CppTypeFor<TypeCategory::Integer, 16> p) {
- return IntMod<true>(x, p);
+ CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
+ int sourceLine) {
+ return IntMod<true>(x, p, sourceFile, sourceLine);
}
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
- CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
- return RealMod<true>(x, p);
+ CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<true>(x, p, sourceFile, sourceLine);
}
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
- CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
- return RealMod<true>(x, p);
+ CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<true>(x, p, sourceFile, sourceLine);
}
#if LONG_DOUBLE == 80
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
- CppTypeFor<TypeCategory::Real, 10> x,
- CppTypeFor<TypeCategory::Real, 10> p) {
- return RealMod<true>(x, p);
+ CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<true>(x, p, sourceFile, sourceLine);
}
#elif LONG_DOUBLE == 128
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
- CppTypeFor<TypeCategory::Real, 16> x,
- CppTypeFor<TypeCategory::Real, 16> p) {
- return RealMod<true>(x, p);
+ CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
+ const char *sourceFile, int sourceLine) {
+ return RealMod<true>(x, p, sourceFile, sourceLine);
}
#endif