diff --git a/flang/test/Evaluate/folding01.f90 b/flang/test/Evaluate/folding01.f90 index fddc034165e12..cb7a9eb5309fd 100644 --- a/flang/test/Evaluate/folding01.f90 +++ b/flang/test/Evaluate/folding01.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test intrinsic operation folding diff --git a/flang/test/Evaluate/folding02.f90 b/flang/test/Evaluate/folding02.f90 index 1033c4daa97bb..9b0ab2b03e8f0 100644 --- a/flang/test/Evaluate/folding02.f90 +++ b/flang/test/Evaluate/folding02.f90 @@ -1,5 +1,5 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 + ! Check intrinsic function folding with host runtime library module m diff --git a/flang/test/Evaluate/folding03.f90 b/flang/test/Evaluate/folding03.f90 index 47fab1a490f3c..47f8ec090df3b 100644 --- a/flang/test/Evaluate/folding03.f90 +++ b/flang/test/Evaluate/folding03.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test operation folding edge case (both expected value and messages) ! These tests make assumptions regarding real(4) and integer(4) extrema. diff --git a/flang/test/Evaluate/folding04.f90 b/flang/test/Evaluate/folding04.f90 index 54d1c385a192e..254a6531ae398 100644 --- a/flang/test/Evaluate/folding04.f90 +++ b/flang/test/Evaluate/folding04.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test intrinsic function folding edge case (both expected value and messages) ! These tests make assumptions regarding real(4) extrema. diff --git a/flang/test/Evaluate/folding05.f90 b/flang/test/Evaluate/folding05.f90 index b5e955a4ac708..22c029030632b 100644 Binary files a/flang/test/Evaluate/folding05.f90 and b/flang/test/Evaluate/folding05.f90 differ diff --git a/flang/test/Evaluate/folding06.f90 b/flang/test/Evaluate/folding06.f90 index fe553b89d3387..4393b3b02f5c5 100644 --- a/flang/test/Evaluate/folding06.f90 +++ b/flang/test/Evaluate/folding06.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test transformational intrinsic function folding module m diff --git a/flang/test/Evaluate/folding07.f90 b/flang/test/Evaluate/folding07.f90 index edee48355be68..6848a1e142f3f 100644 --- a/flang/test/Evaluate/folding07.f90 +++ b/flang/test/Evaluate/folding07.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test numeric model inquiry intrinsics module m diff --git a/flang/test/Evaluate/folding08.f90 b/flang/test/Evaluate/folding08.f90 index 6118e6b14cf08..c64a9590f3533 100644 --- a/flang/test/Evaluate/folding08.f90 +++ b/flang/test/Evaluate/folding08.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of LBOUND and UBOUND module m diff --git a/flang/test/Evaluate/folding09.f90 b/flang/test/Evaluate/folding09.f90 index 6f9be6b50bc35..d78611f4b2a9b 100644 --- a/flang/test/Evaluate/folding09.f90 +++ b/flang/test/Evaluate/folding09.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of IS_CONTIGUOUS on simply contiguous items (9.5.4) ! When IS_CONTIGUOUS() is constant, it's .TRUE. diff --git a/flang/test/Evaluate/folding10.f90 b/flang/test/Evaluate/folding10.f90 index c705741191094..651caa1be5a31 100644 --- a/flang/test/Evaluate/folding10.f90 +++ b/flang/test/Evaluate/folding10.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of SHAPE(TRANSFER(...)) module m diff --git a/flang/test/Evaluate/folding11.f90 b/flang/test/Evaluate/folding11.f90 index 4fdb0ba9aa718..bf957c8251989 100644 --- a/flang/test/Evaluate/folding11.f90 +++ b/flang/test/Evaluate/folding11.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 module m complex, parameter :: z1 = 1. + (2., 3.) logical, parameter :: test_z1 = z1 == (3., 3.) diff --git a/flang/test/Evaluate/folding12.f90 b/flang/test/Evaluate/folding12.f90 index ac74c6ce0e34e..016e692f66264 100644 --- a/flang/test/Evaluate/folding12.f90 +++ b/flang/test/Evaluate/folding12.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of structure constructors module m1 type parent_type diff --git a/flang/test/Evaluate/folding13.f90 b/flang/test/Evaluate/folding13.f90 index 92a300998c357..9527acd6a98b4 100644 --- a/flang/test/Evaluate/folding13.f90 +++ b/flang/test/Evaluate/folding13.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of array constructors with constant implied DO bounds; ! their indices are constant expressions and can be used as such. module m1 diff --git a/flang/test/Evaluate/folding14.f90 b/flang/test/Evaluate/folding14.f90 index a76fe23fed735..1b949351a5149 100644 --- a/flang/test/Evaluate/folding14.f90 +++ b/flang/test/Evaluate/folding14.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of isnan() extension module m1 logical, parameter :: results(*) = isnan([ & diff --git a/flang/test/Evaluate/folding15.f90 b/flang/test/Evaluate/folding15.f90 index 658f91f3011e0..e79cbda87045f 100644 --- a/flang/test/Evaluate/folding15.f90 +++ b/flang/test/Evaluate/folding15.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test folding of array constructors with duplicate names for the implied ! DO variables module m1 diff --git a/flang/test/Evaluate/folding16.f90 b/flang/test/Evaluate/folding16.f90 index a407be31e5154..04474bd5e9970 100644 --- a/flang/test/Evaluate/folding16.f90 +++ b/flang/test/Evaluate/folding16.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Ensure that lower bounds are accounted for in intrinsic folding; ! this is a regression test for a bug in which they were not module m diff --git a/flang/test/Evaluate/folding17.f90 b/flang/test/Evaluate/folding17.f90 index 51e42589c69ec..73ddeabcab3d2 100644 --- a/flang/test/Evaluate/folding17.f90 +++ b/flang/test/Evaluate/folding17.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test implementations of STORAGE_SIZE() and SIZEOF() as expression rewrites module m1 type :: t1 diff --git a/flang/test/Evaluate/folding18.f90 b/flang/test/Evaluate/folding18.f90 index eda70041ce2ba..9110689cf5d63 100644 --- a/flang/test/Evaluate/folding18.f90 +++ b/flang/test/Evaluate/folding18.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test implementations of IEEE inquiry functions module m use ieee_arithmetic diff --git a/flang/test/Evaluate/folding20.f90 b/flang/test/Evaluate/folding20.f90 index 7d14e978dd838..be012074fb4bd 100644 --- a/flang/test/Evaluate/folding20.f90 +++ b/flang/test/Evaluate/folding20.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests reduction intrinsic function folding module m implicit none diff --git a/flang/test/Evaluate/folding21.f90 b/flang/test/Evaluate/folding21.f90 index 2a7923debd7d2..8306e988dc67a 100644 --- a/flang/test/Evaluate/folding21.f90 +++ b/flang/test/Evaluate/folding21.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Check array sizes with varying extents, including extents where the upper ! bound is less than the lower bound module m diff --git a/flang/test/Evaluate/folding22.f90 b/flang/test/Evaluate/folding22.f90 index a5f923b9d9edd..3a9812ce75dd1 100644 --- a/flang/test/Evaluate/folding22.f90 +++ b/flang/test/Evaluate/folding22.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Test character concatenation folding diff --git a/flang/test/Evaluate/folding23.f90 b/flang/test/Evaluate/folding23.f90 index 405f927b0b063..f31478ed3c5e5 100644 --- a/flang/test/Evaluate/folding23.f90 +++ b/flang/test/Evaluate/folding23.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of EOSHIFT (valid cases) module m integer, parameter :: arr(2,3) = reshape([1, 2, 3, 4, 5, 6], shape(arr)) diff --git a/flang/test/Evaluate/folding24.f90 b/flang/test/Evaluate/folding24.f90 index b5c429f94a5e5..e101c09eb5761 100644 --- a/flang/test/Evaluate/folding24.f90 +++ b/flang/test/Evaluate/folding24.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of PACK (valid cases) module m integer, parameter :: arr(2,3) = reshape([1, 2, 3, 4, 5, 6], shape(arr)) diff --git a/flang/test/Evaluate/folding25.f90 b/flang/test/Evaluate/folding25.f90 index a94565ff8fcab..dd01880d47d78 100644 --- a/flang/test/Evaluate/folding25.f90 +++ b/flang/test/Evaluate/folding25.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of UNPACK (valid cases) module m integer, parameter :: vector(*) = [1, 2, 3, 4] diff --git a/flang/test/Evaluate/folding26.f90 b/flang/test/Evaluate/folding26.f90 index 09fd08a0d6cfe..0fb5f91361774 100644 --- a/flang/test/Evaluate/folding26.f90 +++ b/flang/test/Evaluate/folding26.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of TRANSPOSE module m integer, parameter :: matrix(0:1,0:2) = reshape([1,2,3,4,5,6],shape(matrix)) diff --git a/flang/test/Evaluate/folding27.f90 b/flang/test/Evaluate/folding27.f90 index 4497396b434ef..0d3d333c0f100 100644 --- a/flang/test/Evaluate/folding27.f90 +++ b/flang/test/Evaluate/folding27.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_folding.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_folding.py %s %flang_fc1 ! Tests folding of CSHIFT (valid cases) module m integer, parameter :: arr(2,3) = reshape([1, 2, 3, 4, 5, 6], shape(arr)) diff --git a/flang/test/Evaluate/test_folding.py b/flang/test/Evaluate/test_folding.py new file mode 100755 index 0000000000000..ac1c8e553864e --- /dev/null +++ b/flang/test/Evaluate/test_folding.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 + +"""This script verifies expression folding. +It compiles a source file with '-fdebug-dump-symbols' +and looks for parameter declarations 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 kinds of failure: + - test_x is folded to .false.. + This means 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. + +Parameters: + sys.argv[1]: a source file with contains the input and expected output + sys.argv[2]: the Flang frontend driver + sys.argv[3:]: Optional arguments to the Flang frontend driver""" + +import os +import sys +import tempfile +import re +import subprocess + +from difflib import unified_diff +from pathlib import Path + +def check_args(args): + """Verifies that the number is arguments passed is correct.""" + if len(args) < 3: + print(f"Usage: {args[0]} ") + sys.exit(1) + +def set_source(source): + """Sets the path to the source files.""" + if not Path(source).is_file(): + print(f"File not found: {src}") + sys.exit(1) + return Path(source) + +def set_executable(exe): + """Sets the path to the Flang frontend driver.""" + if not Path(exe).is_file(): + print(f"Flang was not found: {exe}") + sys.exit(1) + return str(Path(exe)) + +check_args(sys.argv) +cwd = os.getcwd() +srcdir = set_source(sys.argv[1]).resolve() +with open(srcdir, 'r', encoding="utf-8") as f: + src = f.readlines() +src1 = "" +src2 = "" +src3 = "" +src4 = "" +messages = "" +actual_warnings = "" +expected_warnings = "" +warning_diffs = "" + +flang_fc1 = set_executable(sys.argv[2]) +flang_fc1_args = sys.argv[3:] +flang_fc1_options = "" +LIBPGMATH = os.getenv('LIBPGMATH') +if LIBPGMATH: + flang_fc1_options = ["-fdebug-dump-symbols", "-DTEST_LIBPGMATH"] + print("Assuming libpgmath support") +else: + flang_fc1_options = ["-fdebug-dump-symbols"] + print("Not assuming libpgmath support") + +cmd = [flang_fc1, *flang_fc1_args, *flang_fc1_options, str(srcdir)] +with tempfile.TemporaryDirectory() as tmpdir: + proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + check=True, universal_newlines=True, cwd=tmpdir) + src1 = proc.stdout + messages = proc.stderr + +for line in src1.split("\n"): + m = re.search(r"(\w*)(?=, PARAMETER).*init:(.*)", line) + if m: + src2 += f"{m.group(1)} {m.group(2)}\n" + +for line in src2.split("\n"): + m = re.match(r"test_*", line) + if m: + src3 += f"{m.string}\n" + +for passed_results, line in enumerate(src3.split("\n")): + m = re.search(r"\.false\._.$", line) + if m: + src4 += f"{line}\n" + +for line in messages.split("\n"): + m = re.search(r"[^:]*:(\d*):\d*: (.*)", line) + if m: + actual_warnings += f"{m.group(1)}: {m.group(2)}\n" + +passed_warnings = 0 +warnings = [] +for i, line in enumerate(src, 1): + m = re.search(r"(?:!WARN:)(.*)", line) + if m: + warnings.append(m.group(1)) + continue + if warnings: + for x in warnings: + passed_warnings += 1 + expected_warnings += f"{i}:{x}\n" + warnings = [] + +for line in unified_diff(actual_warnings.split("\n"), + expected_warnings.split("\n"), n=0): + line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line) + line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line) + warning_diffs += line + +if src4 or warning_diffs: + print("Folding test failed:") + # Prints failed tests, including parameters with the same + # suffix so that more information can be obtained by declaring + # expected_x and result_x + if src4: + for line in src4.split("\n"): + m = re.match(r"test_(\w+)", line) + if m: + for line in src2.split("\n"): + if m.group(1) in line: + print(line) + if warning_diffs: + print(warning_diffs) + print() + print("FAIL") + sys.exit(1) +else: + print() + print(f"All {passed_results+passed_warnings} tests passed") + print("PASS") + diff --git a/flang/test/Evaluate/test_folding.sh b/flang/test/Evaluate/test_folding.sh deleted file mode 100755 index 74ca9c820ffe8..0000000000000 --- a/flang/test/Evaluate/test_folding.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash -# This script verifies expression folding. -# It compiles a source file with '-fdebug-dump-symbols' and looks for -# parameter declarations 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 kinds of failure: -# - test_x is folded to .false.. This means 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. - -if [[ $# < 3 ]]; then - echo "Usage: $0 " - exit 1 -fi - -src=$1 -[[ ! -f $src ]] && echo "File not found: $src" && exit 1 -shift - -temp=$1 -mkdir -p $temp -shift - -CMD="$* -fdebug-dump-symbols" - -# Check if tests should assume folding is using libpgmath -if [[ $LIBPGMATH ]]; then - CMD="$CMD -DTEST_LIBPGMATH" - echo "Assuming libpgmath support" -else - echo "Not assuming libpgmath support" -fi - -src1=$temp/symbols.log -src2=$temp/all_parameters.log -src3=$temp/tested_parameters.log -src4=$temp/failures.log -messages=$temp/messages.log -actual_warnings=$temp/actwarnings.log -expected_warnings=$temp/expwarnings.log -warning_diffs=$temp/warnings.diff - -if ! ( cd $temp; $CMD $src ) > $src1 2> $messages # compile, dumping symbols -then - cat $messages - echo FAIL compilation - exit 1 -fi - -# Get all PARAMETER declarations -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 - - -#Check warnings -sed -n 's=^[^:]*:\([0-9]*\):[0-9]*: =\1: =p' $messages > $actual_warnings - -awk ' - BEGIN { FS = "!WARN: "; } - /^ *!WARN: / { warnings[nwarnings++] = $2; next; } - { for (i = 0; i < nwarnings; ++i) printf "%d: %s\n", NR, warnings[i]; nwarnings = 0; } -' $src > $expected_warnings - -diff -U0 $actual_warnings $expected_warnings > $warning_diffs - -if [ -s $src4 ] || [ -s $warning_diffs ]; 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) - if [[ -s $src4 ]]; then - sed -e 's/test_/_/' -e 's/ .*//' $src4 | grep -f - $src2 - fi - if [[ -s $warning_diffs ]]; then - echo "$cmd" - < $warning_diffs \ - sed -n -e 's/^-\([0-9]\)/actual at \1/p' -e 's/^+\([0-9]\)/expect at \1/p' \ - | sort -n -k 2 - fi - echo FAIL - exit 1 -else - passed_results=$(wc -l < $src3) - passed_warnings=$(wc -l < $expected_warnings) - passed=$(($passed_warnings + $passed_results)) - echo all $passed tests passed - echo PASS -fi