Message ID | 1d7afca5-9434-6698-e695-d3e7b44fe562@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | [PATCHv2,rs6000] Merge two vector shift when their sources are the same | expand |
Hi Gently ping this. https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612944.html Thanks Gui Haochen 在 2023/2/28 10:31, HAO CHEN GUI 写道: > Hi, > This patch merges two "vsldoi" insns when their sources are the > same. Particularly, it is simplified to be one move if the total > shift is multiples of 16 bytes. > > Bootstrapped and tested on powerpc64-linux BE and LE with no > regressions. > > Thanks > Gui Haochen > > > ChangeLog > 2023-02-28 Haochen Gui <guihaoc@linux.ibm.com> > > gcc/ > * config/rs6000/altivec.md (*altivec_vsldoi_dup_<mode>): New > insn_and_split to merge two vsldoi when the sources are the same. > > gcc/testsuite/ > * gcc.target/powerpc/vsldoi_merge.c: New. > > > > patch.diff > diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md > index 84660073f32..fae8ec2b2e8 100644 > --- a/gcc/config/rs6000/altivec.md > +++ b/gcc/config/rs6000/altivec.md > @@ -2529,6 +2529,35 @@ (define_insn "altivec_vsldoi_<mode>" > "vsldoi %0,%1,%2,%3" > [(set_attr "type" "vecperm")]) > > +(define_insn_and_split "*altivec_vsldoi_dup_<mode>" > + [(set (match_operand:VM 0 "register_operand" "=v") > + (unspec:VM [(unspec:VM [(match_operand:VM 1 "register_operand" "v") > + (match_dup 1) > + (match_operand:QI 2 "immediate_operand" "i")] > + UNSPEC_VSLDOI) > + (unspec:VM [(match_dup 1) > + (match_dup 1) > + (match_dup 2)] > + UNSPEC_VSLDOI) > + (match_operand:QI 3 "immediate_operand" "i")] > + UNSPEC_VSLDOI))] > + "TARGET_ALTIVEC" > + "#" > + "&& 1" > + [(const_int 0)] > +{ > + unsigned int shift1 = UINTVAL (operands[2]); > + unsigned int shift2 = UINTVAL (operands[3]); > + > + unsigned int shift = (shift1 + shift2) % 16; > + if (shift) > + emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], > + operands[1], GEN_INT (shift))); > + else > + emit_move_insn (operands[0], operands[1]); > + DONE; > +}) > + > (define_insn "altivec_vupkhs<VU_char>" > [(set (match_operand:VP 0 "register_operand" "=v") > (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] > diff --git a/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c b/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c > new file mode 100644 > index 00000000000..eebd7b4d382 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c > @@ -0,0 +1,59 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target powerpc_vsx_ok } */ > +/* { dg-options "-O2 -mvsx -save-temps" } */ > + > +#include "altivec.h" > + > +#ifdef DEBUG > +#include <stdio.h> > +#endif > + > +void abort (void); > + > +__attribute__ ((noipa)) vector signed int > +test1 (vector signed int a) > +{ > + a = vec_sld (a, a, 2); > + a = vec_sld (a, a, 6); > + return a; > +} > + > +__attribute__ ((noipa)) vector signed int > +test2 (vector signed int a) > +{ > + a = vec_sld (a, a, 14); > + a = vec_sld (a, a, 2); > + return a; > +} > + > +int main (void) > +{ > + vector signed int a = {1,2,3,4}; > + vector signed int result_a; > + int i; > + > + result_a = test1 (a); > + vector signed int expect_a = {3,4,1,2}; > + > + for (i = 0; i< 4; i++) > + if (result_a[i] != expect_a[i]) > +#ifdef DEBUG > + printf("ERROR: test1 result[%d] = %d, not expected[%d] = %d\n", > + i, result_a[i], i, expect_a[i]); > +#else > + abort (); > +#endif > + > + result_a = test2 (a); > + > + for (i = 0; i< 4; i++) > + if (result_a[i] != a[i]) > +#ifdef DEBUG > + printf("ERROR: test2 result[%d] = %d, not expected[%d] = %d\n", > + i, result_a[i], i, a[i]); > +#else > + abort (); > +#endif > +} > + > +/* { dg-final { scan-assembler-times {\mvsldoi\M} 1 } } */
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 84660073f32..fae8ec2b2e8 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -2529,6 +2529,35 @@ (define_insn "altivec_vsldoi_<mode>" "vsldoi %0,%1,%2,%3" [(set_attr "type" "vecperm")]) +(define_insn_and_split "*altivec_vsldoi_dup_<mode>" + [(set (match_operand:VM 0 "register_operand" "=v") + (unspec:VM [(unspec:VM [(match_operand:VM 1 "register_operand" "v") + (match_dup 1) + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_VSLDOI) + (unspec:VM [(match_dup 1) + (match_dup 1) + (match_dup 2)] + UNSPEC_VSLDOI) + (match_operand:QI 3 "immediate_operand" "i")] + UNSPEC_VSLDOI))] + "TARGET_ALTIVEC" + "#" + "&& 1" + [(const_int 0)] +{ + unsigned int shift1 = UINTVAL (operands[2]); + unsigned int shift2 = UINTVAL (operands[3]); + + unsigned int shift = (shift1 + shift2) % 16; + if (shift) + emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], + operands[1], GEN_INT (shift))); + else + emit_move_insn (operands[0], operands[1]); + DONE; +}) + (define_insn "altivec_vupkhs<VU_char>" [(set (match_operand:VP 0 "register_operand" "=v") (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] diff --git a/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c b/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c new file mode 100644 index 00000000000..eebd7b4d382 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsldoi_merge.c @@ -0,0 +1,59 @@ +/* { dg-do run } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx -save-temps" } */ + +#include "altivec.h" + +#ifdef DEBUG +#include <stdio.h> +#endif + +void abort (void); + +__attribute__ ((noipa)) vector signed int +test1 (vector signed int a) +{ + a = vec_sld (a, a, 2); + a = vec_sld (a, a, 6); + return a; +} + +__attribute__ ((noipa)) vector signed int +test2 (vector signed int a) +{ + a = vec_sld (a, a, 14); + a = vec_sld (a, a, 2); + return a; +} + +int main (void) +{ + vector signed int a = {1,2,3,4}; + vector signed int result_a; + int i; + + result_a = test1 (a); + vector signed int expect_a = {3,4,1,2}; + + for (i = 0; i< 4; i++) + if (result_a[i] != expect_a[i]) +#ifdef DEBUG + printf("ERROR: test1 result[%d] = %d, not expected[%d] = %d\n", + i, result_a[i], i, expect_a[i]); +#else + abort (); +#endif + + result_a = test2 (a); + + for (i = 0; i< 4; i++) + if (result_a[i] != a[i]) +#ifdef DEBUG + printf("ERROR: test2 result[%d] = %d, not expected[%d] = %d\n", + i, result_a[i], i, a[i]); +#else + abort (); +#endif +} + +/* { dg-final { scan-assembler-times {\mvsldoi\M} 1 } } */