https://gcc.gnu.org/g:f2586a4a6c8ae21775fecb57f46ddbaa83af49f3

commit r16-4170-gf2586a4a6c8ae21775fecb57f46ddbaa83af49f3
Author: Andreas Schwab <[email protected]>
Date:   Mon Sep 29 18:46:45 2025 +0200

    m68k: fix adddi3/subdi3 with POST_INC/PRE_DEC destination
    
    This part has never been exercised until r15-1579-g792f97b44ffc5e.
    
            PR target/122066
            * config/m68k/m68k.md (adddi3, subdi3): Strip POST_INC and PRE_DEC
            when generating high part of the destination operand.
    
            * gcc.c-torture/compile/pr122066.c: New test.

Diff:
---
 gcc/config/m68k/m68k.md                        | 16 +++++++++-------
 gcc/testsuite/gcc.c-torture/compile/pr122066.c | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index c96937f0b2ca..7f345bfa123b 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -2442,14 +2442,15 @@
       gcc_assert (GET_CODE (operands[0]) == MEM);
       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
        {
-         operands[1] = gen_rtx_MEM (SImode,
-                                    plus_constant (Pmode,
-                                                   XEXP(operands[0], 0), -8));
+         operands[1]
+           = gen_rtx_MEM (SImode,
+                          plus_constant (Pmode,
+                                         XEXP (XEXP (operands[0], 0), 0), -8));
          return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1";
        }
       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
        {
-         operands[1] = XEXP(operands[0], 0);
+         operands[1] = XEXP (XEXP (operands[0], 0), 0);
          return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1";
        }
       else
@@ -2949,13 +2950,14 @@
       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
        {
          operands[1]
-           = gen_rtx_MEM (SImode, plus_constant (Pmode,
-                                                 XEXP (operands[0], 0), -8));
+           = gen_rtx_MEM (SImode,
+                          plus_constant (Pmode,
+                                         XEXP (XEXP (operands[0], 0), 0), -8));
          return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1";
        }
       else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
        {
-         operands[1] = XEXP(operands[0], 0);
+         operands[1] = XEXP (XEXP (operands[0], 0), 0);
          return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1";
        }
       else
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr122066.c 
b/gcc/testsuite/gcc.c-torture/compile/pr122066.c
new file mode 100644
index 000000000000..5fecb7f02b8a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr122066.c
@@ -0,0 +1,18 @@
+/* PR target/122066 -- adddi3/subdi3 mishandle POST_INC/PRE_DEC dest on m68k */
+
+struct {
+  long long wp_ssd[3];
+  long long wp_sum[3];
+} m_lowres;
+void calcAdaptiveQuantFrame() {
+  for (int i = 0; i < 3; i++) {
+    long sum = m_lowres.wp_sum[i];
+    long long ssd = m_lowres.wp_ssd[i];
+    m_lowres.wp_ssd[i] = ssd - sum;
+  }
+  for (int i = 0; i < 3; i++) {
+    long sum = m_lowres.wp_sum[i];
+    long long ssd = m_lowres.wp_ssd[i];
+    m_lowres.wp_ssd[i] = ssd + sum;
+  }
+}

Reply via email to