Ping! Please review. Thanks, Avinash Jayakar
On Fri, 2025-10-24 at 14:45 +0530, Avinash Jayakar wrote: > Hi Segher, > > Please ignore the v7 patch, had minor errors in capitalization. > Thanks for the review of the v6 patch. I have incorporated all the > mentioned > changes in this patch. > Bootstrapped and regtested on powerpc64le-linux with no regressions. > Ok for trunk? > > As mentioned in the PATCH v6 thread vaddudm tests fail in power8/9 > for: > 1. pr119702-3.c: Surya's patch for PR107757 should fix this test case > once > upstream. > 2. pr119702-4.c: Work in progress (PR122065) > > Changes from v7: > 1. Minor corrections in commit message. > Changes from v6: > 1. for loop formatting in predicates.md > 2. Correct type from long to char in pr119702-2.c > 3. Add has_arch_pwr8 for vaddudm tests. > Changes from v5: > 1. Corrected formatting and define_insn name. > 2. Removed cpu specific flag for altivec tests. > 3. Remove target lp64 for altivec tests. > 4. Use native types instead of types from inttypes.h for > altivec tests. > Changes from v4: > 1. Added comments for the new predicate "vector_constant_1". > 2. Added new tests for altivec vector types. > 3. Added comments in test file. > Changes from v3: > 1. Add author information before changelog. > 2. Right placement of PR target/119702. > 3. Added new test to check multiply by 2 generates vadd > insn. > Changes from v2: > 1. Indentation fixes in the commit message > 2. define_insn has the name *altivec_vsl<VI_char>_const_1 > 3. Iterate starting from 0 for checking vector constant = 1 > and > fixed source code formatting for the for loop. > 4. Removed unused macro in pr119702-1.c test file > Changes from v1: > 1. Use define_insn instead of define_expand to recognize > left > shift by constant 1 and generate add instruction. > 2. Updated test cases to cover integer types from byte, > half- > word, word and double word. > > Thanks and regards, > Avinash Jayakar > > > Whenever a vector of integers is left shifted by a constant value 1, > gcc generates the following code for powerpc64le target: > vspltisw 0,1 > vsld 2,2,0 > Instead the following code can be generated which is more efficient: > vaddudm 2,2,2 > This patch adds a pattern in altivec.md to recognize a vector left > shift by a constant value, and generates an add instruction if > constant > is 1. > > Added the pattern in altivec.md to recognize a vector left shift by a > constant value, and generate add instructions if constant is 1. > Added a predicate in predicates.md to recognize if the rtl node is a > uniform constant vector with value 1. > > 2025-10-24 Avinash Jayakar <[email protected]> > > gcc/ChangeLog: > PR target/119702 > * config/rs6000/altivec.md (*altivec_vsl<VI_char>_const_1): > Recognize > << 1 and replace with vadd insn. > * config/rs6000/predicates.md (vector_constant_1): Predicate > to check if > all elements of a vector constant is 1. > > gcc/testsuite/ChangeLog: > PR target/119702 > * gcc.target/powerpc/pr119702-1.c: New test. > * gcc.target/powerpc/pr119702-2.c: New test. > * gcc.target/powerpc/pr119702-3.c: New test. > * gcc.target/powerpc/pr119702-4.c: New test. > --- > gcc/config/rs6000/altivec.md | 8 +++ > gcc/config/rs6000/predicates.md | 13 ++++ > gcc/testsuite/gcc.target/powerpc/pr119702-1.c | 60 > +++++++++++++++++++ > gcc/testsuite/gcc.target/powerpc/pr119702-2.c | 59 > ++++++++++++++++++ > gcc/testsuite/gcc.target/powerpc/pr119702-3.c | 36 +++++++++++ > gcc/testsuite/gcc.target/powerpc/pr119702-4.c | 36 +++++++++++ > 6 files changed, 212 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-1.c > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-2.c > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-3.c > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-4.c > > diff --git a/gcc/config/rs6000/altivec.md > b/gcc/config/rs6000/altivec.md > index fa3368079ad..11b8501a7d0 100644 > --- a/gcc/config/rs6000/altivec.md > +++ b/gcc/config/rs6000/altivec.md > @@ -2107,6 +2107,14 @@ > "vsrv %0,%1,%2" > [(set_attr "type" "vecsimple")]) > > +(define_insn "*altivec_vsl<VI_char>_const_1" > + [(set (match_operand:VI2 0 "register_operand" "=v") > + (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") > + (match_operand:VI2 2 "vector_constant_1" > "")))] > + "<VI_unit>" > + "vaddu<VI_char>m %0,%1,%1" > +) > + > (define_insn "*altivec_vsl<VI_char>" > [(set (match_operand:VI2 0 "register_operand" "=v") > (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") > diff --git a/gcc/config/rs6000/predicates.md > b/gcc/config/rs6000/predicates.md > index 647e89afb6a..017ff867aea 100644 > --- a/gcc/config/rs6000/predicates.md > +++ b/gcc/config/rs6000/predicates.md > @@ -924,6 +924,19 @@ > } > }) > > +;; Return 1 if the operand is a vector constant with 1 in all of the > elements. > +(define_predicate "vector_constant_1" > + (match_code "const_vector") > +{ > + unsigned nunits = GET_MODE_NUNITS (mode); > + for (unsigned i = 0; i < nunits; i++) > + { > + if (INTVAL (CONST_VECTOR_ELT (op, i)) != 1) > + return 0; > + } > + return 1; > +}) > + > ;; Return 1 if operand is 0.0. > (define_predicate "zero_fp_constant" > (and (match_code "const_double") > 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..d12ae23be60 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-1.c > @@ -0,0 +1,60 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -maltivec" } */ > +/* { dg-require-effective-target powerpc_altivec } */ > + > +/* PR target/119702 -- verify left shift by 1 is converted into > + a vaddu<x>m instruction. */ > + > + > +void lshift1_64(unsigned long long *a) > +{ > + a[0] <<= 1; > + a[1] <<= 1; > +} > + > +void lshift1_32(unsigned int *a) > +{ > + a[0] <<= 1; > + a[1] <<= 1; > + a[2] <<= 1; > + a[3] <<= 1; > +} > + > +void lshift1_16(unsigned short *a) > +{ > + a[0] <<= 1; > + a[1] <<= 1; > + a[2] <<= 1; > + a[3] <<= 1; > + a[4] <<= 1; > + a[5] <<= 1; > + a[6] <<= 1; > + a[7] <<= 1; > +} > + > +void lshift1_8(unsigned char *a) > +{ > + a[0] <<= 1; > + a[1] <<= 1; > + a[2] <<= 1; > + a[3] <<= 1; > + a[4] <<= 1; > + a[5] <<= 1; > + a[6] <<= 1; > + a[7] <<= 1; > + a[8] <<= 1; > + a[9] <<= 1; > + a[10] <<= 1; > + a[11] <<= 1; > + a[12] <<= 1; > + a[13] <<= 1; > + a[14] <<= 1; > + a[15] <<= 1; > +} > + > + > +/* { dg-final { scan-assembler-times {\mvaddudm\M} 1 { target > has_arch_pwr8 } } } */ > +/* { dg-final { scan-assembler-times {\mvadduwm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvadduhm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvaddubm\M} 1 } } */ > + > diff --git a/gcc/testsuite/gcc.target/powerpc/pr119702-2.c > b/gcc/testsuite/gcc.target/powerpc/pr119702-2.c > new file mode 100644 > index 00000000000..45161f6311a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-2.c > @@ -0,0 +1,59 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -maltivec" } */ > +/* { dg-require-effective-target powerpc_altivec } */ > + > +/* PR target/119702 -- verify multiply by 2 is converted into > + a vaddu<x>m instruction. */ > + > +void lshift1_64(unsigned long long *a) > +{ > + a[0] *= 2; > + a[1] *= 2; > +} > + > +void lshift1_32(unsigned int *a) > +{ > + a[0] *= 2; > + a[1] *= 2; > + a[2] *= 2; > + a[3] *= 2; > +} > + > +void lshift1_16(unsigned short *a) > +{ > + a[0] *= 2; > + a[1] *= 2; > + a[2] *= 2; > + a[3] *= 2; > + a[4] *= 2; > + a[5] *= 2; > + a[6] *= 2; > + a[7] *= 2; > +} > + > +void lshift1_8(unsigned char *a) > +{ > + a[0] *= 2; > + a[1] *= 2; > + a[2] *= 2; > + a[3] *= 2; > + a[4] *= 2; > + a[5] *= 2; > + a[6] *= 2; > + a[7] *= 2; > + a[8] *= 2; > + a[9] *= 2; > + a[10] *= 2; > + a[11] *= 2; > + a[12] *= 2; > + a[13] *= 2; > + a[14] *= 2; > + a[15] *= 2; > +} > + > + > +/* { dg-final { scan-assembler-times {\mvaddudm\M} 1 { target > has_arch_pwr8 } } } */ > +/* { dg-final { scan-assembler-times {\mvadduwm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvadduhm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvaddubm\M} 1 } } */ > + > diff --git a/gcc/testsuite/gcc.target/powerpc/pr119702-3.c > b/gcc/testsuite/gcc.target/powerpc/pr119702-3.c > new file mode 100644 > index 00000000000..28a53e75dd9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-3.c > @@ -0,0 +1,36 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -maltivec" } */ > +/* { dg-require-effective-target powerpc_altivec } */ > + > +/* PR target/119702 -- verify vector shift left by 1 is converted > into > + a vaddu<x>m instruction. */ > + > +vector unsigned long long > +lshift1_64 (vector unsigned long long a) > +{ > + return a << (vector unsigned long long) { 1, 1 }; > +} > + > +vector unsigned int > +lshift1_32 (vector unsigned int a) > +{ > + return a << (vector unsigned int) { 1, 1, 1, 1 }; > +} > + > +vector unsigned short > +lshift1_16 (vector unsigned short a) > +{ > + return a << (vector unsigned short) { 1, 1, 1, 1, 1, 1, 1, 1 }; > +} > + > +vector unsigned char > +lshift1_8 (vector unsigned char a) > +{ > + return a << (vector unsigned char) { 1, 1, 1, 1, 1, 1, 1, 1, > + 1, 1, 1, 1, 1, 1, 1, 1 }; > +} > + > +/* { dg-final { scan-assembler-times {\mvaddudm\M} 1 { target > has_arch_pwr8 } } } */ > +/* { dg-final { scan-assembler-times {\mvadduwm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvadduhm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvaddubm\M} 1 } } */ > diff --git a/gcc/testsuite/gcc.target/powerpc/pr119702-4.c > b/gcc/testsuite/gcc.target/powerpc/pr119702-4.c > new file mode 100644 > index 00000000000..759866e2cd2 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-4.c > @@ -0,0 +1,36 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -maltivec" } */ > +/* { dg-require-effective-target powerpc_altivec } */ > + > +/* PR target/119702 -- verify vector multiply by 2 is converted into > + a vaddu<x>m instruction. */ > + > +vector unsigned long long > +lshift1_64 (vector unsigned long long a) > +{ > + return a * (vector unsigned long long) { 2, 2 }; > +} > + > +vector unsigned int > +lshift1_32 (vector unsigned int a) > +{ > + return a * (vector unsigned int) { 2, 2, 2, 2 }; > +} > + > +vector unsigned short > +lshift1_16 (vector unsigned short a) > +{ > + return a * (vector unsigned short) { 2, 2, 2, 2, 2, 2, 2, 2 }; > +} > + > +vector unsigned char > +lshift1_8 (vector unsigned char a) > +{ > + return a * (vector unsigned char) { 2, 2, 2, 2, 2, 2, 2, 2, > + 2, 2, 2, 2, 2, 2, 2, 2 }; > +} > + > +/* { dg-final { scan-assembler-times {\mvaddudm\M} 1 { target > has_arch_pwr8 } } } */ > +/* { dg-final { scan-assembler-times {\mvadduwm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvadduhm\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mvaddubm\M} 1 } } */
