summaryrefslogtreecommitdiff
path: root/flang/unittests
diff options
context:
space:
mode:
authorSlava Zakharin <szakharin@nvidia.com>2022-09-22 09:31:20 -0700
committerSlava Zakharin <szakharin@nvidia.com>2022-09-22 10:10:42 -0700
commitd37250c9db48d12b6ba66e10a2ccaf8e3e66b547 (patch)
tree2093e82cf83d1b274a048dc82e4fc578b199f5e4 /flang/unittests
parent0ca5993741877ab7fd27a251cbc1895bd092d5ee (diff)
downloadllvm-d37250c9db48d12b6ba66e10a2ccaf8e3e66b547.tar.gz
[flang][runtime] Fixes for element size calculation.
BytesFor() used to return KIND for the size, which is not always correct, so I changed it to return the size of the actual CppType corresponding to the given category and kind. MinElemLen() used to calculate size incorrectly (e.g. CFI_type_extended_double was sized 10, whereas it may occupy more bytes on a target), so I changed it to call BytesFor(). Additional changes were needed to resolve new failures for transformational intrinsics. These intrinsics used to work for not fully supported data types (e.g. REAL(3)), but now stopped working because CppType cannot be computed for those categories/kinds. The solution is to use known element size from the source argument(s) for establishing the destination descriptor - the element size is all that is needed for transformational intrinsics to keep working. Note that this does not help cases, where runtime still has to compute the element size, e.g. when it creates descriptors for components of derived types. If the component has unsupported data type, BytesFor() will still fail. So these cases require adding support for the missing types. New regression unit test in Runtime/Transformational.cpp demonstrates the case that will start working properly with this commit.
Diffstat (limited to 'flang/unittests')
-rw-r--r--flang/unittests/Runtime/Transformational.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/flang/unittests/Runtime/Transformational.cpp b/flang/unittests/Runtime/Transformational.cpp
index 6abe3d638cc9..a4672369f782 100644
--- a/flang/unittests/Runtime/Transformational.cpp
+++ b/flang/unittests/Runtime/Transformational.cpp
@@ -317,3 +317,31 @@ TEST(Transformational, Unpack) {
}
result.Destroy();
}
+
+#if LDBL_MANT_DIG == 64
+// Make sure the destination descriptor is created by the runtime
+// with proper element size, when REAL*10 maps to 'long double'.
+#define Real10CppType long double
+TEST(Transformational, TransposeReal10) {
+ // ARRAY 1 3 5
+ // 2 4 6
+ auto array{MakeArray<TypeCategory::Real, 10>(std::vector<int>{2, 3},
+ std::vector<Real10CppType>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0},
+ sizeof(Real10CppType))};
+ StaticDescriptor<2, true> statDesc;
+ Descriptor &result{statDesc.descriptor()};
+ RTNAME(Transpose)(result, *array, __FILE__, __LINE__);
+ EXPECT_EQ(result.ElementBytes(), sizeof(Real10CppType));
+ EXPECT_EQ(result.type(), array->type());
+ EXPECT_EQ(result.rank(), 2);
+ EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
+ EXPECT_EQ(result.GetDimension(0).Extent(), 3);
+ EXPECT_EQ(result.GetDimension(1).LowerBound(), 1);
+ EXPECT_EQ(result.GetDimension(1).Extent(), 2);
+ static Real10CppType expect[6]{1.0, 3.0, 5.0, 2.0, 4.0, 6.0};
+ for (int j{0}; j < 6; ++j) {
+ EXPECT_EQ(*result.ZeroBasedIndexedElement<Real10CppType>(j), expect[j]);
+ }
+ result.Destroy();
+}
+#endif