Hi all, Below is a draft of the patch for PR119702. I request you to please review it.
In vector extensions for rs6000, there is no immediate version of left shift. 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. 2025-08-13 Avinash Jayakar <avina...@linux.ibm.com> PR target/119702 gcc: * config/rs6000/vector.md (vashl<mode>3): Generate add when operand 2 is a constant with value 1. gcc/testsuite: * gcc.target/powerpc/pr119702-1.c: New test (for checking generation of add for *2, << 1 and x+x). --- gcc/config/rs6000/vector.md | 24 ++++++++++- gcc/testsuite/gcc.target/powerpc/pr119702-1.c | 40 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-1.c 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; +}) ;; No immediate version of this 128-bit instruction (define_expand "vashl<mode>3" diff --git a/gcc/testsuite/gcc.target/powerpc/pr119702-1.c b/gcc/testsuite/gcc.target/powerpc/pr119702-1.c new file mode 100644 index 00000000000..2f53a26eaaf --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-1.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target powerpc_vsx } */ +#include <altivec.h> +#define ull unsigned long long + +void lshift1(unsigned long long *a) { + a[0] <<= 1; + a[1] <<= 1; +} + +vector ull lshift1_vector(vector ull a) { + return a <<= 1; +} + +void add(unsigned long long *a) +{ + a[0] += a[0]; + a[1] += a[1]; +} + +vector ull add_vector(vector ull a) { + return a + a; +} + +void mult2(unsigned long long *a) +{ + a[0] *= 2; + a[1] *= 2; +} + +vector ull mult2_vector(vector ull a) +{ + return a*2; +} + +/* { dg-final { scan-assembler-times {\mvaddudm?\M} 6 } } */ + -- 2.50.1