[rs6000] Fix PR83399, ICE During LRA with 2-op rtl pattern for lvx instruction

Message ID cb28ff47-f0b4-d56d-4c1b-d8095ffe450d@vnet.ibm.com
State New
Headers show
Series
  • [rs6000] Fix PR83399, ICE During LRA with 2-op rtl pattern for lvx instruction
Related show

Commit Message

Peter Bergner Jan. 9, 2018, 6:22 p.m.
PR83399 shows a problem where we emit an altivec load using a builtin
that forces us to use a specific altivec load pattern.  The generated
rtl pattern has a use of sfp (frame pointer) and during LRA, we eliminate
it's use to the sp (lra-eliminations.c:process_insn_for_elimination).
During this process, we re-recog the insn and end up matching a different
vsx pattern, because it exists earlier in the machine description file.
That vsx pattern uses a "Z" constraint for its address operand, which will
not accept the "special" altivec address we have, but the memory_operand
predicate the pattern uses allows it.  The recog'ing to a different pattern
than we want, causes us to ICE later on.

The solution here is to tighten the predicate used for the address in the
vsx pattern to use the indexed_or_indirect_operand instead, which will
reject the altivec address our rtl pattern has.

Once this is fixed, we end up hitting another issue in print_operand when
outputing altivec addresses when using -mvsx.  This was fixed by allowing
both ALTIVEC or VSX VECTOR MEMs.

This passed bootstrap and regtesting on powerpc64le-linux with no regressions.
Ok for trunk?

Is this ok for the open release branches too, once testing has completed there?

Peter


gcc/
	PR target/83399
	* config/rs6000/rs6000.c (print_operand): Use
	VECTOR_MEM_ALTIVEC_OR_VSX_P.
	* config/rs6000/vsx.md (*vsx_le_perm_load_<mode><VSX_D>): Use
	indexed_or_indirect_operand predicate.
	(*vsx_le_perm_load_<mode><VSX_W>): Likewise.
	(*vsx_le_perm_load_v8hi): Likewise.
	(*vsx_le_perm_load_v8hi): Likewise.
	(*vsx_le_perm_load_v16qi): Likewise.
	(*vsx_le_perm_store_<mode><VSX_D>): Likewise in pattern and splitters.
	(*vsx_le_perm_store_<mode><VSX_W>): Likewise.
	(*vsx_le_perm_store_v8hi): Likewise.
	(*vsx_le_perm_store_v16qi): Likewise.

gcc/testsuite/
	PR target/83399
	* gcc.target/powerpc/pr83399.c: New test.

Comments

Segher Boessenkool Jan. 10, 2018, 7:44 p.m. | #1
On Tue, Jan 09, 2018 at 12:22:38PM -0600, Peter Bergner wrote:
> PR83399 shows a problem where we emit an altivec load using a builtin

> that forces us to use a specific altivec load pattern.  The generated

> rtl pattern has a use of sfp (frame pointer) and during LRA, we eliminate

> it's use to the sp (lra-eliminations.c:process_insn_for_elimination).

> During this process, we re-recog the insn and end up matching a different

> vsx pattern, because it exists earlier in the machine description file.

> That vsx pattern uses a "Z" constraint for its address operand, which will

> not accept the "special" altivec address we have, but the memory_operand

> predicate the pattern uses allows it.  The recog'ing to a different pattern

> than we want, causes us to ICE later on.

> 

> The solution here is to tighten the predicate used for the address in the

> vsx pattern to use the indexed_or_indirect_operand instead, which will

> reject the altivec address our rtl pattern has.

> 

> Once this is fixed, we end up hitting another issue in print_operand when

> outputing altivec addresses when using -mvsx.  This was fixed by allowing

> both ALTIVEC or VSX VECTOR MEMs.

> 

> This passed bootstrap and regtesting on powerpc64le-linux with no regressions.

> Ok for trunk?

> 

> Is this ok for the open release branches too, once testing has completed there?

> 

> Peter

> 

> 

> gcc/

> 	PR target/83399

> 	* config/rs6000/rs6000.c (print_operand): Use

> 	VECTOR_MEM_ALTIVEC_OR_VSX_P.


(print_operand) <'y'>: ...

> 	* config/rs6000/vsx.md (*vsx_le_perm_load_<mode><VSX_D>): Use

> 	indexed_or_indirect_operand predicate.


It's *vsx_le_perm_load_<mode> -- <VSX_D> is not part of the name.  It
makes sense to mention it, maybe like
	* config/rs6000/vsx.md (*vsx_le_perm_load_<mode> for VSX_D): ...

> 	(*vsx_le_perm_load_<mode><VSX_W>): Likewise.


Similar.

> 	(*vsx_le_perm_load_v8hi): Likewise.

> 	(*vsx_le_perm_load_v8hi): Likewise.


You duplicated this line.

> 	(*vsx_le_perm_load_v16qi): Likewise.

> 	(*vsx_le_perm_store_<mode><VSX_D>): Likewise in pattern and splitters.

> 	(*vsx_le_perm_store_<mode><VSX_W>): Likewise.


Same for these two.

> 	(*vsx_le_perm_store_v8hi): Likewise.

> 	(*vsx_le_perm_store_v16qi): Likewise.

> 

> gcc/testsuite/

> 	PR target/83399

> 	* gcc.target/powerpc/pr83399.c: New test.


>  (define_split

> -  [(set (match_operand:VSX_D 0 "memory_operand" "")

> +  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")

>          (match_operand:VSX_D 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"

>    [(set (match_dup 2)

> @@ -570,7 +570,7 @@ (define_split

>  ;; The post-reload split requires that we re-permute the source

>  ;; register in case it is still live.

>  (define_split

> -  [(set (match_operand:VSX_D 0 "memory_operand" "")

> +  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")

>          (match_operand:VSX_D 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

>    [(set (match_dup 1)


You don't mention these in the changelog.

>  (define_split

> -  [(set (match_operand:VSX_W 0 "memory_operand" "")

> +  [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "")

>          (match_operand:VSX_W 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"

>    [(set (match_dup 2)

> @@ -617,7 +617,7 @@ (define_split

>  ;; The post-reload split requires that we re-permute the source

>  ;; register in case it is still live.

>  (define_split

> -  [(set (match_operand:VSX_W 0 "memory_operand" "")

> +  [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "")

>          (match_operand:VSX_W 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

>    [(set (match_dup 1)

> @@ -638,7 +638,7 @@ (define_split

>    "")


Or these.

>  (define_split

> -  [(set (match_operand:V8HI 0 "memory_operand" "")

> +  [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "")

>          (match_operand:V8HI 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"

>    [(set (match_dup 2)

> @@ -671,7 +671,7 @@ (define_split

>  ;; The post-reload split requires that we re-permute the source

>  ;; register in case it is still live.

>  (define_split

> -  [(set (match_operand:V8HI 0 "memory_operand" "")

> +  [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "")

>          (match_operand:V8HI 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

>    [(set (match_dup 1)


Or these.

>  (define_split

> -  [(set (match_operand:V16QI 0 "memory_operand" "")

> +  [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "")

>          (match_operand:V16QI 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"

>    [(set (match_dup 2)

> @@ -739,7 +739,7 @@ (define_split

>  ;; The post-reload split requires that we re-permute the source

>  ;; register in case it is still live.

>  (define_split

> -  [(set (match_operand:V16QI 0 "memory_operand" "")

> +  [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "")

>          (match_operand:V16QI 1 "vsx_register_operand" ""))]

>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

>    [(set (match_dup 1)


And more :-)

Please fix up the changelog.  The patch is fine :-)  Okay for trunk, and
okay for the branches after the usual wait.  Thanks!


Segher
Peter Bergner Jan. 10, 2018, 7:55 p.m. | #2
On 1/10/18 1:44 PM, Segher Boessenkool wrote:
> On Tue, Jan 09, 2018 at 12:22:38PM -0600, Peter Bergner wrote:

>> 	* config/rs6000/rs6000.c (print_operand): Use

>> 	VECTOR_MEM_ALTIVEC_OR_VSX_P.

> 

> (print_operand) <'y'>: ...


Will fix.



>> 	* config/rs6000/vsx.md (*vsx_le_perm_load_<mode><VSX_D>): Use

>> 	indexed_or_indirect_operand predicate.

> 

> It's *vsx_le_perm_load_<mode> -- <VSX_D> is not part of the name.  It

> makes sense to mention it, maybe like

> 	* config/rs6000/vsx.md (*vsx_le_perm_load_<mode> for VSX_D): ...


I didn't know how to handle that, so I guessed! :-)  Will fix.



>> 	(*vsx_le_perm_load_v8hi): Likewise.

>> 	(*vsx_le_perm_load_v8hi): Likewise.

> 

> You duplicated this line.


Will fix.

>> 	(*vsx_le_perm_store_<mode><VSX_D>): Likewise in pattern and splitters.


[snip]

>>  (define_split

>> -  [(set (match_operand:VSX_D 0 "memory_operand" "")

>> +  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")

>>          (match_operand:VSX_D 1 "vsx_register_operand" ""))]

>>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"

>>    [(set (match_dup 2)

>> @@ -570,7 +570,7 @@ (define_split

>>  ;; The post-reload split requires that we re-permute the source

>>  ;; register in case it is still live.

>>  (define_split

>> -  [(set (match_operand:VSX_D 0 "memory_operand" "")

>> +  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")

>>          (match_operand:VSX_D 1 "vsx_register_operand" ""))]

>>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

>>    [(set (match_dup 1)

> 

> You don't mention these in the changelog.


I tried to by mentioning splitters in the entry above.  How are these
unnamed splitters supposed to be mentioned?  Maybe like:

	(*vsx_le_perm_store_<mode> for <VSX_D>): Likewise/
	(*vsx_le_perm_store_<mode> for <VSX_D> splitter): Likewise.

?

Peter
Segher Boessenkool Jan. 10, 2018, 8:38 p.m. | #3
Hi,

On Wed, Jan 10, 2018 at 01:55:34PM -0600, Peter Bergner wrote:
> >> @@ -570,7 +570,7 @@ (define_split

> >>  ;; The post-reload split requires that we re-permute the source

> >>  ;; register in case it is still live.

> >>  (define_split

> >> -  [(set (match_operand:VSX_D 0 "memory_operand" "")

> >> +  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")

> >>          (match_operand:VSX_D 1 "vsx_register_operand" ""))]

> >>    "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"

> >>    [(set (match_dup 1)

> > 

> > You don't mention these in the changelog.

> 

> I tried to by mentioning splitters in the entry above.  How are these

> unnamed splitters supposed to be mentioned?  Maybe like:

> 

> 	(*vsx_le_perm_store_<mode> for <VSX_D>): Likewise/

> 	(*vsx_le_perm_store_<mode> for <VSX_D> splitter): Likewise.


They don't have that name (they don't have any name).

I often say things like

	(8 unnamed splitters): Likewise.

(you can try to merge a define_split first, to a define_insn_and_split,
which is a nice cleanup by itself; but that won't work here I think).


Segher
Peter Bergner Jan. 10, 2018, 9:10 p.m. | #4
On 1/10/18 2:38 PM, Segher Boessenkool wrote:
> They don't have that name (they don't have any name).

> 

> I often say things like

> 

> 	(8 unnamed splitters): Likewise.


Ok, committed with the following updated ChangeLog which we discussed offline.
Thanks!

gcc/
        PR target/83399
        * config/rs6000/rs6000.c (print_operand) <'y'>: Use
        VECTOR_MEM_ALTIVEC_OR_VSX_P.
        * config/rs6000/vsx.md (*vsx_le_perm_load_<mode> for VSX_D): Use
        indexed_or_indirect_operand predicate.
        (*vsx_le_perm_load_<mode> for VSX_W): Likewise.
        (*vsx_le_perm_load_v8hi): Likewise.
        (*vsx_le_perm_load_v16qi): Likewise.
        (*vsx_le_perm_store_<mode> for VSX_D): Likewise.
        (*vsx_le_perm_store_<mode> for VSX_W): Likewise.
        (*vsx_le_perm_store_v8hi): Likewise.
        (*vsx_le_perm_store_v16qi): Likewise.
        (eight unnamed splitters): Likewise.

gcc/testsuite/
        PR target/83399
        * gcc.target/powerpc/pr83399.c: New test.

Peter
Peter Bergner Feb. 28, 2018, 3:48 p.m. | #5
On 1/10/18 3:10 PM, Peter Bergner wrote:
> gcc/

>         PR target/83399

>         * config/rs6000/rs6000.c (print_operand) <'y'>: Use

>         VECTOR_MEM_ALTIVEC_OR_VSX_P.

>         * config/rs6000/vsx.md (*vsx_le_perm_load_<mode> for VSX_D): Use

>         indexed_or_indirect_operand predicate.

>         (*vsx_le_perm_load_<mode> for VSX_W): Likewise.

>         (*vsx_le_perm_load_v8hi): Likewise.

>         (*vsx_le_perm_load_v16qi): Likewise.

>         (*vsx_le_perm_store_<mode> for VSX_D): Likewise.

>         (*vsx_le_perm_store_<mode> for VSX_W): Likewise.

>         (*vsx_le_perm_store_v8hi): Likewise.

>         (*vsx_le_perm_store_v16qi): Likewise.

>         (eight unnamed splitters): Likewise.

> 

> gcc/testsuite/

>         PR target/83399

>         * gcc.target/powerpc/pr83399.c: New test.


David reported that the new test case was failing on AIX because -mlittle
is not supported there.  I have committed as obvious the following patch
that limits the test being run on Linux only.

Peter

	PR target/83399
	* gcc.target/powerpc/pr83399.c: Only run on Linux.

 	PR tree-optimization/84584
Index: gcc/testsuite/gcc.target/powerpc/pr83399.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr83399.c	(revision 258070)
+++ gcc/testsuite/gcc.target/powerpc/pr83399.c	(working copy)
@@ -1,5 +1,5 @@
 /* PR target/83399 */
-/* { dg-do compile } */
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
 /* { dg-require-effective-target powerpc_vsx_ok } */
 /* { dg-options "-O1 -mabi=elfv2 -mlittle -mvsx" } */

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 256351)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -21671,7 +21671,7 @@  print_operand (FILE *file, rtx x, int co
 
 	tmp = XEXP (x, 0);
 
-	if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
+	if (VECTOR_MEM_ALTIVEC_OR_VSX_P (GET_MODE (x))
 	    && GET_CODE (tmp) == AND
 	    && GET_CODE (XEXP (tmp, 1)) == CONST_INT
 	    && INTVAL (XEXP (tmp, 1)) == -16)
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 256351)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -430,7 +430,7 @@  (define_c_enum "unspec"
 ;; VSX moves so they match first.
 (define_insn_and_split "*vsx_le_perm_load_<mode>"
   [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSa>")
-        (match_operand:VSX_D 1 "memory_operand" "Z"))]
+        (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
@@ -453,7 +453,7 @@  (define_insn_and_split "*vsx_le_perm_loa
 
 (define_insn_and_split "*vsx_le_perm_load_<mode>"
   [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
-        (match_operand:VSX_W 1 "memory_operand" "Z"))]
+        (match_operand:VSX_W 1 "indexed_or_indirect_operand" "Z"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
@@ -478,7 +478,7 @@  (define_insn_and_split "*vsx_le_perm_loa
 
 (define_insn_and_split "*vsx_le_perm_load_v8hi"
   [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
-        (match_operand:V8HI 1 "memory_operand" "Z"))]
+        (match_operand:V8HI 1 "indexed_or_indirect_operand" "Z"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
@@ -507,7 +507,7 @@  (define_insn_and_split "*vsx_le_perm_loa
 
 (define_insn_and_split "*vsx_le_perm_load_v16qi"
   [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
-        (match_operand:V16QI 1 "memory_operand" "Z"))]
+        (match_operand:V16QI 1 "indexed_or_indirect_operand" "Z"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
@@ -543,7 +543,7 @@  (define_insn_and_split "*vsx_le_perm_loa
    (set_attr "length" "8")])
 
 (define_insn "*vsx_le_perm_store_<mode>"
-  [(set (match_operand:VSX_D 0 "memory_operand" "=Z")
+  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "=Z")
         (match_operand:VSX_D 1 "vsx_register_operand" "+<VSa>"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
@@ -551,7 +551,7 @@  (define_insn "*vsx_le_perm_store_<mode>"
    (set_attr "length" "12")])
 
 (define_split
-  [(set (match_operand:VSX_D 0 "memory_operand" "")
+  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")
         (match_operand:VSX_D 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
   [(set (match_dup 2)
@@ -570,7 +570,7 @@  (define_split
 ;; The post-reload split requires that we re-permute the source
 ;; register in case it is still live.
 (define_split
-  [(set (match_operand:VSX_D 0 "memory_operand" "")
+  [(set (match_operand:VSX_D 0 "indexed_or_indirect_operand" "")
         (match_operand:VSX_D 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
   [(set (match_dup 1)
@@ -588,7 +588,7 @@  (define_split
   "")
 
 (define_insn "*vsx_le_perm_store_<mode>"
-  [(set (match_operand:VSX_W 0 "memory_operand" "=Z")
+  [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "=Z")
         (match_operand:VSX_W 1 "vsx_register_operand" "+<VSa>"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
@@ -596,7 +596,7 @@  (define_insn "*vsx_le_perm_store_<mode>"
    (set_attr "length" "12")])
 
 (define_split
-  [(set (match_operand:VSX_W 0 "memory_operand" "")
+  [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "")
         (match_operand:VSX_W 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
   [(set (match_dup 2)
@@ -617,7 +617,7 @@  (define_split
 ;; The post-reload split requires that we re-permute the source
 ;; register in case it is still live.
 (define_split
-  [(set (match_operand:VSX_W 0 "memory_operand" "")
+  [(set (match_operand:VSX_W 0 "indexed_or_indirect_operand" "")
         (match_operand:VSX_W 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
   [(set (match_dup 1)
@@ -638,7 +638,7 @@  (define_split
   "")
 
 (define_insn "*vsx_le_perm_store_v8hi"
-  [(set (match_operand:V8HI 0 "memory_operand" "=Z")
+  [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "=Z")
         (match_operand:V8HI 1 "vsx_register_operand" "+wa"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
@@ -646,7 +646,7 @@  (define_insn "*vsx_le_perm_store_v8hi"
    (set_attr "length" "12")])
 
 (define_split
-  [(set (match_operand:V8HI 0 "memory_operand" "")
+  [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "")
         (match_operand:V8HI 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
   [(set (match_dup 2)
@@ -671,7 +671,7 @@  (define_split
 ;; The post-reload split requires that we re-permute the source
 ;; register in case it is still live.
 (define_split
-  [(set (match_operand:V8HI 0 "memory_operand" "")
+  [(set (match_operand:V8HI 0 "indexed_or_indirect_operand" "")
         (match_operand:V8HI 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
   [(set (match_dup 1)
@@ -698,7 +698,7 @@  (define_split
   "")
 
 (define_insn "*vsx_le_perm_store_v16qi"
-  [(set (match_operand:V16QI 0 "memory_operand" "=Z")
+  [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "=Z")
         (match_operand:V16QI 1 "vsx_register_operand" "+wa"))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
   "#"
@@ -706,7 +706,7 @@  (define_insn "*vsx_le_perm_store_v16qi"
    (set_attr "length" "12")])
 
 (define_split
-  [(set (match_operand:V16QI 0 "memory_operand" "")
+  [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "")
         (match_operand:V16QI 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
   [(set (match_dup 2)
@@ -739,7 +739,7 @@  (define_split
 ;; The post-reload split requires that we re-permute the source
 ;; register in case it is still live.
 (define_split
-  [(set (match_operand:V16QI 0 "memory_operand" "")
+  [(set (match_operand:V16QI 0 "indexed_or_indirect_operand" "")
         (match_operand:V16QI 1 "vsx_register_operand" ""))]
   "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
   [(set (match_dup 1)
Index: gcc/testsuite/gcc.target/powerpc/pr83399.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr83399.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr83399.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* PR target/83399 */
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O1 -mabi=elfv2 -mlittle -mvsx" } */
+
+typedef __attribute__((altivec(vector__))) int v4si_t;
+int
+foo (void)
+{
+  v4si_t a, u, v, y;
+  u = __builtin_altivec_lvx (32, ((void *) &a) - 32);
+  v = __builtin_altivec_lvx (64, ((void *) &a) - 32);
+  y = u + v;
+  return y[0];
+}