diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 3355ca4e3fb5feb4da46115c6e266ec42c55419a..fbd269881064445dc8957cf8627aa17c5c89a73f 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -633,7 +633,8 @@ gen_vsetvl_pat (enum vsetvl_type insn_type, const vl_vtype_info &info, rtx vl) } static rtx -gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info) +gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info, + rtx vl = NULL_RTX) { rtx new_pat; vl_vtype_info new_info = info; @@ -644,7 +645,7 @@ gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info) if (vsetvl_insn_p (rinsn) || vlmax_avl_p (info.get_avl ())) { rtx dest = get_vl (rinsn); - new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, dest); + new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, vl ? vl : dest); } else if (INSN_CODE (rinsn) == CODE_FOR_vsetvl_vtype_change_only) new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, new_info, NULL_RTX); @@ -926,7 +927,8 @@ change_insn (rtx_insn *rinsn, rtx new_pat) print_rtl_single (dump_file, PATTERN (rinsn)); } - validate_change (rinsn, &PATTERN (rinsn), new_pat, false); + bool change_p = validate_change (rinsn, &PATTERN (rinsn), new_pat, false); + gcc_assert (change_p); if (dump_file) { @@ -1039,7 +1041,8 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, } static void -change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) +change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info, + rtx vl = NULL_RTX) { rtx_insn *rinsn; if (vector_config_insn_p (insn->rtl ())) @@ -1053,7 +1056,7 @@ change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) rinsn = PREV_INSN (insn->rtl ()); gcc_assert (vector_config_insn_p (rinsn)); } - rtx new_pat = gen_vsetvl_pat (rinsn, info); + rtx new_pat = gen_vsetvl_pat (rinsn, info, vl); change_insn (rinsn, new_pat); } @@ -3331,7 +3334,21 @@ pass_vsetvl::backward_demand_fusion (void) new_info)) continue; - change_vsetvl_insn (new_info.get_insn (), new_info); + rtx vl = NULL_RTX; + /* Backward VLMAX VL: + bb 3: + vsetivli zero, 1 ... -> vsetvli t1, zero + vmv.s.x + bb 5: + vsetvli t1, zero ... -> to be elided. + vlse16.v + + We should forward "t1". */ + if (!block_info.reaching_out.has_avl_reg () + && vlmax_avl_p (new_info.get_avl ())) + vl = get_vl (prop.get_insn ()->rtl ()); + change_vsetvl_insn (new_info.get_insn (), new_info, vl); + if (block_info.local_dem == block_info.reaching_out) block_info.local_dem = new_info; block_info.reaching_out = new_info;