[flang-commits] [flang] 7898e7c - [flang] Implement the runtime portion of the CSHIFT intrinsic

Peter Steinfeld via flang-commits flang-commits at lists.llvm.org
Wed Jul 21 13:39:42 PDT 2021


Author: Peter Steinfeld
Date: 2021-07-21T13:39:21-07:00
New Revision: 7898e7c82d98fabc8c87a5b7b4a4f7786df69314

URL: https://github.com/llvm/llvm-project/commit/7898e7c82d98fabc8c87a5b7b4a4f7786df69314
DIFF: https://github.com/llvm/llvm-project/commit/7898e7c82d98fabc8c87a5b7b4a4f7786df69314.diff

LOG: [flang] Implement the runtime portion of the CSHIFT intrinsic

This change fixes a bug in  the runtime portion of the CSHIFT intrinsic
that happens when the value of the SHIFT argument is negative.

Differential Revision: https://reviews.llvm.org/D106292

Added: 
    

Modified: 
    flang/runtime/transformational.cpp
    flang/unittests/RuntimeGTest/Transformational.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/transformational.cpp b/flang/runtime/transformational.cpp
index a6e44001034c..3fc294bc948b 100644
--- a/flang/runtime/transformational.cpp
+++ b/flang/runtime/transformational.cpp
@@ -130,7 +130,7 @@ static inline std::size_t AllocateResult(Descriptor &result,
 
 extern "C" {
 
-// CSHIFT of rank > 1
+// CSHIFT where rank of ARRAY argument > 1
 void RTNAME(Cshift)(Descriptor &result, const Descriptor &source,
     const Descriptor &shift, int dim, const char *sourceFile, int line) {
   Terminator terminator{sourceFile, line};
@@ -172,7 +172,7 @@ void RTNAME(Cshift)(Descriptor &result, const Descriptor &source,
   }
 }
 
-// CSHIFT of vector
+// CSHIFT where rank of ARRAY argument == 1
 void RTNAME(CshiftVector)(Descriptor &result, const Descriptor &source,
     std::int64_t shift, const char *sourceFile, int line) {
   Terminator terminator{sourceFile, line};
@@ -184,6 +184,9 @@ void RTNAME(CshiftVector)(Descriptor &result, const Descriptor &source,
   for (SubscriptValue j{0}; j < extent; ++j) {
     SubscriptValue resultAt{1 + j};
     SubscriptValue sourceAt{lb + (j + shift) % extent};
+    if (sourceAt < 0) {
+      sourceAt += extent;
+    }
     CopyElement(result, &resultAt, source, &sourceAt, terminator);
   }
 }

diff  --git a/flang/unittests/RuntimeGTest/Transformational.cpp b/flang/unittests/RuntimeGTest/Transformational.cpp
index 969eea3ceaec..1394e53aefc6 100644
--- a/flang/unittests/RuntimeGTest/Transformational.cpp
+++ b/flang/unittests/RuntimeGTest/Transformational.cpp
@@ -60,6 +60,39 @@ TEST(Transformational, Shifts) {
   }
   result.Destroy();
 
+  // VECTOR  1 3 5 2 4 6
+  auto vector{MakeArray<TypeCategory::Integer, 4>(
+      std::vector<int>{6}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
+  vector->GetDimension(0).SetLowerBound(0);
+  StaticDescriptor<1, true> vectorDesc;
+  Descriptor &vectorResult{vectorDesc.descriptor()};
+
+  RTNAME(CshiftVector)(vectorResult, *vector, 2, __FILE__, __LINE__);
+  EXPECT_EQ(vectorResult.type(), array->type());
+  EXPECT_EQ(vectorResult.rank(), 1);
+  EXPECT_EQ(vectorResult.GetDimension(0).LowerBound(), 1);
+  EXPECT_EQ(vectorResult.GetDimension(0).Extent(), 6);
+  EXPECT_EQ(vectorResult.type(), (TypeCode{TypeCategory::Integer, 4}));
+  static std::int32_t cshiftExpect3[6]{3, 4, 5, 6, 1, 2};
+  for (int j{0}; j < 6; ++j) {
+    EXPECT_EQ(*vectorResult.ZeroBasedIndexedElement<std::int32_t>(j),
+        cshiftExpect3[j]);
+  }
+  vectorResult.Destroy();
+
+  RTNAME(CshiftVector)(vectorResult, *vector, -2, __FILE__, __LINE__);
+  EXPECT_EQ(vectorResult.type(), array->type());
+  EXPECT_EQ(vectorResult.rank(), 1);
+  EXPECT_EQ(vectorResult.GetDimension(0).LowerBound(), 1);
+  EXPECT_EQ(vectorResult.GetDimension(0).Extent(), 6);
+  EXPECT_EQ(vectorResult.type(), (TypeCode{TypeCategory::Integer, 4}));
+  static std::int32_t cshiftExpect4[6]{5, 6, 1, 2, 3, 4};
+  for (int j{0}; j < 6; ++j) {
+    EXPECT_EQ(*vectorResult.ZeroBasedIndexedElement<std::int32_t>(j),
+        cshiftExpect4[j]);
+  }
+  vectorResult.Destroy();
+
   auto boundary{MakeArray<TypeCategory::Integer, 4>(
       std::vector<int>{3}, std::vector<std::int32_t>{-1, -2, -3})};
   boundary->GetDimension(0).SetLowerBound(9); // shouldn't matter


        


More information about the flang-commits mailing list