1# Copyright (C) 2003-2020 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with GCC; see the file COPYING3. If not see 15# <http://www.gnu.org/licenses/>. 16 17# Please email any bugs, comments, and/or additions to this file to 18# the author. 19 20# This file was written by Steven Bosscher (s.bosscher@student.tudelft.nl) 21# based on f-torture.exp, which was written by Rob Savoye. 22 23load_lib target-supports.exp 24load_lib fortran-modules.exp 25load_lib target-utils.exp 26 27# Return the list of options to use for fortran torture tests. 28# The default option list can be overridden by 29# TORTURE_OPTIONS="{ { list1 } ... { listN } }" 30proc get-fortran-torture-options { } { 31 global TORTURE_OPTIONS 32 33 if [info exists TORTURE_OPTIONS] { 34 return $TORTURE_OPTIONS 35 } 36 37 # determine if host supports vectorization, and the necessary set 38 # of options, based on code from testsuite/vect/vect.exp 39 40 set vectorizer_options [list "-O2" "-ftree-vectorize"] 41 42 if { [istarget powerpc*-*-*] 43 && [is-effective-target powerpc_altivec_ok] 44 && [check_vmx_hw_available] } { 45 lappend vectorizer_options "-maltivec" 46 set test_tree_vectorize 1 47 } elseif { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) 48 && [check_effective_target_sse2] 49 && [check_sse2_hw_available] 50 && [check_sse_os_support_available] } { 51 lappend vectorizer_options "-msse2" 52 set test_tree_vectorize 1 53 } elseif { [istarget mips*-*-*] 54 && [check_effective_target_mpaired_single] 55 && [check_effective_target_nomips16] } { 56 lappend vectorizer_options "-mpaired-single" 57 set test_tree_vectorize 1 58 } elseif { [istarget sparc*-*-*] 59 && [check_effective_target_ultrasparc_hw] } { 60 lappend vectorizer_options "-mcpu=ultrasparc" "-mvis" 61 set test_tree_vectorize 1 62 } elseif { [istarget alpha*-*-*] 63 && [check_alpha_max_hw_available] } { 64 lappend vectorizer_options "-mmax" 65 set test_tree_vectorize 1 66 } elseif [istarget ia64-*-*] { 67 set test_tree_vectorize 1 68 } else { 69 set test_tree_vectorize 0 70 } 71 72 set options {} 73 74 lappend options \ 75 { -O0 } \ 76 { -O1 } \ 77 { -O2 } \ 78 { -O2 -fomit-frame-pointer -finline-functions } \ 79 { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \ 80 { -O2 -fbounds-check } \ 81 { -O3 -g } \ 82 { -Os } 83 if { $test_tree_vectorize } { 84 lappend options $vectorizer_options 85 } 86 87 if [info exists ADDITIONAL_TORTURE_OPTIONS] { 88 set options [concat $options $ADDITIONAL_TORTURE_OPTIONS] 89 } 90 91 return $options 92} 93 94 95# 96# fortran-torture-compile -- compile a gfortran.fortran-torture testcase. 97# 98# SRC is the full pathname of the testcase. 99# OPTION is the specific compiler flag we're testing (eg: -O2). 100# 101proc fortran-torture-compile { src option } { 102 global output 103 global srcdir tmpdir 104 global host_triplet 105 106 set output "$tmpdir/[file tail [file rootname $src]].o" 107 108 regsub "(?q)$srcdir/" $src "" testcase 109 110 # If we couldn't rip $srcdir out of `src' then just do the best we can. 111 # The point is to reduce the unnecessary noise in the logs. Don't strip 112 # out too much because different testcases with the same name can confuse 113 # `test-tool'. 114 if [string match "/*" $testcase] { 115 set testcase "[file tail [file dirname $src]]/[file tail $src]" 116 } 117 118 verbose "Testing $testcase, $option" 1 119 120 # Run the compiler and get results in comp_output. 121 set options "" 122 lappend options "additional_flags=-w $option" 123 124 set comp_output [gfortran_target_compile "$src" "$output" object $options] 125 126 # See if we got something bad. 127 set fatal_signal "*95*: Internal compiler error: program*got fatal signal" 128 129 if [string match "$fatal_signal 6" $comp_output] then { 130 gfortran_fail $testcase "Got Signal 6, $option" 131 catch { remote_file build delete $output } 132 return 133 } 134 135 if [string match "$fatal_signal 11" $comp_output] then { 136 gfortran_fail $testcase "Got Signal 11, $option" 137 catch { remote_file build delete $output } 138 return 139 } 140 141 if [string match "*internal compiler error*" $comp_output] then { 142 gfortran_fail $testcase "$option (internal compiler error)" 143 catch { remote_file build delete $output } 144 return 145 } 146 147 # We shouldn't get these because of -w, but just in case. 148 if [string match "*95*:*warning:*" $comp_output] then { 149 warning "$testcase: (with warnings) $option" 150 send_log "$comp_output\n" 151 unresolved "$testcase, $option" 152 catch { remote_file build delete $output } 153 return 154 } 155 156 # Prune warnings we know are unwanted. 157 set comp_output [prune_warnings $comp_output] 158 159 # Report if the testcase is not supported. 160 set unsupported_message [gfortran_check_unsupported_p $comp_output] 161 if { $unsupported_message != "" } { 162 unsupported "$testcase: $unsupported_message" 163 catch { remote_file build delete $output } 164 return 165 } 166 167 # remove any leftover LF/CR to make sure any output is legit 168 regsub -all -- "\[\r\n\]*" $comp_output "" comp_output 169 170 # If any message remains, we fail. 171 if ![string match "" $comp_output] then { 172 gfortran_fail $testcase $option 173 catch { remote_file build delete $output } 174 return 175 } 176 177 gfortran_pass $testcase $option 178 catch { remote_file build delete $output } 179} 180 181 182# 183# fortran-torture-execute -- compile and execute a testcase. 184# 185# SRC is the full pathname of the testcase. 186# 187# If the testcase has an associated .x file, we source that to run the 188# test instead. We use .x so that we don't lengthen the existing filename 189# to more than 14 chars. 190# 191proc fortran-torture-execute { src } { 192 global output 193 global srcdir tmpdir 194 global tool 195 global compiler_conditional_xfail_data 196 global torture_with_loops 197 198 # Check for alternate driver. 199 set additional_flags "" 200 if [file exists [file rootname $src].x] { 201 verbose "Using alternate driver [file rootname [file tail $src]].x" 2 202 set done_p 0 203 catch "set done_p \[source [file rootname $src].x\]" 204 if { $done_p } { 205 return 206 } 207 } 208 209 # Setup the options for the testcase run. 210 set option_list $torture_with_loops 211 set executable $tmpdir/[file tail [file rootname $src].x] 212 regsub "(?q)$srcdir/" $src "" testcase 213 214 # If we couldn't rip $srcdir out of `src' then just do the best we can. 215 # The point is to reduce the unnecessary noise in the logs. Don't strip 216 # out too much because different testcases with the same name can confuse 217 # `test-tool'. 218 if [string match "/*" $testcase] { 219 set testcase "[file tail [file dirname $src]]/[file tail $src]" 220 } 221 list-module-names $src 222 223 # Walk the list of options and copmile and run the testcase for all 224 # options that are not explicitly disabled by the .x script (if present). 225 foreach option $option_list { 226 227 # Torture_{compile,execute}_xfail are set by the .x script. 228 if [info exists torture_compile_xfail] { 229 setup_xfail $torture_compile_xfail 230 } 231 232 # Torture_execute_before_{compile,execute} can be set by the .x script. 233 if [info exists torture_eval_before_compile] { 234 set ignore_me [eval $torture_eval_before_compile] 235 } 236 237 # FIXME: We should make sure that the modules required by this testcase 238 # exist. If not, the testcase should XFAIL. 239 240 # Compile the testcase. 241 catch { remote_file build delete $executable } 242 verbose "Testing $testcase, $option" 1 243 244 set options "" 245 lappend options "additional_flags=-w $option" 246 if { $additional_flags != "" } { 247 lappend options "additional_flags=$additional_flags" 248 } 249 set comp_output [gfortran_target_compile "$src" "$executable" executable $options] 250 251 # See if we got something bad. 252 set fatal_signal "*95*: Internal compiler error: program*got fatal signal" 253 254 if [string match "$fatal_signal 6" $comp_output] then { 255 gfortran_fail $testcase "Got Signal 6, $option" 256 catch { remote_file build delete $executable } 257 continue 258 } 259 260 if [string match "$fatal_signal 11" $comp_output] then { 261 gfortran_fail $testcase "Got Signal 11, $option" 262 catch { remote_file build delete $executable } 263 continue 264 } 265 266 if [string match "*internal compiler error*" $comp_output] then { 267 gfortran_fail $testcase "$option (internal compiler error)" 268 catch { remote_file build delete $executable } 269 continue 270 } 271 272 # We shouldn't get these because of -w, but just in case. 273 if [string match "*95*:*warning:*" $comp_output] then { 274 warning "$testcase: (with warnings) $option" 275 send_log "$comp_output\n" 276 unresolved "$testcase, $option" 277 catch { remote_file build delete $executable } 278 continue 279 } 280 281 # Prune warnings we know are unwanted. 282 set comp_output [prune_warnings $comp_output] 283 284 # Report if the testcase is not supported. 285 set unsupported_message [gfortran_check_unsupported_p $comp_output] 286 if { $unsupported_message != "" } { 287 unsupported "$testcase: $unsupported_message" 288 continue 289 } elseif ![file exists $executable] { 290 if ![is3way] { 291 fail "$testcase compilation, $option" 292 untested "$testcase execution, $option" 293 continue 294 } else { 295 # FIXME: since we can't test for the existence of a remote 296 # file without short of doing an remote file list, we assume 297 # that since we got no output, it must have compiled. 298 pass "$testcase compilation, $option" 299 } 300 } else { 301 pass "$testcase compilation, $option" 302 } 303 304 # See if this source file uses INTEGER(KIND=8) types, if it does, and 305 # no_long_long is set, skip execution of the test. 306 # FIXME: We should also look for F95 style "_8" or select_int_kind() 307 # integers, but that is obviously much harder than just regexping this. 308 # So maybe we should just avoid those in testcases. 309 if [target_info exists no_long_long] then { 310 if [expr [search_for_re $src "integer\*8"] \ 311 +[search_for_re $src "integer *( *8 *)"] \ 312 +[search_for_re $src "integer *( *kind *= *8 *)"]] \ 313 then { 314 untested "$testcase execution, $option" 315 continue 316 } 317 } 318 319 if [info exists torture_execute_xfail] { 320 setup_xfail $torture_execute_xfail 321 } 322 323 if [info exists torture_eval_before_execute] { 324 set ignore_me [eval $torture_eval_before_execute] 325 } 326 327 # Run the testcase, and analyse the output. 328 set result [gfortran_load "$executable" "" ""] 329 set status [lindex $result 0] 330 set output [lindex $result 1] 331 if { $status == "pass" } { 332 catch { remote_file build delete $executable } 333 } 334 $status "$testcase execution, $option" 335 } 336 cleanup-modules "" 337} 338 339 340# 341# search_for_re -- looks for a string match in a file 342# 343proc search_for_re { file pattern } { 344 set fd [open $file r] 345 while { [gets $fd cur_line]>=0 } { 346 set lower [string tolower $cur_line] 347 if [regexp "$pattern" $lower] then { 348 close $fd 349 return 1 350 } 351 } 352 close $fd 353 return 0 354} 355 356 357# 358# fortran-torture -- the fortran-torture testcase source file processor 359# 360# This runs compilation only tests (no execute tests). 361# 362# SRC is the full pathname of the testcase, or just a file name in which 363# case we prepend $srcdir/$subdir. 364# 365# If the testcase has an associated .x file, we source that to run the 366# test instead. We use .x so that we don't lengthen the existing filename 367# to more than 14 chars. 368# 369proc fortran-torture { args } { 370 global srcdir subdir 371 global compiler_conditional_xfail_data 372 global torture_with_loops 373 374 set src [lindex $args 0] 375 if { [llength $args] > 1 } { 376 set options [lindex $args 1] 377 } else { 378 set options "" 379 } 380 381 # Prepend $srdir/$subdir if missing. 382 if ![string match "*/*" $src] { 383 set src "$srcdir/$subdir/$src" 384 } 385 386 # Check for alternate driver. 387 if [file exists [file rootname $src].x] { 388 verbose "Using alternate driver [file rootname [file tail $src]].x" 2 389 set done_p 0 390 catch "set done_p \[source [file rootname $src].x\]" 391 if { $done_p } { 392 return 393 } 394 } 395 list-module-names $src 396 397 # loop through all the options 398 set option_list $torture_with_loops 399 foreach option $option_list { 400 401 # torture_compile_xfail is set by the .x script (if present) 402 if [info exists torture_compile_xfail] { 403 setup_xfail $torture_compile_xfail 404 } 405 406 # torture_execute_before_compile is set by the .x script (if present) 407 if [info exists torture_eval_before_compile] { 408 set ignore_me [eval $torture_eval_before_compile] 409 } 410 411 fortran-torture-compile $src "$option $options" 412 cleanup-modules "" 413 } 414} 415 416# 417# add-ieee-options -- add options necessary for 100% ieee conformance. 418# 419proc add-ieee-options { } { 420 # Ensure that excess precision does not cause problems. 421 if { [istarget i?86-*-*] 422 || [istarget m68k-*-*] } then { 423 uplevel 1 lappend additional_flags "-ffloat-store" 424 } 425 426 # Enable full IEEE compliance mode. 427 if { [istarget alpha*-*-*] 428 || [istarget sh*-*-*] } then { 429 uplevel 1 lappend additional_flags "-mieee" 430 } 431} 432