aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>2023-12-07 20:08:02 +0800
committerLehua Ding <lehua.ding@rivai.ai>2023-12-07 20:21:10 +0800
commitabded9bf3e1ebc1789d47ac2c445f5b613981a0e (patch)
treed423712b4abdd32a484c0ffaee37536d768e7787 /gcc
parent570d74119d2daaa9ea909b6326a3756f548097d0 (diff)
downloadgcc-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.cc36
-rw-r--r--gcc/config/riscv/t-riscv2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c41
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 = &pm;
+ *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 } } */