diff options
author | Juzhe-Zhong <juzhe.zhong@rivai.ai> | 2023-12-07 20:08:02 +0800 |
---|---|---|
committer | Lehua Ding <lehua.ding@rivai.ai> | 2023-12-07 20:21:10 +0800 |
commit | abded9bf3e1ebc1789d47ac2c445f5b613981a0e (patch) | |
tree | d423712b4abdd32a484c0ffaee37536d768e7787 /gcc | |
parent | 570d74119d2daaa9ea909b6326a3756f548097d0 (diff) | |
download | gcc-abded9bf3e1ebc1789d47ac2c445f5b613981a0e.zip gcc-abded9bf3e1ebc1789d47ac2c445f5b613981a0e.tar.gz gcc-abded9bf3e1ebc1789d47ac2c445f5b613981a0e.tar.bz2 |
RISC-V: Fix AVL propagation ICE for vleff/vlsegff
This patch fixes 400 ICEs in full coverage testing:
internal compiler error: in validate_change_or_fail, at config/riscv/riscv-v.cc:4597
The root cause is each operand is used in vleff/vlsegff twice:
(define_insn "@pred_fault_load<mode>"
[(set (match_operand:V 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:V
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, Wc1, Wc1")
(match_operand 4 "vector_length_operand" " rK, rK, rK, rK")
(match_operand 5 "const_int_operand" " i, i, i, i")
(match_operand 6 "const_int_operand" " i, i, i, i")
(match_operand 7 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(unspec:V
[(match_operand:V 3 "memory_operand" " m, m, m, m")] UNSPEC_VLEFF)
(match_operand:V 2 "vector_merge_operand" " vu, 0, vu, 0")))
(set (reg:SI VL_REGNUM)
(unspec:SI
[(if_then_else:V
(unspec:<VM>
[(match_dup 1) (match_dup 4) (match_dup 5)
(match_dup 6) (match_dup 7)
(reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(unspec:V [(match_dup 3)] UNSPEC_VLEFF)
(match_dup 2))] UNSPEC_MODIFY_VL))]
Then later instruction change in AVL propagation change ICE:
validate_change_or_fail (rinsn, recog_data.operand_loc[index],
get_avl_type_rtx (avl_type::NONVLMAX), false);
which is the operand change according to location. Such operand change in 2 locations instead of 1.
So regenerate pattern for such instructions AVL propagation to fix the ICEs.
gcc/ChangeLog:
* config/riscv/riscv-avlprop.cc (simplify_replace_avl): New function.
(simplify_replace_vlmax_avl): Fix bug.
* config/riscv/t-riscv: Add a new include file.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/vsetvl/avl_prop-2.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/riscv-avlprop.cc | 36 | ||||
-rw-r--r-- | gcc/config/riscv/t-riscv | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c | 41 |
3 files changed, 72 insertions, 7 deletions
diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc index d298f0e..02f0067 100644 --- a/gcc/config/riscv/riscv-avlprop.cc +++ b/gcc/config/riscv/riscv-avlprop.cc @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgcleanup.h" #include "insn-attr.h" #include "tm-constrs.h" +#include "insn-opinit.h" using namespace rtl_ssa; using namespace riscv_vector; @@ -142,6 +143,34 @@ get_insn_vtype_mode (rtx_insn *rinsn) return GET_MODE (recog_data.operand[mode_idx]); } +/* Return new pattern for AVL propagation. + Normally, we just replace AVL operand only for most + of the instructions. However, for instructions like + fault load which use AVL TYPE twice in the pattern which + will cause ICE in the later AVL TYPE change so we regenerate + the whole pattern for such instructions. */ +static rtx +simplify_replace_avl (rtx_insn *rinsn, rtx new_avl) +{ + /* Replace AVL operand. */ + extract_insn_cached (rinsn); + rtx avl = recog_data.operand[get_attr_vl_op_idx (rinsn)]; + int count = count_regno_occurrences (rinsn, REGNO (avl)); + gcc_assert (count == 1); + rtx new_pat = simplify_replace_rtx (PATTERN (rinsn), avl, new_avl); + if (get_attr_type (rinsn) == TYPE_VLDFF + || get_attr_type (rinsn) == TYPE_VLSEGDFF) + new_pat + = gen_pred_fault_load (recog_data.operand_mode[0], recog_data.operand[0], + recog_data.operand[1], recog_data.operand[2], + recog_data.operand[3], new_avl, + recog_data.operand[5], recog_data.operand[6], + get_avl_type_rtx (avl_type::NONVLMAX)); + else + new_pat = simplify_replace_rtx (PATTERN (rinsn), avl, new_avl); + return new_pat; +} + static void simplify_replace_vlmax_avl (rtx_insn *rinsn, rtx new_avl) { @@ -152,12 +181,7 @@ simplify_replace_vlmax_avl (rtx_insn *rinsn, rtx new_avl) fprintf (dump_file, "into: "); print_rtl_single (dump_file, rinsn); } - /* Replace AVL operand. */ - extract_insn_cached (rinsn); - rtx avl = recog_data.operand[get_attr_vl_op_idx (rinsn)]; - int count = count_regno_occurrences (rinsn, REGNO (avl)); - gcc_assert (count == 1); - rtx new_pat = simplify_replace_rtx (PATTERN (rinsn), avl, new_avl); + rtx new_pat = simplify_replace_avl (rinsn, new_avl); validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false); /* Change AVL TYPE into NONVLMAX if it is VLMAX. */ diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index 3b9686d..372bb77 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -81,7 +81,7 @@ riscv-vector-costs.o: $(srcdir)/config/riscv/riscv-vector-costs.cc \ riscv-avlprop.o: $(srcdir)/config/riscv/riscv-avlprop.cc \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ $(TARGET_H) tree-pass.h df.h rtl-ssa.h cfgcleanup.h insn-attr.h \ - tm-constrs.h + tm-constrs.h insn-opinit.h $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/riscv/riscv-avlprop.cc diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c new file mode 100644 index 0000000..fdef8e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O3 --param=riscv-autovec-preference=fixed-vlmax" } */ + +int d0, sj, v0, rp, zi; + +void +zn(void) +{ + if (v0 != 0) + { + int *js, *r3; + int pm, gc; + + for (gc = 0; gc < 1; ++gc) + { + sj = 1; + while (sj != 0) + ; + } + r3 = ± + *js = (long)&gc; +ka: + for (d0 = 0; d0 < 2; ++d0) + { + d0 = zi; + if (zi) + for (pm = 2; pm != 0; --pm) + ; + } + while (*r3 != 0) + { + while (pm) + ; + ++r3; + } + } + rp = 0; + goto ka; +} + +/* { dg-final { scan-assembler-times {vsetivli\tzero,\s*1} 2 } } */ |