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