aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Steinfeld <psteinfeld@nvidia.com>2021-02-02 14:15:50 -0800
committerPeter Steinfeld <psteinfeld@nvidia.com>2021-02-03 10:53:32 -0800
commit2018dafce50cbd1363fdd4e24c76e98852843a19 (patch)
tree01abc99b9bbc3c842182f264c1ec799911f3e50f
parent15f26c5f5191fd4cfdece0e9621efd395ba57bc8 (diff)
downloadllvm-2018dafce50cbd1363fdd4e24c76e98852843a19.zip
llvm-2018dafce50cbd1363fdd4e24c76e98852843a19.tar.gz
llvm-2018dafce50cbd1363fdd4e24c76e98852843a19.tar.bz2
[flang] Fix calls to LBOUND() intrinsic for arrays with lower bounds not 1
Constant folding for calls to LBOUND() was not working when the lower bound of a constant array was not 1. I fixed this and re-enabled the test in Evaluate/folding16.f90 that previously was silently failing. I slightly changed the test to parenthesize the first argument to exercise all of the new code. Differential Revision: https://reviews.llvm.org/D95894
-rw-r--r--flang/lib/Evaluate/fold-integer.cpp38
-rw-r--r--flang/test/Evaluate/folding16.f906
2 files changed, 40 insertions, 4 deletions
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 9f3482d..eea7b6e 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -7,9 +7,44 @@
//===----------------------------------------------------------------------===//
#include "fold-implementation.h"
+#include "flang/Evaluate/check-expression.h"
namespace Fortran::evaluate {
+// Class to retrieve the constant lower bound of an expression which is an
+// array that devolves to a type of Constant<T>
+class GetConstantArrayLboundHelper {
+public:
+ GetConstantArrayLboundHelper(ConstantSubscript dim) : dim_{dim} {}
+
+ template <typename T> ConstantSubscript GetLbound(const T &) {
+ // The method is needed for template expansion, but we should never get
+ // here in practice.
+ CHECK(false);
+ return 0;
+ }
+
+ template <typename T> ConstantSubscript GetLbound(const Constant<T> &x) {
+ // Return the lower bound
+ return x.lbounds()[dim_];
+ }
+
+ template <typename T> ConstantSubscript GetLbound(const Parentheses<T> &x) {
+ // Strip off the parentheses
+ return GetLbound(x.left());
+ }
+
+ template <typename T> ConstantSubscript GetLbound(const Expr<T> &x) {
+ // recurse through Expr<T>'a until we hit a constant
+ return std::visit([&](const auto &inner) { return GetLbound(inner); },
+ // [&](const auto &) { return 0; },
+ x.u);
+ }
+
+private:
+ ConstantSubscript dim_;
+};
+
template <int KIND>
Expr<Type<TypeCategory::Integer, KIND>> LBOUND(FoldingContext &context,
FunctionRef<Type<TypeCategory::Integer, KIND>> &&funcRef) {
@@ -51,6 +86,9 @@ Expr<Type<TypeCategory::Integer, KIND>> LBOUND(FoldingContext &context,
lowerBoundsAreOne = symbol.Rank() == 0; // LBOUND(array%component)
}
}
+ if (IsActuallyConstant(*array)) {
+ return Expr<T>{GetConstantArrayLboundHelper{*dim}.GetLbound(*array)};
+ }
if (lowerBoundsAreOne) {
if (dim) {
return Expr<T>{1};
diff --git a/flang/test/Evaluate/folding16.f90 b/flang/test/Evaluate/folding16.f90
index a21f5a7..ac4550a 100644
--- a/flang/test/Evaluate/folding16.f90
+++ b/flang/test/Evaluate/folding16.f90
@@ -7,10 +7,8 @@ module m
integer, parameter :: c(-1:1) = [33, 22, 11]
integer, parameter :: d(1:3) = [33, 22, 11]
integer, parameter :: e(-2:0) = ([33, 22, 11])
- ! The following test is commented out because constant folding for "lbound"
- ! is currently broken
- !logical, parameter :: test_1 = lbound(a,1)==-1 .and. lbound(b,1)==-1 .and. &
- ! lbound(log(a),1)==1 .and. all(b==0)
+ logical, parameter :: test_1 = lbound((a),1)==-1 .and. lbound(b,1)==-1 .and. &
+ lbound(log(a),1)==1 .and. all(b==0)
logical, parameter :: test_2 = all(c .eq. d)
logical, parameter :: test_3 = all(c .eq. e)
logical, parameter :: test_4 = all(d .eq. e)