On 5/25/23 08:43, Robin Dapp wrote:
Beside, V2 patch should change this:
emit_vlmax_masked_insn (unsigned icode, int op_num, rtx *ops)

change it into emit_vlmax_masked_mu_insn .

V3 is inline with these changes.

This patch implements abs<mode>2, vneg<mode>2 and vnot<mode>2 expanders
for integer vector registers and adds tests for them.

gcc/ChangeLog:

        * config/riscv/autovec.md (<optab><mode>2): Add vneg/vnot.
        (abs<mode>2): Add.
        * config/riscv/riscv-protos.h (emit_vlmax_masked_mu_insn):
        Declare.
        * config/riscv/riscv-v.cc (emit_vlmax_masked_mu_insn): New
        function.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/rvv.exp: Add unop tests.
        * gcc.target/riscv/rvv/autovec/unop/abs-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-template.h: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-template.h: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-template.h: New test.
OK for the trunk.  BUt one comment inline...



+
+;; 
-------------------------------------------------------------------------------
+;; - ABS expansion to vmslt and vneg
+;; 
-------------------------------------------------------------------------------
+
+(define_expand "abs<mode>2"
+  [(set (match_operand:VI 0 "register_operand")
+    (match_operand:VI 1 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  rtx zero = gen_const_vec_duplicate (<MODE>mode, GEN_INT (0));
+  machine_mode mask_mode = riscv_vector::get_mask_mode (<MODE>mode).require ();
+  rtx mask = gen_reg_rtx (mask_mode);
+  riscv_vector::expand_vec_cmp (mask, LT, operands[1], zero);
+
+  rtx ops[] = {operands[0], mask, operands[1], operands[1]};
+  riscv_vector::emit_vlmax_masked_mu_insn (code_for_pred (NEG, <MODE>mode),
+                                          riscv_vector::RVV_UNOP_MU, ops);
+  DONE;
+})
So I'm a bit surprised we needed this. Presumably we needed to expose the vector abs because the vectorizer doesn't have any code to synthesize abs from other primitives?

WRT the actual synthesis... It looks like you're building a mask based on which elements are < 0 then doing a masked negation to flip them. Would this synthesis be better:

  t = -x;
  res = max (x, t);

That's the preferred synthesis at the gimple->rtl border for scalars.

Anyway, if we think that's a better synthesis, we can adjust as a follow-up patch.

So again, OK for the trunk.

jeff

Reply via email to