PR 80108 describes an ICE that occurs on an existing test program when compiled with a particular combination of target options.
This patch fixes the compiler to reject that particular combination of target options since it is not meaningful and duplicates the offending test case with a dg-options directive to exercise the problematic command-line options. This patch has been bootstrapped and tested with no regressions on both powerpc64-unknown-linux-gnu and powerpc64le-unknown-linux-gnu. Is this ok for the trunk? gcc/ChangeLog: 2017-03-31 Kelvin Nilsen <kel...@gcc.gnu.org> PR target/80108 * config/rs6000/rs6000.c (rs6000_option_override_internal): Enhance special handling given to the TARGET_P9_MINMAX option in relation to certain other options. gcc/testsuite/ChangeLog: 2017-03-31 Kelvin Nilsen <kel...@gcc.gnu.org> PR target/80108 * gcc.target/powerpc/ppc-fortran/ppc-fortran.exp: New file. * gcc.target/powerpc/ppc-fortran/pr80108-1.f90: New test. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 246573) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -4273,8 +4273,30 @@ rs6000_option_override_internal (bool global_init_ /* For the newer switches (vsx, dfp, etc.) set some of the older options, unless the user explicitly used the -mno-<option> to disable the code. */ if (TARGET_P9_VECTOR || TARGET_MODULO || TARGET_P9_DFORM_SCALAR - || TARGET_P9_DFORM_VECTOR || TARGET_P9_DFORM_BOTH > 0 || TARGET_P9_MINMAX) + || TARGET_P9_DFORM_VECTOR || TARGET_P9_DFORM_BOTH > 0) rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~rs6000_isa_flags_explicit); + else if (TARGET_P9_MINMAX) + { + if (have_cpu) + { + if (cpu_index == PROCESSOR_POWER9) + /* legacy behavior: allow -mcpu-power9 with certain capabilities + (eg -mno-vsx) explicitly disabled. */ + rs6000_isa_flags |= + (ISA_3_0_MASKS_SERVER & ~rs6000_isa_flags_explicit); + else + error ("Power9 target option is incompatible with -mcpu=<xxx> for " + "<xxx> less than power9"); + } + else if ((ISA_3_0_MASKS_SERVER & rs6000_isa_flags_explicit) + != (ISA_3_0_MASKS_SERVER & rs6000_isa_flags + & rs6000_isa_flags_explicit)) + /* Enforce that none of the ISA_3_0_MASKS_SERVER flags + were explicitly cleared. */ + error ("-mpower9-minmax incompatible with explicitly disabled options"); + else + rs6000_isa_flags |= ISA_3_0_MASKS_SERVER; + } else if (TARGET_P8_VECTOR || TARGET_DIRECT_MOVE || TARGET_CRYPTO) rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~rs6000_isa_flags_explicit); else if (TARGET_VSX) Index: gcc/testsuite/gcc.target/powerpc/ppc-fortran/ppc-fortran.exp =================================================================== --- gcc/testsuite/gcc.target/powerpc/ppc-fortran/ppc-fortran.exp (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ppc-fortran/ppc-fortran.exp (revision 246624) @@ -0,0 +1,65 @@ +# Copyright (C) 2004-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gfortran-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_FFLAGS +if ![info exists DEFAULT_FFLAGS] then { + set DEFAULT_FFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +global gfortran_test_path +global gfortran_aux_module_flags +set gfortran_test_path $srcdir/$subdir +set gfortran_aux_module_flags $DEFAULT_FFLAGS +proc dg-compile-aux-modules { args } { + global gfortran_test_path + global gfortran_aux_module_flags + if { [llength $args] != 2 } { + error "dg-set-target-env-var: needs one argument" + return + } + + set level [info level] + if { [info procs dg-save-unknown] != [list] } { + rename dg-save-unknown dg-save-unknown-level-$level + } + + dg-test $gfortran_test_path/[lindex $args 1] "" $gfortran_aux_module_flags + # cleanup-modules is intentionally not invoked here. + + if { [info procs dg-save-unknown-level-$level] != [list] } { + rename dg-save-unknown-level-$level dg-save-unknown + } +} + +# Main loop. +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS + +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $DEFAULT_FFLAGS + + +# All done. +dg-finish Index: gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr80108-1.f90 =================================================================== --- gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr80108-1.f90 (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr80108-1.f90 (working copy) @@ -0,0 +1,53 @@ +! Originally contributed by Tobias Burnas. +! { dg-do compile { target { powerpc*-*-* } } } +! { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } +! { dg-require-effective-target powerpc_p9vector_ok } +! { dg-options "-m32 -mcpu=405 -mpower9-minmax -mfloat128-type" } +! { dg-excess-errors "expect error due to conflicting target options" } +! Since the error message is not associated with a particular line +! number, we cannot use the dg-error directive and cannot specify a +! regexp to describe the expected error message. The expected error +! message is: +! "Power9 target option is incompatible with -mcpu=<xxx> for <xxx> +! less than power9" + +program stream_test + implicit none + character(len=*), parameter :: rec1 = 'record1' + character(len=*), parameter :: rec2 = 'record2' + character(len=50) :: str1,str2 + integer :: len, i + real :: r + + open(10,form='formatted',access='stream',& + status='scratch',position='rewind') + write(10,'(a)') rec1//new_line('a')//rec2 + rewind(10) + read(10,*) str1 + read(10,*) str2 + if(str1 /= rec1 .or. str2 /= rec2) call abort() + rewind(10) + read(10,'(a)') str1 + read(10,'(a)') str2 + if(str1 /= rec1 .or. str2 /= rec2) call abort() + close(10) + + open(10,form='formatted',access='stream',& + status='scratch',position='rewind') + write(10,*) '123 '//trim(rec1)//' 1e-12' + write(10,*) '12345.6789' + rewind(10) + read(10,*) i,str1 + read(10,*) r + if(i /= 123 .or. str1 /= rec1 .or. r /= 12345.6789) & + call abort() + close(10) + + open(unit=10,form='unformatted',access='stream', & + status='scratch',position='rewind') + write(10) rec1//new_line('a')//rec2 + len = len_trim(rec1//new_line('a')//rec2) + rewind(10) + read(10) str1(1:len) + if(str1 /= rec1//new_line('a')//rec2) call abort() +end program stream_test