diff options
author | jeanPerier <jperier@nvidia.com> | 2024-05-27 10:32:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-27 10:32:33 +0200 |
commit | 2b78c641525b7cea9dec8125b7f5cd06d7ce8fff (patch) | |
tree | 936a6c6a5dff62f508816a086973d38f9f132261 /flang/unittests | |
parent | 7429950d840b8fec3d9a48d00e612a3240c2be83 (diff) | |
download | llvm-2b78c641525b7cea9dec8125b7f5cd06d7ce8fff.zip llvm-2b78c641525b7cea9dec8125b7f5cd06d7ce8fff.tar.gz llvm-2b78c641525b7cea9dec8125b7f5cd06d7ce8fff.tar.bz2 |
[flang] add API to copy and update descriptors for assumed ranks (#93305)
When passing assumed-rank around, the lower bounds, dynamic type and
attribute must sometimes be updated to match the dummy attributes. See
https://github.com/llvm/llvm-project/blob/main/flang/docs/AssumedRank.md#annex-1---descriptor-temporary-for-the-dummy-arguments
for more details.
Doing it inline would require generating many instructions and block CFG
at the LLVM IR dialect level in codegen. Go for a simple runtime API
instead.
A matching fir.rebox_assumed_rank operation will be created and will
allow for easier future optimizations when inlining is done in FIR.
Diffstat (limited to 'flang/unittests')
-rw-r--r-- | flang/unittests/Runtime/CMakeLists.txt | 1 | ||||
-rw-r--r-- | flang/unittests/Runtime/Support.cpp | 58 |
2 files changed, 59 insertions, 0 deletions
diff --git a/flang/unittests/Runtime/CMakeLists.txt b/flang/unittests/Runtime/CMakeLists.txt index f7caaca..ed047b08 100644 --- a/flang/unittests/Runtime/CMakeLists.txt +++ b/flang/unittests/Runtime/CMakeLists.txt @@ -25,6 +25,7 @@ add_flang_unittest(FlangRuntimeTests Reduction.cpp RuntimeCrashTest.cpp Stop.cpp + Support.cpp Time.cpp TemporaryStack.cpp Transformational.cpp diff --git a/flang/unittests/Runtime/Support.cpp b/flang/unittests/Runtime/Support.cpp new file mode 100644 index 0000000..fa2a233 --- /dev/null +++ b/flang/unittests/Runtime/Support.cpp @@ -0,0 +1,58 @@ +//===-- flang/unittests/Runtime/Support.cpp ----------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "flang/Runtime/support.h" +#include "gtest/gtest.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" + +using namespace Fortran::runtime; +using Fortran::common::TypeCategory; +TEST(CopyAndUpdateDescriptor, Basic) { + auto x{MakeArray<TypeCategory::Integer, 4>( + std::vector<int>{2, 3}, std::vector<std::int32_t>{0, 1, 2, 3, 4, 5})}; + x->GetDimension(0).SetLowerBound(11); + x->GetDimension(1).SetLowerBound(12); + + StaticDescriptor<2, false> statDesc; + Descriptor &result{statDesc.descriptor()}; + + RTNAME(CopyAndUpdateDescriptor) + (result, *x, nullptr, CFI_attribute_pointer, LowerBoundModifier::Preserve); + ASSERT_EQ(result.rank(), 2); + EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); + EXPECT_TRUE(result.IsPointer()); + EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); + EXPECT_EQ( + result.GetDimension(0).LowerBound(), x->GetDimension(0).LowerBound()); + EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); + EXPECT_EQ( + result.GetDimension(1).LowerBound(), x->GetDimension(1).LowerBound()); + + RTNAME(CopyAndUpdateDescriptor) + (result, *x, nullptr, CFI_attribute_allocatable, + LowerBoundModifier::SetToZeroes); + ASSERT_EQ(result.rank(), 2); + EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); + EXPECT_TRUE(result.IsAllocatable()); + EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); + EXPECT_EQ(result.GetDimension(0).LowerBound(), 0); + EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); + EXPECT_EQ(result.GetDimension(1).LowerBound(), 0); + + RTNAME(CopyAndUpdateDescriptor) + (result, *x, nullptr, CFI_attribute_other, LowerBoundModifier::SetToOnes); + ASSERT_EQ(result.rank(), 2); + EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); + EXPECT_FALSE(result.IsAllocatable()); + EXPECT_FALSE(result.IsPointer()); + EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); + EXPECT_EQ(result.GetDimension(0).LowerBound(), 1); + EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); + EXPECT_EQ(result.GetDimension(1).LowerBound(), 1); +} |