From 4073e47343d69d2cdf3eb52e50b0db99c73c9a12 Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Thu, 21 Mar 2019 08:31:21 -0700 Subject: [PATCH] [flang] Add test framework for folding Original-commit: flang-compiler/f18@d6b658c318ff6e5f61bb1c7490e96394fe7f03a8 Tree-same-pre-rewrite: false --- flang/test/evaluate/CMakeLists.txt | 9 ++++ flang/test/evaluate/folding01.f90 | 99 +++++++++++++++++++++++++++++++++++++ flang/test/evaluate/test_folding.sh | 85 +++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 flang/test/evaluate/folding01.f90 create mode 100755 flang/test/evaluate/test_folding.sh diff --git a/flang/test/evaluate/CMakeLists.txt b/flang/test/evaluate/CMakeLists.txt index 3fd9f0d..7c1abdb 100644 --- a/flang/test/evaluate/CMakeLists.txt +++ b/flang/test/evaluate/CMakeLists.txt @@ -116,6 +116,11 @@ target_link_libraries(folding-test FortranEvaluate ) +set(FOLDING_TESTS + folding01.f90 +) + + add_test(Expression expression-test) add_test(Leadz leading-zero-bit-count-test) add_test(PopPar bit-population-count-test) @@ -126,3 +131,7 @@ add_test(Real real-test) add_test(RESHAPE reshape-test) add_test(ISO-binding ISO-Fortran-binding-test) add_test(folding folding-test) + +foreach(test ${FOLDING_TESTS}) + add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test_folding.sh ${test}) +endforeach() diff --git a/flang/test/evaluate/folding01.f90 b/flang/test/evaluate/folding01.f90 new file mode 100644 index 0000000..2c32be6 --- /dev/null +++ b/flang/test/evaluate/folding01.f90 @@ -0,0 +1,99 @@ +! 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 intrinsic operation folding + +module m +! Check logical intrinsic operation folding + logical, parameter :: test_not1 = .NOT..false. + logical, parameter :: test_not2 = .NOT..NOT..true. + + logical, parameter :: test_parantheses1 = .NOT.(.false.) + logical, parameter :: test_parantheses2 = .NOT..NOT.(.true.) + + logical, parameter :: test_and1 = .true..AND..true. + logical, parameter :: test_and2 = .NOT.(.false..AND..true.) + logical, parameter :: test_and3 = .NOT.(.false..AND..false.) + logical, parameter :: test_and4 = .NOT.(.true..AND..false.) + + logical, parameter :: test_or1 = .true..OR..true. + logical, parameter :: test_or2 = .false..OR..true. + logical, parameter :: test_or3 = .NOT.(.false..OR..false.) + logical, parameter :: test_or4 = .true..OR..false. + + logical, parameter :: test_eqv1 = .false..EQV..false. + logical, parameter :: test_eqv2 = .true..EQV..true. + logical, parameter :: test_eqv3 = .NOT.(.false..EQV..true.) + logical, parameter :: test_eqv4 = .NOT.(.true..EQV..false.) + + logical, parameter :: test_neqv1 = .true..NEQV..false. + logical, parameter :: test_neqv2 = .false..NEQV..true. + logical, parameter :: test_neqv3 = .NOT.(.false..NEQV..false.) + logical, parameter :: test_neqv4 = .NOT.(.true..NEQV..true.) + +! Check integer intrinsic operator folding + +! Check integer relational intrinsic operation folding + logical, parameter :: test_le_i1 = 1.LE.2 + logical, parameter :: test_le_i2 = .NOT.(2.LE.1) + logical, parameter :: test_le_i3 = 2.LE.2 + logical, parameter :: test_le_i4 = -1.LE.2 + logical, parameter :: test_le_i5 = .NOT.(-2.LE.-3) + + logical, parameter :: test_lt_i1 = 1.LT.2 + logical, parameter :: test_lt_i2 = .NOT.(2.LT.1) + logical, parameter :: test_lt_i3 = .NOT.(2.LT.2) + logical, parameter :: test_lt_i4 = -1.LT.2 + logical, parameter :: test_lt_i5 = .NOT.(-2.LT.-3) + + logical, parameter :: test_ge_i1 = .NOT.(1.GE.2) + logical, parameter :: test_ge_i2 = 2.GE.1 + logical, parameter :: test_ge_i3 = 2.GE.2 + logical, parameter :: test_ge_i4 = .NOT.(-1.GE.2) + logical, parameter :: test_ge_i5 = -2.GE.-3 + + logical, parameter :: test_gt_i1 = .NOT.(1.GT.2) + logical, parameter :: test_gt_i2 = 2.GT.1 + logical, parameter :: test_gt_i3 = .NOT.(2.GT.2) + logical, parameter :: test_gt_i4 = .NOT.(-1.GT.2) + logical, parameter :: test_gt_i5 = -2.GT.-3 + + logical, parameter :: test_eq_i1 = 2.EQ.2 + logical, parameter :: test_eq_i2 = .NOT.(-2.EQ.2) + + logical, parameter :: test_ne_i1 =.NOT.(2.NE.2) + logical, parameter :: test_ne_i2 = -2.NE.2 + +! Check integer intrinsic operation folding + logical, parameter :: test_unaryminus_i = (-(-1)).EQ.1 + logical, parameter :: test_unaryplus_i = (+1).EQ.1 + + logical, parameter :: test_plus_i1 = (1+1).EQ.2 + logical, parameter :: test_plus_i2 = ((-3)+1).EQ.-2 + + logical, parameter :: test_minus_i1 = (1-1).EQ.0 + logical, parameter :: test_minus_i2 = (1-(-1)).EQ.2 + + logical, parameter :: test_multiply_i1 = (2*2).EQ.4 + logical, parameter :: test_multiply_i2 = (0*1).EQ.0 + logical, parameter :: test_multiply_i3= ((-3)*2).EQ.(-6) + + logical, parameter :: test_divide_i1 = (5/3).EQ.(1) + logical, parameter :: test_divide_i2 = (6/3).EQ.(2) + logical, parameter :: test_divide_i3 = ((-7)/2).EQ.(-3) + logical, parameter :: test_divide_i4 = (0/127).EQ.(0) + + +end module diff --git a/flang/test/evaluate/test_folding.sh b/flang/test/evaluate/test_folding.sh new file mode 100755 index 0000000..587de29 --- /dev/null +++ b/flang/test/evaluate/test_folding.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# 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. + +# This script verifies expression folding. +# This compiles a source file with '-fdebug-dump-symbols' and looks for +# the parameter declaration to check they have been folded as expected. +# To check folding of an expression EXPR, the fortran program passed to this script +# must contain the following: +# logical, parameter :: test_x = +# This script will test that all parameter with a name starting with "test_" have +# been folded to .true. +# For instance, acos folding can be tested with: +# +# real(4), parameter :: res_acos = acos(0.5_4) +# real(4), parameter :: exp_acos = 1.047 +# logical, parameter :: test_acos = abs(res_acos - exp_acos).LE.(0.001_4) +# +# There are two kind of failures: +# - test_x is folded to .false.. This means that the expression was folded +# but the value is not as expected. +# - test_x is not folded (it is neither .true. nor .false.). This means the +# compiler could not fold the expression. + + + +PATH=/usr/bin:/bin +srcdir=$(dirname $0) +CMD="${F18:-../../build-clang-llvm8+gcc-8.3.0/tools/f18/f18} -fdebug-dump-symbols -fparse-only" + +if [[ $# != 1 ]]; then + echo "Usage: $0 " + exit 1 +fi +src=$srcdir/$1 +[[ ! -f $src ]] && echo "File not found: $src" && exit 1 + +temp=temp-$1 +rm -rf $temp +mkdir $temp +[[ $KEEP ]] || trap "rm -rf $temp" EXIT + +src1=$temp/1.f90 +src2=$temp/2.f90 +src3=$temp/3.f90 +src4=$temp/4.f90 +diffs=$temp/diffs + + +$CMD $src > $src1 # compile, dumping symbols + +#get all PARAMETER declaration +sed -e '/, PARAMETER/!d' -e 's/, PARAMETER.*init:/ /' \ + -e 's/^ *//' $src1 > $src2 + +#Collect test results +sed -e '/^test_/!d' $src2 > $src3 + +#Check all tests results (keep tests that do not resolve to true) +sed -e '/\.true\._.$/d' $src3 > $src4 + +if [[ -s $src4 ]]; then + echo "folding test failed:" + # print failed tests (It will actually print all parameters + # that have the same suffix as the failed test so that one can get more info + # by declaring expected_x and result_x for instance) + sed -e 's/test_/_/' -e 's/ .*//' $src4 | grep -f - $src2 + echo FAIL + exit 1 +else + passed="$(wc -l $src3 | sed 's/ .*//')" + echo all $passed tests passed + echo PASS +fi -- 2.7.4