From 5c3197fa0bdc505e254859e40d02524b1af3a79c Mon Sep 17 00:00:00 2001 From: peter klausler Date: Fri, 5 Apr 2019 12:54:19 -0700 Subject: [PATCH] [flang] Fix implied DO folding with negative strides, add test Original-commit: flang-compiler/f18@2e14b76041c79f5861fb2f912a93572130e08d17 Reviewed-on: https://github.com/flang-compiler/f18/pull/386 Tree-same-pre-rewrite: false --- flang/lib/evaluate/fold.cc | 15 +++++-- flang/test/semantics/CMakeLists.txt | 1 + flang/test/semantics/modfile25.f90 | 64 +++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 flang/test/semantics/modfile25.f90 diff --git a/flang/lib/evaluate/fold.cc b/flang/lib/evaluate/fold.cc index 6f980e80e96e..2d0d6d1e101e 100644 --- a/flang/lib/evaluate/fold.cc +++ b/flang/lib/evaluate/fold.cc @@ -884,10 +884,19 @@ private: std::optional start{ToInt64(lower)}, end{ToInt64(upper)}, step{ToInt64(stride)}; if (start.has_value() && end.has_value() && step.has_value()) { + if (*step == 0) { + return false; + } bool result{true}; - for (std::int64_t &j{context_.StartImpliedDo(iDo.name(), *start)}; - j <= *end; j += *step) { - result &= FoldArray(iDo.values()); + std::int64_t &j{context_.StartImpliedDo(iDo.name(), *start)}; + if (*step > 0) { + for (; j <= *end; j += *step) { + result &= FoldArray(iDo.values()); + } + } else { + for (; j >= *end; j += *step) { + result &= FoldArray(iDo.values()); + } } context_.EndImpliedDo(iDo.name()); return result; diff --git a/flang/test/semantics/CMakeLists.txt b/flang/test/semantics/CMakeLists.txt index c63b9b1d52b2..8b26066ca59c 100644 --- a/flang/test/semantics/CMakeLists.txt +++ b/flang/test/semantics/CMakeLists.txt @@ -135,6 +135,7 @@ set(MODFILE_TESTS modfile22.f90 modfile23.f90 modfile24.f90 + modfile25.f90 ) set(LABEL_TESTS diff --git a/flang/test/semantics/modfile25.f90 b/flang/test/semantics/modfile25.f90 new file mode 100644 index 000000000000..fa3c2df4719c --- /dev/null +++ b/flang/test/semantics/modfile25.f90 @@ -0,0 +1,64 @@ +! Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. + +! Test compile-time analysis of shapes. + +module m1 + integer(8), parameter :: a0s(:) = shape(3.14159) + real :: a1(5,5,5) + integer(8), parameter :: a1s(:) = shape(a1) + integer(8), parameter :: a1ss(:) = shape(a1s) + integer(8), parameter :: a1sss(:) = shape(a1ss) + integer(8), parameter :: a1rs(:) = [rank(a1),rank(a1s),rank(a1ss),rank(a1sss)] + integer(8), parameter :: a1n(:) = [size(a1),size(a1,1),size(a1,2)] + integer(8), parameter :: a1sn(:) = [size(a1s),size(a1ss),size(a1sss)] + integer(8), parameter :: ac1s(:) = shape([1]) + integer(8), parameter :: ac2s(:) = shape([1,2,3]) + integer(8), parameter :: ac3s(:) = shape([(1,j=1,4)]) + integer(8), parameter :: ac3bs(:) = shape([(1,j=4,1,-1)]) + integer(8), parameter :: ac4s(:) = shape([((j,k,j*k,k=1,3),j=1,4)]) + integer(8), parameter :: ac5s(:) = shape([((0,k=5,1,-2),j=9,2,-3)]) + contains + subroutine subr(x,n1,n2) + real, intent(in) :: x(:,:) + integer, intent(in) :: n1(3), n2(:) + real :: a(:,:,:) + a = reshape(x,n1) + a = reshape(x,n2(10:30:9)) ! fails if we can't figure out triplet shape + end subroutine +end module m1 +!Expect: m1.mod +! !mod$ v1 sum:7a360903510189bc +! module m1 +! integer(8),parameter::a0s(1_8:)=[Integer(8)::] +! real(4)::a1(1_8:5_8,1_8:5_8,1_8:5_8) +! integer(8),parameter::a1s(1_8:)=[Integer(8)::5_8,5_8,5_8] +! integer(8),parameter::a1ss(1_8:)=[Integer(8)::3_8] +! integer(8),parameter::a1sss(1_8:)=[Integer(8)::1_8] +! integer(8),parameter::a1rs(1_8:)=[Integer(4)::3_4,1_4,1_4,1_4] +! integer(8),parameter::a1n(1_8:)=[Integer(8)::125_8,5_8,5_8] +! integer(8),parameter::a1sn(1_8:)=[Integer(8)::3_8,1_8,1_8] +! integer(8),parameter::ac1s(1_8:)=[Integer(8)::1_8] +! integer(8),parameter::ac2s(1_8:)=[Integer(8)::3_8] +! integer(8),parameter::ac3s(1_8:)=[Integer(8)::4_8] +! integer(8),parameter::ac3bs(1_8:)=[Integer(8)::4_8] +! integer(8),parameter::ac4s(1_8:)=[Integer(8)::36_8] +! integer(8),parameter::ac5s(1_8:)=[Integer(8)::9_8] +! contains +! subroutine subr(x,n1,n2) +! real(4),intent(in)::x(1_8:,1_8:) +! integer(4),intent(in)::n1(1_8:3_8) +! integer(4),intent(in)::n2(1_8:) +! end +! end -- 2.34.1