Re: rs6000: Fix vec_permx wrong-code [PR125138]
Surya Kumari Jangala <[email protected]> Tue, 4 Aug 2026 17:17:31 +0530
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
This patch looks good to me. I cannot approve it though. -Surya On 27/07/26 4:57 PM, jeevitha wrote: > > Hi All, > > The following patch has been bootstrapped and regtested on powerpc64le-linux. > > The little-endian expansion of vec_permx modified the permute control > vector. When the same control vector was used by multiple vec_permx > calls, later calls used the modified value and produced incorrect > results. > > Generate the negated control vector in a new pseudo register instead of > modifying the input operand. > > 2026-07-27 Jeevitha Palanisamy <[email protected]> > > gcc/ > PR target/125138 > * config/rs6000/vsx.md (xxpermx): Use a temporary register for the > negated control vector. > > gcc/testsuite/ > PR target/125138 > * gcc.target/powerpc/pr125138.c: New test. > > diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md > index 9863c476bac..739716c198f 100644 > --- a/gcc/config/rs6000/vsx.md > +++ b/gcc/config/rs6000/vsx.md > @@ -6789,12 +6789,13 @@ > of element from 7. */ > int value = INTVAL (operands[4]); > rtx vreg = gen_reg_rtx (V16QImode); > + rtx tmp = gen_reg_rtx (V16QImode); > > emit_insn (gen_xxspltib_v16qi (vreg, GEN_INT (-1))); > - emit_insn (gen_xorv16qi3 (operands[3], operands[3], vreg)); > + emit_insn (gen_xorv16qi3 (tmp, operands[3], vreg)); > value = 7 - value; > emit_insn (gen_xxpermx_inst (operands[0], operands[2], > - operands[1], operands[3], > + operands[1], tmp, > GEN_INT (value))); > } > > diff --git a/gcc/testsuite/gcc.target/powerpc/pr125138.c b/gcc/testsuite/gcc.target/powerpc/pr125138.c > new file mode 100644 > index 00000000000..f7f0d2c7f08 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr125138.c > @@ -0,0 +1,34 @@ > +/* PR target/125138 */ > +/* { dg-do compile } */ > +/* { dg-require-effective-target power10_ok } */ > +/* { dg-options "-O3 -mdejagnu-cpu=power10" } */ > + > +#include <altivec.h> > + > +typedef vector unsigned char vui8_t; > + > +vui8_t > +test1 (vui8_t vra0, vui8_t vrb0, vui8_t vra1, vui8_t vrb1, vui8_t vrc) > +{ > + vui8_t perm0, perm1; > + perm0 = vec_permx (vra0, vrb0, vrc, 0); > + perm1 = vec_permx (vra1, vrb1, vrc, 1); > + return vec_or (perm0, perm1); > +} > + > +vui8_t > +test2 (vui8_t vra0, vui8_t vrb0, vui8_t vra1, vui8_t vrb1, vui8_t vra2, > + vui8_t vrb2, vui8_t vra3, vui8_t vrb3, vui8_t vrc) > +{ > + vui8_t perm0, perm1, perm2, perm3; > + perm0 = vec_permx (vra0, vrb0, vrc, 0); > + perm1 = vec_permx (vra1, vrb1, vrc, 1); > + perm2 = vec_permx (vra2, vrb2, vrc, 2); > + perm3 = vec_permx (vra3, vrb3, vrc, 3); > + perm0 = vec_or (perm0, perm1); > + perm2 = vec_or (perm2, perm3); > + return vec_or (perm0, perm2); > +} > + > +/* { dg-final { scan-assembler-times {\mxxlnor\M} 2 } } */ > +/* { dg-final { scan-assembler-times {\mxxpermx\M} 6 } } */ >