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 } } */
>