Hi Juzhe, just one/two really minor nits.
> + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; > + riscv_vector::emit_vlmax_ternary_insn (code_for_pred_widen_mul_plus > (<CODE>, <MODE>mode), > + riscv_vector::RVV_WIDEN_TERNOP, ops); Here and in the following similar cases you could just use operands instead of creating a new rtx array. > +;; Enhance the combine optimizations. Similar example as before would be nice or just "this helps combine match ...". Apart from that I just wondered where/how these unpredicated patterns are being generated at all? Is this for VLA? > +;; Combine ext + ext + mult + plus ===> widen fma. > +;; We have some special cases generated by LoopVectorizer: > +;; vect__8.18_46 = (vector([8,8]) signed short) vect__7.17_47; > +;; vect__11.22_41 = (vector([8,8]) signed short) vect__10.21_42; > +;; vect__12.23_40 = vect__11.22_41 * vect__8.18_46; > +;; vect__14.25_38 = vect__13.24_39 + vect__5.14_51; > +;; This situation doesn't generate FMA IR. > +(define_insn_and_split "*double_<optab>mult_plus<mode>" > + [(set (match_operand:VWEXTI 0 "register_operand") > + (if_then_else:VWEXTI > + (unspec:<VM> > + [(match_operand:<VM> 1 "vector_mask_operand") > + (match_operand 6 "vector_length_operand") > + (match_operand 7 "const_int_operand") > + (match_operand 8 "const_int_operand") > + (match_operand 9 "const_int_operand") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (plus:VWEXTI > + (if_then_else:VWEXTI > + (unspec:<VM> > + [(match_dup 1) > + (match_dup 6) > + (match_dup 7) > + (match_dup 8) > + (match_dup 9) > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (mult:VWEXTI > + (any_extend:VWEXTI > + (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand")) > + (any_extend:VWEXTI > + (match_operand:<V_DOUBLE_TRUNC> 5 "register_operand"))) > + (match_operand:VWEXTI 2 "vector_undef_operand")) > + (match_operand:VWEXTI 3 "register_operand")) > + (match_dup 2)))] > + "TARGET_VECTOR && can_create_pseudo_p ()" > + "#" > + "&& 1" > + [(const_int 0)] > + { > + emit_insn (gen_pred_widen_mul_plus (<CODE>, <MODE>mode, operands[0], > + operands[1], operands[3], operands[4], > + operands[5], operands[6], operands[7], > + operands[8], operands[9])); I had similar patterns locally but just as splitters and not insns. Didn't make it any less ugly though. We might be needing several of such patterns still. Can't help thinking about tweaking combine at some point in the (distant) future to at least provide it with some sense of VLA structure. It could query the backend for unspec equality and then combine "normally". > +;; Combine signe_extend + zero_extend + fma ===> widen fma (su). -e Regards Robin