From 53ad1bd520759580b9a5cc590a81a1a30b9e2e28 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Thu, 14 Sep 2023 15:52:13 +0800 Subject: [PATCH] RISC-V: Fix ICE in get_avl_or_vl_reg update v1 -> v2: Add available fortran compiler check in rvv-fortran.exp. This patch fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111395 ICE update v2 -> v3: Remove redundant format. PR target/111395 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (avl_info::operator==): Fix ICE. (vector_insn_info::global_merge): Ditto. (vector_insn_info::get_avl_or_vl_reg): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/fortran/pr111395.f90: New test. * gcc.target/riscv/rvv/rvv-fortran.exp: New test. --- gcc/config/riscv/riscv-vsetvl.cc | 28 +++++++----- .../gcc.target/riscv/rvv/fortran/pr111395.f90 | 41 +++++++++++++++++ .../gcc.target/riscv/rvv/rvv-fortran.exp | 45 +++++++++++++++++++ 3 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index e9e75fe32863..dc02246756d6 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1652,6 +1652,8 @@ avl_info::operator== (const avl_info &other) const /* Handle VLMAX AVL. */ if (vlmax_avl_p (m_value)) return vlmax_avl_p (other.get_value ()); + if (vlmax_avl_p (other.get_value ())) + return false; /* If any source is undef value, we think they are not equal. */ if (!m_source || !other.get_source ()) @@ -2258,6 +2260,18 @@ vector_insn_info::global_merge (const vector_insn_info &merge_info, new_info.set_avl_source (first_set); } + /* Make sure VLMAX AVL always has a set_info the get VL. */ + if (vlmax_avl_p (new_info.get_avl ())) + { + if (this->get_avl_source ()) + new_info.set_avl_source (this->get_avl_source ()); + else + { + gcc_assert (merge_info.get_avl_source ()); + new_info.set_avl_source (merge_info.get_avl_source ()); + } + } + new_info.fuse_sew_lmul (*this, merge_info); new_info.fuse_tail_policy (*this, merge_info); new_info.fuse_mask_policy (*this, merge_info); @@ -2274,9 +2288,6 @@ vector_insn_info::get_avl_or_vl_reg (void) const if (!vlmax_avl_p (get_avl ())) return get_avl (); - if (get_avl_source ()) - return get_avl_reg_rtx (); - rtx_insn *rinsn = get_insn ()->rtl (); if (has_vl_op (rinsn) || vsetvl_insn_p (rinsn)) { @@ -2288,14 +2299,9 @@ vector_insn_info::get_avl_or_vl_reg (void) const return vl; } - /* A DIRTY (polluted EMPTY) block if: - - get_insn is scalar move (no AVL or VL operand). - - get_avl_source is null (no def in the current DIRTY block). - Then we trace the previous insn which must be the insn - already inserted in Phase 2 to get the VL operand for VLMAX. */ - rtx_insn *prev_rinsn = PREV_INSN (rinsn); - gcc_assert (prev_rinsn && vsetvl_insn_p (prev_rinsn)); - return ::get_vl (prev_rinsn); + /* We always has avl_source if it is VLMAX AVL. */ + gcc_assert (get_avl_source ()); + return get_avl_reg_rtx (); } bool diff --git a/gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 b/gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 new file mode 100644 index 000000000000..71253fe6bc5e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/fortran/pr111395.f90 @@ -0,0 +1,41 @@ +! { dg-do compile } +! { dg-options "-march=rv64gcv -mabi=lp64d -Ofast -std=legacy" } + +MODULE a + REAL b +CONTAINS + SUBROUTINE c(d,KTE) + REAL,DIMENSION(KTE) :: d,e,f,g + REAL,DIMENSION(KTE) :: h + i : DO j=1,b + z=k + DO l=m,n + IF(o>=p)THEN + IF(laf)THEN + DO l=m,n + d=h + ENDDO + ENDIF + END SUBROUTINE c +END MODULE a diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp new file mode 100644 index 000000000000..88d82281d43f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv-fortran.exp @@ -0,0 +1,45 @@ +# Copyright (C) 2023-2023 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a RISC-V target. +if { ![istarget riscv*-*-*] } then { + return +} + +# Make sure there is a fortran compiler to test. +if { ![check_no_compiler_messages fortran_available assembly { +! Fortran +program P + stop +end program P +} ""] } { + return +} + +# Load support procs. +load_lib gfortran-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/fortran/*.\[fF\]{,90,95,03,08} ] ] "" "" + +# All done. +dg-finish -- 2.47.2