Hi,

I have been working on making better use of s390's vzero instruction.
Currently we rather zero a vector register once and load it into other
registers via vlr instead of emitting multiple vzeros.

At IRA/reload point we e.g. have

(insn 8 5 19 2 (set (reg/v:V2DI 64 [ zero ])
        (const_vector:V2DI [
                (const_int 0 [0]) repeated x2
            ])) "vzero-vs-vlr.c":18:17 412 {movv2di}
     (expr_list:REG_EQUIV (const_vector:V2DI [
                (const_int 0 [0]) repeated x2 ])
        (nil)))

so reg 64 is equivalent to a const_vector 0.  I expected ira/reload to
match our move pattern (abbreviated for readability)

(define_insn "mov<mode>"
  [(set (match_operand:V_64 0 "nonimmediate_operand" "v")
        (match_operand:V_64 1 "general_operand"      "j00"))]
  "TARGET_ZARCH"
  "@
   vzero\t%v0 [..]

where the j00 constraint is simply

(define_constraint "j00"
  "Zero scalar or vector constant"
  (match_test "op == CONST0_RTX (GET_MODE (op))"))

Apparently this is not what's happening.  The vzero alternative is
rejected since the register is not actually a constant but only
equivalent to one.

It is possible to work around that by changing pattern decisions earlier
but I'd still like to understand what is supposed to happen here.
Should another pass perform the equiv replacement or is this not how all
of this works entirely?  I was also thinking into the direction of
register_move_costs and rtx_costs but at least initial attempts did not
help.

Thanks for clarifying
 Robin

Reply via email to