https://gcc.gnu.org/g:d60c7baae662f45d9f846b65f4906980472ea31e
commit d60c7baae662f45d9f846b65f4906980472ea31e Author: Kishan Parmar <[email protected]> Date: Mon Jun 1 18:42:57 2026 +0530 rs6000: Fix VSX register numbering in dmxxextfdmr512 instruction output The dmxxextfdmr512 instruction extracts 512 bits from a DMR register and stores the result into four consecutive VSX registers. The instruction requires two VSX register numbers (vs[n] and vs[n+2]) as operands. The output templates were missing the %x modifier, which caused two issues: 1. When Altivec registers were allocated during reload. 2. The %Y modifier was adding 2 to register number by default, without checking if the VSX register numbering was used. This caused subsequent instructions to misinterpret which registers dmxxextfdmr512 stored into. When Altivec register v28 was allocated: - dmxxextfdmr512 instruction: Stored result into vs28, vs29, vs30, vs31. - Subsequent stxv instructions: Tried to access v28+32 (vs60,vs61,vs62,vs63) thinking they were accessing Altivec registers, but the offset calculation was wrong because the pattern didn't use VSX numbering. The actual assembly showed: dmxxextfdmr512 vs28,vs30,dm1,0 # Wrong: should be vs60,vs62 stxv vs60,96(r1) # Accessing wrong registers The fix ensures VSX register numbering is used consistently: 1. Add %x modifier to patterns to force vsx register allocation (v28 + 32). 2. Modify %Y to convert to VSX numbering before adding offset, so the second register number is also correct (vs60+2 → vs62, not v28+2 → v30). With the fix, the correct assembly is generated: dmxxextfdmr512 vs60,vs62,dm1,0 # Correct VSX register numbers stxv vs60,96(r1) # Accessing correct registers Diff: --- gcc/config/rs6000/mma.md | 6 +++--- gcc/config/rs6000/rs6000.cc | 25 ++++++++++++++++++++++- gcc/testsuite/gcc.target/powerpc/dm-double-test.c | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index b5fe4cf3188f..98e4b4aa74c3 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -481,9 +481,9 @@ # # # - dmxxinstdmr512 %0,%1,%Y1,0 + dmxxinstdmr512 %0,%x1,%Y1,0 dmmr %0,%1 - dmxxextfdmr512 %0,%Y0,%1,0" + dmxxextfdmr512 %x0,%Y0,%1,0" "&& reload_completed && !dmr_operand (operands[0], XOmode) && !dmr_operand (operands[1], XOmode)" @@ -1016,7 +1016,7 @@ (match_operand 2 "const_0_to_1_operand" "n")] UNSPEC_DM_EXTRACT512))] "TARGET_DENSE_MATH" - "dmxxextfdmr512 %0,%Y0,%1,%2" + "dmxxextfdmr512 %x0,%Y0,%1,%2" [(set_attr "type" "mma")]) ;; Reload DMR registers from memory diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 4930966d1476..7f7bb28f28be 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -14704,7 +14704,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 VSX 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; /* Add 2 to VSX register number */ + +#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); diff --git a/gcc/testsuite/gcc.target/powerpc/dm-double-test.c b/gcc/testsuite/gcc.target/powerpc/dm-double-test.c index 66c197795856..eaa01426c780 100644 --- a/gcc/testsuite/gcc.target/powerpc/dm-double-test.c +++ b/gcc/testsuite/gcc.target/powerpc/dm-double-test.c @@ -188,7 +188,7 @@ main (int argc, char *argv[]) return ret; } -/* { dg-final { scan-assembler {\mdmsetdmrz\M} } } */ +/* { dg-final { scan-assembler {\mdmsetaccz\M} } } */ /* { dg-final { scan-assembler {\mdmxvf64gerpp\M} } } */ /* { dg-final { scan-assembler {\mdmxxextfdmr512\M} } } */
