From f326036767aaa179daedbdb62b10ad6ddea18e37 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Fri, 14 Mar 2025 17:13:21 -0700 Subject: [PATCH] [flang-rt] Added IsContiguousUpTo runtime function. (#131048) I want to be able to check if the storage is contiguous in the innermost dimension, so I decided to add an entry point that takes `dim` as the number of leading dimensions to check. It seems that a runtime call might result in less code size even when `dim` is 1, so here it is. For opt-for-speed I am going to inline it in FIR. Depends on #131047. --- flang-rt/lib/runtime/support.cpp | 4 ++++ flang-rt/unittests/Runtime/Support.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/flang-rt/lib/runtime/support.cpp b/flang-rt/lib/runtime/support.cpp index 5a2b0c920aa8..9beb46e48a11 100644 --- a/flang-rt/lib/runtime/support.cpp +++ b/flang-rt/lib/runtime/support.cpp @@ -19,6 +19,10 @@ bool RTDEF(IsContiguous)(const Descriptor &descriptor) { return descriptor.IsContiguous(); } +bool RTDEF(IsContiguousUpTo)(const Descriptor &descriptor, int dim) { + return descriptor.IsContiguous(dim); +} + bool RTDEF(IsAssumedSize)(const Descriptor &descriptor) { return ISO::IsAssumedSize(&descriptor.raw()); } diff --git a/flang-rt/unittests/Runtime/Support.cpp b/flang-rt/unittests/Runtime/Support.cpp index c97a6eae3a15..46c6805d5d23 100644 --- a/flang-rt/unittests/Runtime/Support.cpp +++ b/flang-rt/unittests/Runtime/Support.cpp @@ -78,3 +78,23 @@ TEST(DescriptorBytesFor, Basic) { EXPECT_GT(b, 0U); } } + +TEST(IsContiguous, Basic) { + // ARRAY 1 3 5 + // 2 4 6 + auto array{MakeArray( + std::vector{2, 3}, std::vector{1, 2, 3, 4, 5, 6})}; + StaticDescriptor<2> sectionStaticDesc; + Descriptor §ion{sectionStaticDesc.descriptor()}; + section.Establish(array->type(), array->ElementBytes(), + /*p=*/nullptr, /*rank=*/2); + static const SubscriptValue lbs[]{1, 1}, ubs[]{2, 3}, strides[]{1, 2}; + const auto error{ + CFI_section(§ion.raw(), &array->raw(), lbs, ubs, strides)}; + ASSERT_EQ(error, 0) << "CFI_section failed for array: " << error; + + EXPECT_TRUE(RTNAME(IsContiguous)(*array)); + EXPECT_FALSE(RTNAME(IsContiguous)(section)); + EXPECT_TRUE(RTNAME(IsContiguousUpTo)(section, 1)); + EXPECT_FALSE(RTNAME(IsContiguousUpTo)(section, 2)); +}