Thank you for reviewing this patch!

On Fri, 2025-08-29 at 13:14 -0500, Segher Boessenkool wrote:
> > This leads to having 2 instructions for the simple
> > case of left shift by one.
> >     vspltisw 0,1
> >     vsld 2,2,0
> > This could have been performed simply with one add instruction
> >     vaddudm 2,2,2
> > This patch fixes this issue. During the expansion of vashl op
> > check if the operand number 2 is a constant and its value is 1,
> > if yes then generate plus op, otherwise materialize the result
> > of operand 2 into a register and generate ashift op.
> 
> Please don't do this.  Just do a define_insn that recognises a shift
> by
> const int 1, and emits an vaddudm machine insn for that.  The RTL as
> we
> currently create is just fine, and if we would want a canonical
> representation for this the shift is probably the best idea!
> 
I did try this approach, and encountered several issues. 
1. The pattern 
[(set (match_operand:VEC_I 0 "vint_operand")
        (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand")
                      (match_operand:VEC_I 2 "vint_operand")))]
makes sure that operand #2 must be vint_operand, thus if it is a
constant, then the function 'maybe_legitimize_operands' which is called
under 'maybe_gen_insn', materialized the constant into a register after
which the pattern matches successfully. 
2. Due to the above problem, I could not create a define insn, that can
look at the operand 2 as a constant and generate vaddudm. I try
something like following:
(define_insn 
  [(set (match_operand:VEC_I 0 "vint_operand")
        (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand")
                      (const_vector:V2DI [(const_int 1) (const_int
1)])))]
  "<VI_unit>"
  {
    return "vaddu<VI_char>m %0,%1,%1";
  }
)

But the problem is again, operand 2 is always materialized into a
register. If possible, could you please suggest how I can recognize
operand #2 as a constant when it is already in a register. 

> >     PR target/119702
> > gcc:
> >     * config/rs6000/vector.md (vashl<mode>3): Generate add
> > when
> >       operand 2 is a constant with value 1.
> 
> Changelog lines are 80 character positions wide.  Please do not wrap
> early.
> 
> There should be no indent for continuation lines after the * line. 
> So:
> 
>       * wherever/that/is: Something and something more more more
> more more
>       more more more and some more.
> 
> > diff --git a/gcc/config/rs6000/vector.md
> > b/gcc/config/rs6000/vector.md
> > index f5797387ca7..02e2361e4a3 100644
> > --- a/gcc/config/rs6000/vector.md
> > +++ b/gcc/config/rs6000/vector.md
> > @@ -1391,9 +1391,29 @@
> >  (define_expand "vashl<mode>3"
> >    [(set (match_operand:VEC_I 0 "vint_operand")
> >     (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand")
> > -                 (match_operand:VEC_I 2 "vint_operand")))]
> > +                 (match_operand:VEC_I 2 "general_operand")))]
> >    "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
> > -  "")
> > +{
> > +  rtx op2 = operands[2];
> > +  if (CONSTANT_P(op2)) {
> > +    HOST_WIDE_INT shift = INTVAL(const_vector_elt (op2, 0));
> > +
> > +    if (shift == 1)
> > +      {
> > +        emit_insn (gen_rtx_SET (operands[0],
> > +                                gen_rtx_PLUS (<MODE>mode,
> > +                                              operands[1],
> > +                                              operands[1])));
> > +        DONE;
> > +      }
> > +  }
> > +  operands[2] = copy_to_mode_reg (<MODE>mode, op2);
> > +  emit_insn (gen_rtx_SET (operands[0],
> > +                          gen_rtx_ASHIFT (<MODE>mode,
> > +                                          operands[1],
> > +                                          operands[2])));
> > +  DONE;
> > +})
> 
> You shouldn't ever do things this way: if what you want to generate
> is
> just the pattern of the define_*, just fall throough (without calling
> DONE (or FAIL).  This is much more usual in a define_insn, but it
> works
> fine in a define_expand as well, see our add<mode>3_carry_in for
> example
> (this pattern is generated by name from other things in the backend,
> many of those things will finally end up in define_insn
> *add<mode>3_carry_in_internal, the next pattern, doing "adde").
> 

Just adding this comment, in case the above mentioned approach does not
work. Would this be ok? Make the operand #2 constraint as
general_operand (so that it is not materialized into a register). Then
if operand #2 is a constant int 1, pass through, else copy it to mode
reg and generate emit ASHIFT insn. 

diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index f5797387ca7..cba57a7319e 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1387,13 +1387,24 @@
   DONE;
 })
 
+
 ;; Expanders for arithmetic shift left on each vector element
 (define_expand "vashl<mode>3"
   [(set (match_operand:VEC_I 0 "vint_operand")
        (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand")
-                     (match_operand:VEC_I 2 "vint_operand")))]
+                     (match_operand:VEC_I 2 "general_operand")))]
   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
-  "")
+{
+  rtx op2 = operands[2];
+  if (CONSTANT_P(op2) && INTVAL(const_vector_elt (op2, 0)) != 1) {
+    operands[2] = copy_to_mode_reg (<MODE>mode, op2);
+    emit_insn (gen_rtx_SET (operands[0],
+                        gen_rtx_ASHIFT (<MODE>mode,
+                                        operands[1],
+                                        operands[2])));
+    DONE;
+  }
+})


This way it is easy to recognize in define_insn as follows

diff --git a/gcc/config/rs6000/altivec.md
b/gcc/config/rs6000/altivec.md
index 7edc288a656..3f678f2e666 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -2107,6 +2107,17 @@
   "vsrv %0,%1,%2"
   [(set_attr "type" "vecsimple")])
 
+
+(define_insn ""
+  [(set (match_operand:VI2 0 "register_operand" "=v")
+       (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
+                     (const_vector:V2DI [(const_int 1) (const_int
1)])))]
+  "<VI_unit>"
+  {
+    return "vaddu<VI_char>m %0,%1,%1";
+  }
+)
+
As you mentioned I will have to add patterns for various sizes as well.


Regards,
Avinash Jayakar

Reply via email to