Hello,

Below patch is bootstrapped and regtested on Power64le-linux-gnu.

Thank You,
Kishan

The %Y print operand modifier unconditionally prints 
reg_names[REGNO (x) + 2], i.e. it adds 2 to the register's hardware
register number.

Some instruction patterns for a future Power processor print one
operand with '%x', which forces that operand to be printed and follow
(and allocated) using VSX register numbering.  A second, related
operand in the same pattern is printed with %Y, which is meant to give
the next register in sequence relative to the first. The %Y operand
modifier always added 2 to the hardware register number without first
converting to VSX register numbering. Reason being result did not match
the numbering used by '%x' in the same instruction whenever an Altivec
register was allocated, causing later code to reference the wrong
physical registers.

Fix %Y so that, for VSX-eligible registers, it converts to VSX register
numbering before adding 2, matching '%x'.  Non-VSX registers are
unaffected.

2026-07-02  Kishan Parmar  <[email protected]>

gcc/ChangeLog:
        PR target/125549
        * config/rs6000/rs6000.cc (print_operand) <case 'Y'>: Convert
        VSX-eligible registers to VSX numbering before adding 2.
---
 gcc/config/rs6000/rs6000.cc | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d8669d9ffce..b6353e3f0be 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -14534,7 +14534,30 @@ print_operand (FILE *file, rtx x, int code)
     case 'Y':
       /* Like 'L', for third word of TImode/PTImode  */
       if (REG_P (x))
-       fputs (reg_names[REGNO (x) + 2], file);
+       {
+         /* Check if this is a register being used in a VSX context.
+            If so, convert to VSX numbering and add 2.  */
+         if (VSX_REGNO_P (REGNO (x)))
+           {
+             int reg = REGNO (x);
+             int vsx_reg = (FP_REGNO_P (reg)
+                            ? reg - 32
+                            : reg - FIRST_ALTIVEC_REGNO + 32);
+             vsx_reg += 2;
+
+#ifdef TARGET_REGNAMES
+             if (TARGET_REGNAMES)
+               fprintf (file, "%%vs%d", vsx_reg);
+             else
+#endif
+               fprintf (file, "%d", vsx_reg);
+           }
+         else
+           {
+             /* Non-VSX register: use original behavior (add 2 to hardware 
reg) */
+             fputs (reg_names[REGNO (x) + 2], file);
+           }
+       }
       else if (MEM_P (x))
        {
          machine_mode mode = GET_MODE (x);
-- 
2.52.0

Reply via email to